ForEach-Object
Esegue un'operazione su ogni elemento in una raccolta di oggetti di input.
Sintassi
ScriptBlockSet (Impostazione predefinita)
ForEach-Object
[-Process] <ScriptBlock[]>
[-InputObject <PSObject>]
[-Begin <ScriptBlock>]
[-End <ScriptBlock>]
[-RemainingScripts <ScriptBlock[]>]
[-WhatIf]
[-Confirm]
[<CommonParameters>]
PropertyAndMethodSet
ForEach-Object
[-MemberName] <String>
[-InputObject <PSObject>]
[-ArgumentList <Object[]>]
[-WhatIf]
[-Confirm]
[<CommonParameters>]
ParallelParameterSet
ForEach-Object
-Parallel <ScriptBlock>
[-InputObject <PSObject>]
[-ThrottleLimit <Int32>]
[-TimeoutSeconds <Int32>]
[-AsJob]
[-WhatIf]
[-Confirm]
[<CommonParameters>]
Descrizione
Il cmdlet ForEach-Object esegue un'operazione su ogni elemento in una raccolta di oggetti di input. Gli oggetti di input possono essere inviati tramite pipe al cmdlet o specificati utilizzando il parametro InputObject .
A partire da Windows PowerShell 3.0, esistono due modi diversi per costruire un comando ForEach-Object.
Blocco di script. È possibile usare un blocco di script per specificare l'operazione. All'interno del blocco di script usare la variabile
$_per rappresentare l'oggetto corrente. Il blocco di script è il valore del parametro Process . Il blocco di script può contenere qualsiasi script di PowerShell.Ad esempio, il comando seguente ottiene il valore della proprietà ProcessName di ogni processo nel computer.
Get-Process | ForEach-Object {$_.ProcessName}ForEach-Objectsupporta i blocchibegin,processeendcome descritto in about_functions.Annotazioni
I blocchi di script vengono eseguiti nell'ambito del chiamante. Pertanto, i blocchi hanno accesso alle variabili in tale ambito e possono creare nuove variabili che vengono mantenute in tale ambito dopo il completamento del cmdlet.
Istruzione operativa. È anche possibile scrivere un'istruzione operativa, che è molto più simile al linguaggio naturale. È possibile utilizzare l'istruzione operation per specificare un valore di proprietà o chiamare un metodo. Le istruzioni operative sono state introdotte in Windows PowerShell 3.0.
Ad esempio, il comando seguente ottiene anche il valore della proprietà ProcessName di ogni processo nel computer.
Get-Process | ForEach-Object ProcessNameBlocco di script in esecuzione parallelo. A partire da PowerShell 7.0, è disponibile un terzo set di parametri che esegue ogni blocco di script in parallelo. Il parametro ThrottleLimit limita il numero di script paralleli in esecuzione alla volta. Come in precedenza, usare la
$_variabile per rappresentare l'oggetto di input corrente nel blocco di script. Usare la parola chiave$using:per passare riferimenti a variabili allo script in esecuzione.In PowerShell 7 viene creato un nuovo spazio di esecuzione per ogni iterazione del ciclo per garantire il massimo isolamento. Può trattarsi di un impatto elevato sulle prestazioni e sulle risorse se il lavoro che si sta eseguendo è ridotto rispetto alla creazione di nuovi spazi di esecuzione o se sono presenti molte iterazioni che eseguono un lavoro significativo. A partire da PowerShell 7.1, gli spazi di esecuzione di un pool di spazi di esecuzione vengono riutilizzati per impostazione predefinita. Le dimensioni del pool dello spazio di esecuzione sono specificate dal parametro ThrottleLimit . La dimensione predefinita del pool di spazi di esecuzione è 5. È comunque possibile creare un nuovo spazio di esecuzione per ogni iterazione usando l'opzione UseNewRunspace .
Per impostazione predefinita, gli scriptblock paralleli usano la directory di lavoro corrente del chiamante che ha avviato le attività parallele.
Per altre informazioni, vedere la sezione NOTES di questo articolo.
Esempio
Esempio 1: Dividere numeri interi in una matrice
Questo esempio accetta una matrice di tre interi e li divide per 1024.
30000, 56798, 12432 | ForEach-Object -Process {$_/1024}
29.296875
55.466796875
12.140625
Esempio 2: Ottenere la lunghezza di tutti i file in una directory
In questo esempio vengono elaborati i file e le directory nella directory di installazione di PowerShell $PSHOME.
Get-ChildItem $PSHOME |
ForEach-Object -Process {if (!$_.PSIsContainer) {$_.Name; $_.Length / 1024; " " }}
Se l'oggetto non è una directory, il blocco di script ottiene il nome del file, divide il valore della relativa proprietà Length per 1024 e aggiunge uno spazio (" ") per separarlo dalla voce successiva. Il cmdlet usa la proprietà PSISContainer per determinare se un oggetto è una directory.
Esempio 3: Operare sugli eventi di sistema più recenti
In questo esempio vengono scritti i 1000 eventi più recenti dal registro eventi di sistema in un file di testo. L'ora corrente viene visualizzata prima e dopo l'elaborazione degli eventi.
$Events = Get-EventLog -LogName System -Newest 1000
$events | ForEach-Object -Begin {Get-Date} -Process {Out-File -FilePath Events.txt -Append -InputObject $_.Message} -End {Get-Date}
Get-EventLog ottiene i 1000 eventi più recenti dal registro eventi di sistema e li memorizza nella $Events variabile.
$Events viene quindi inviato tramite pipe al ForEach-Object cmdlet. Il parametro Begin visualizza la data e l'ora correnti. Successivamente, il parametro Process utilizza il Out-File cmdlet per creare un file di testo denominato events.txt e archivia la proprietà message di ogni evento in tale file. Infine, il parametro End viene utilizzato per visualizzare la data e l'ora al termine di tutta l'elaborazione.
Esempio 4: Modificare il valore di una chiave del Registro di sistema
In questo esempio il valore della voce del Registro di sistema RemotePath in tutte le sottochiavi sotto la HKCU:\Network chiave viene modificato in testo maiuscolo.
Get-ItemProperty -Path HKCU:\Network\* |
ForEach-Object {Set-ItemProperty -Path $_.PSPath -Name RemotePath -Value $_.RemotePath.ToUpper();}
È possibile utilizzare questo formato per modificare il formato o il contenuto di un valore di voce del Registro di sistema.
Ogni sottochiave nella chiave di rete rappresenta un'unità di rete mappata che si riconnette all'accesso. La voce RemotePath contiene il percorso UNC dell'unità connessa. Ad esempio, se si esegue il mapping dell'unità E: a \\Server\Share, viene creata una sottochiave E con HKCU:\Network il valore del Registro di sistema RemotePath impostato su \\Server\Share.
Il comando usa il Get-ItemProperty cmdlet per ottenere tutte le sottochiavi della chiave di rete e il Set-ItemProperty cmdlet per modificare il valore della voce del Registro di sistema RemotePath in ogni chiave.
Nel comando Set-ItemProperty il percorso è il valore della proprietà PSPath della chiave del Registro di sistema. Si tratta di una proprietà dell'oggetto Microsoft .NET Framework che rappresenta la chiave del Registro di sistema, non una voce del Registro di sistema. Il comando utilizza il metodo ToUpper() del valore RemotePath , che è una stringa (REG_SZ).
Poiché Set-ItemProperty modifica la proprietà di ogni chiave, per accedere alla proprietà è necessario il cmdlet ForEach-Object.
Esempio 5: Utilizzare la variabile automatica $Null
In questo esempio viene illustrato l'effetto del piping della variabile automatica $Null al cmdlet ForEach-Object.
1, 2, $null, 4 | ForEach-Object {"Hello"}
Hello
Hello
Hello
Hello
Poiché PowerShell considera null come un segnaposto esplicito, il ForEach-Object cmdlet genera un valore per $Null, esattamente come avviene per altri oggetti che vengono reindirizzati ad esso.
Esempio 6: Ottenere i valori delle proprietà
In questo esempio viene ottenuto il valore della proprietà Path di tutti i moduli di PowerShell installati usando il parametro MemberName del ForEach-Object cmdlet.
Get-Module -ListAvailable | ForEach-Object -MemberName Path
Get-Module -ListAvailable | Foreach Path
Il secondo comando equivale al primo. Usa l'alias Foreach del ForEach-Object cmdlet e omette il nome del parametro MemberName , facoltativo.
Il ForEach-Object cmdlet è utile per ottenere i valori delle proprietà, perché ottiene il valore senza modificare il tipo, a differenza dei cmdlet Format o del Select-Object cmdlet , che modificano il tipo di valore della proprietà.
Esempio 7: Suddividere i nomi dei moduli in nomi di componenti
In questo esempio vengono illustrati tre modi per suddividere due nomi di modulo separati da punti nei nomi dei componenti. I comandi chiamano il metodo Split di stringhe. I tre comandi usano una sintassi diversa, ma sono equivalenti e intercambiabili. L'output è lo stesso per tutti e tre i casi.
"Microsoft.PowerShell.Core", "Microsoft.PowerShell.Host" | ForEach-Object {$_.Split(".")}
"Microsoft.PowerShell.Core", "Microsoft.PowerShell.Host" | ForEach-Object -MemberName Split -ArgumentList "."
"Microsoft.PowerShell.Core", "Microsoft.PowerShell.Host" | Foreach Split "."
Microsoft
PowerShell
Core
Microsoft
PowerShell
Host
Il primo comando usa la sintassi tradizionale, che include un blocco di script e l'operatore oggetto corrente $_. Usa la sintassi del punto per specificare il metodo e le parentesi per racchiudere l'argomento delimitatore.
Il secondo comando usa il parametro MemberName per specificare il metodo Split e il parametro ArgumentList per identificare il punto (.) come delimitatore di divisione.
Il terzo comando usa l'alias Foreach del cmdlet ForEach-Object e omette i nomi dei parametri MemberName e ArgumentList, facoltativi.
Esempio 8: Uso di ForEach-Object con due blocchi di script
In questo esempio vengono passati due blocchi di script in modo posizionale. Tutti i blocchi di script vengono associati al parametro Process . Tuttavia, vengono considerati come se fossero stati passati ai parametri Begin e Process .
1..2 | ForEach-Object { 'begin' } { 'process' }
begin
process
process
Esempio 9: Uso di ForEach-Object con più di due blocchi di script
In questo esempio vengono passati due blocchi di script in modo posizionale. Tutti i blocchi di script vengono associati al parametro Process . Tuttavia, vengono considerati come se fossero stati passati ai parametri Begin, Process e End .
1..2 | ForEach-Object { 'begin' } { 'process A' } { 'process B' } { 'end' }
begin
process A
process B
process A
process B
end
Annotazioni
Il primo blocco di script viene sempre mappato al begin blocco, l'ultimo blocco viene mappato al end blocco e i blocchi intermedi vengono tutti mappati al process blocco.
Esempio 10: Eseguire più blocchi di script per ogni elemento della pipeline
Come illustrato nell'esempio precedente, più blocchi di script passati usando il parametro Process vengono mappati ai parametri Begin e End . Per evitare questo mapping, è necessario specificare valori espliciti per i parametri Begin e End .
1..2 | ForEach-Object -Begin $null -Process { 'one' }, { 'two' }, { 'three' } -End $null
one
two
three
one
two
three
Esempio 11: Eseguire script lenti in batch paralleli
In questo esempio viene eseguito un semplice blocco di script che valuta una stringa e viene sospeso per un secondo.
$Message = "Output:"
1..8 | ForEach-Object -Parallel {
"$using:Message $_"
Start-Sleep 1
} -ThrottleLimit 4
Output: 1
Output: 2
Output: 3
Output: 4
Output: 5
Output: 6
Output: 7
Output: 8
Il valore del parametro ThrottleLimit è impostato su 4 in modo che l'input venga elaborato in batch di quattro.
La parola chiave $using: viene usata per passare la variabile $Message in ogni blocco di script parallelo.
Esempio 12: Recuperare le voci di log in parallelo
In questo esempio vengono recuperate 50.000 voci di log da 5 log di sistema in un computer Windows locale.
$logNames = 'Security','Application','System','Windows PowerShell','Microsoft-Windows-Store/Operational'
$logEntries = $logNames | ForEach-Object -Parallel {
Get-WinEvent -LogName $_ -MaxEvents 10000
} -ThrottleLimit 5
$logEntries.Count
50000
Il parametro Parallel consente di specificare il blocco di script eseguito in parallelo per ogni nome di log di input. Il parametro ThrottleLimit garantisce che tutti e cinque i blocchi di script vengano eseguiti contemporaneamente.
Esempio 13: Esecuzione in parallelo come processo
In questo esempio viene eseguito un semplice blocco di script in parallelo, creando due processi in background alla volta.
$job = 1..10 | ForEach-Object -Parallel {
"Output: $_"
Start-Sleep 1
} -ThrottleLimit 2 -AsJob
$job | Receive-Job -Wait
Output: 1
Output: 2
Output: 3
Output: 4
Output: 5
Output: 6
Output: 7
Output: 8
Output: 9
Output: 10
La $job variabile riceve l'oggetto processo che raccoglie i dati di output e monitora lo stato di esecuzione.
L'oggetto processo viene inviato tramite pipe con Receive-Job il parametro dell'opzione Wait . E questo trasmette l'output alla console, proprio come se ForEach-Object -Parallel fosse stato eseguito senza AsJob.
Esempio 14: Uso di riferimenti a variabili thread-safe
In questo esempio vengono richiamati blocchi di script in parallelo per raccogliere oggetti Process denominati in modo univoco.
$threadSafeDictionary = [System.Collections.Concurrent.ConcurrentDictionary[string,object]]::new()
Get-Process | ForEach-Object -Parallel {
$dict = $using:threadSafeDictionary
$dict.TryAdd($_.ProcessName, $_)
}
$threadSafeDictionary["pwsh"]
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
82 82.87 130.85 15.55 2808 2 pwsh
Una singola istanza di un oggetto ConcurrentDictionary viene passata a ogni blocco di script per raccogliere gli oggetti. Poiché ConcurrentDictionary è thread-safe , è sicuro che possa essere modificato da ogni script parallelo. Un oggetto non thread-safe, ad esempio System.Collections.Generic.Dictionary, non sarebbe sicuro da usare qui.
Annotazioni
Questo esempio è un uso molto inefficiente del parametro Parallel . Lo script aggiunge semplicemente l'oggetto di input a un oggetto dizionario concorrente. È banale e non vale la pena di invocare ogni script in un thread separato. Funzionare ForEach-Object normalmente senza l'interruttore parallelo è molto più efficiente e veloce. Questo esempio è destinato solo a illustrare come usare le variabili thread-safe.
Esempio 15: Scrittura di errori con esecuzione parallela
Questo esempio scrive nel flusso di errori in parallelo, in cui l'ordine degli errori scritti è casuale.
1..3 | ForEach-Object -Parallel {
Write-Error "Error: $_"
}
Write-Error: Error: 1
Write-Error: Error: 3
Write-Error: Error: 2
Esempio 16: Terminazione degli errori nell'esecuzione parallela
In questo esempio viene illustrato un errore irreversibile in un blocco di script in esecuzione parallelo.
1..5 | ForEach-Object -Parallel {
if ($_ -eq 3)
{
throw "Terminating Error: $_"
}
Write-Output "Output: $_"
}
Exception: Terminating Error: 3
Output: 1
Output: 4
Output: 2
Output: 5
Output: 3 non viene mai scritto perché lo scriptblock parallelo per tale iterazione è stato terminato.
Annotazioni
PipelineVariable variabili di parametro comuni non sono supportate negli scenari di Foreach-Object -Parallel anche con la parola chiave $using:.
Esempio 17: Passaggio di variabili nello script parallelo annidato ScriptBlockSet
È possibile creare una variabile all'esterno di un Foreach-Object -Parallel scriptblock con ambito e usarla all'interno del blocco script con la parola chiave $using.
$test1 = 'TestA'
1..2 | Foreach-Object -Parallel {
$using:test1
}
TestA
TestA
# You CANNOT create a variable inside a scoped scriptblock
# to be used in a nested foreach parallel scriptblock.
$test1 = 'TestA'
1..2 | Foreach-Object -Parallel {
$using:test1
$test2 = 'TestB'
1..2 | Foreach-Object -Parallel {
$using:test2
}
}
Line |
2 | 1..2 | Foreach-Object -Parallel {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
| The value of the using variable '$using:test2' cannot be retrieved because it has not been set in the local session.
Lo scriptblock annidato non può accedere alla variabile $test2 e viene generato un errore.
Parametri
-ArgumentList
Specifica una matrice di argomenti per una chiamata al metodo. Per altre informazioni sul comportamento di ArgumentList, vedere about_Splatting.
Questo parametro è stato introdotto in Windows PowerShell 3.0.
Proprietà dei parametri
| Tipo: | Object[] |
| Valore predefinito: | None |
| Supporta i caratteri jolly: | False |
| DontShow: | False |
| Alias: | Argomenti |
Set di parametri
PropertyAndMethodSet
| Posizione: | Named |
| Obbligatorio: | False |
| Valore dalla pipeline: | False |
| Valore dalla pipeline in base al nome della proprietà: | False |
| Valore dagli argomenti rimanenti: | False |
-AsJob
Fa sì che la chiamata parallela sia eseguita come processo di PowerShell. Viene restituito un singolo oggetto processo anziché l'output dai blocchi di script in esecuzione. L'oggetto processo contiene processi figlio per ogni blocco di script parallelo eseguito. L'oggetto processo può essere usato da tutti i cmdlet del processo di PowerShell per monitorare lo stato di esecuzione e recuperare i dati.
Questo parametro è stato introdotto in PowerShell 7.0.
Proprietà dei parametri
| Tipo: | SwitchParameter |
| Valore predefinito: | None |
| Supporta i caratteri jolly: | False |
| DontShow: | False |
Set di parametri
ParallelParameterSet
| Posizione: | Named |
| Obbligatorio: | False |
| Valore dalla pipeline: | False |
| Valore dalla pipeline in base al nome della proprietà: | False |
| Valore dagli argomenti rimanenti: | False |
-Begin
Specifica un blocco di script eseguito prima dell'elaborazione di qualsiasi oggetto di input da parte di questo cmdlet. Questo blocco di script viene eseguito una sola volta per l'intera pipeline. Per altre informazioni sul begin blocco, vedere about_Functions.
Proprietà dei parametri
| Tipo: | ScriptBlock |
| Valore predefinito: | None |
| Supporta i caratteri jolly: | False |
| DontShow: | False |
Set di parametri
ScriptBlockSet
| Posizione: | Named |
| Obbligatorio: | False |
| Valore dalla pipeline: | False |
| Valore dalla pipeline in base al nome della proprietà: | False |
| Valore dagli argomenti rimanenti: | False |
-Confirm
Richiede conferma prima di eseguire il cmdlet.
Proprietà dei parametri
| Tipo: | SwitchParameter |
| Valore predefinito: | False |
| Supporta i caratteri jolly: | False |
| DontShow: | False |
| Alias: | cfr |
Set di parametri
(All)
| Posizione: | Named |
| Obbligatorio: | False |
| Valore dalla pipeline: | False |
| Valore dalla pipeline in base al nome della proprietà: | False |
| Valore dagli argomenti rimanenti: | False |
-End
Specifica un blocco di script eseguito dopo che questo cmdlet elabora tutti gli oggetti di input. Questo blocco di script viene eseguito una sola volta per l'intera pipeline. Per altre informazioni sul end blocco, vedere about_Functions.
Proprietà dei parametri
| Tipo: | ScriptBlock |
| Valore predefinito: | None |
| Supporta i caratteri jolly: | False |
| DontShow: | False |
Set di parametri
ScriptBlockSet
| Posizione: | Named |
| Obbligatorio: | False |
| Valore dalla pipeline: | False |
| Valore dalla pipeline in base al nome della proprietà: | False |
| Valore dagli argomenti rimanenti: | False |
-InputObject
Specifica gli oggetti di input.
ForEach-Object esegue l'istruzione del blocco di script o dell'operazione su ogni oggetto di input. Immettere una variabile contenente gli oggetti oppure digitare un comando o un'espressione che ottiene gli oggetti .
Quando si usa il parametro InputObject con ForEach-Object, invece di eseguire il piping dei risultati del comando a ForEach-Object, il valore InputObject viene considerato come un singolo oggetto. Questo vale anche se il valore è un insieme che è il risultato di un comando, ad esempio -InputObject (Get-Process).
Poiché InputObject non è in grado di restituire singole proprietà da una matrice o da un insieme di oggetti, è consigliabile utilizzare ForEach-Object nella pipeline se si utilizzano ForEach-Object operazioni su un insieme di oggetti per gli oggetti che hanno valori specifici nelle proprietà definite.
Proprietà dei parametri
| Tipo: | PSObject |
| Valore predefinito: | None |
| Supporta i caratteri jolly: | False |
| DontShow: | False |
Set di parametri
(All)
| Posizione: | Named |
| Obbligatorio: | False |
| Valore dalla pipeline: | True |
| Valore dalla pipeline in base al nome della proprietà: | False |
| Valore dagli argomenti rimanenti: | False |
-MemberName
Specifica la proprietà da ottenere o il metodo da chiamare.
I caratteri jolly sono consentiti, ma funzionano solo se la stringa risultante viene risolta in un valore univoco.
Ad esempio, se si esegue Get-Process | ForEach -MemberName *Name, il criterio con caratteri jolly corrisponde a più membri, causando l'esito negativo del comando.
Questo parametro è stato introdotto in Windows PowerShell 3.0.
Proprietà dei parametri
| Tipo: | String |
| Valore predefinito: | None |
| Supporta i caratteri jolly: | True |
| DontShow: | False |
Set di parametri
PropertyAndMethodSet
| Posizione: | 0 |
| Obbligatorio: | True |
| Valore dalla pipeline: | False |
| Valore dalla pipeline in base al nome della proprietà: | False |
| Valore dagli argomenti rimanenti: | False |
-Parallel
Specifica il blocco di script da utilizzare per l'elaborazione parallela degli oggetti di input. Immettere un blocco di script che descrive l'operazione.
Questo parametro è stato introdotto in PowerShell 7.0.
Proprietà dei parametri
| Tipo: | ScriptBlock |
| Valore predefinito: | None |
| Supporta i caratteri jolly: | False |
| DontShow: | False |
Set di parametri
ParallelParameterSet
| Posizione: | Named |
| Obbligatorio: | True |
| Valore dalla pipeline: | False |
| Valore dalla pipeline in base al nome della proprietà: | False |
| Valore dagli argomenti rimanenti: | False |
-Process
Specifica l'operazione che viene eseguita su ogni oggetto di input. Questo blocco di script viene eseguito per ogni oggetto nella pipeline. Per altre informazioni sul process blocco, vedere about_Functions.
Quando si forniscono più blocchi di script al parametro Process , il primo blocco di script viene sempre mappato al begin blocco. Se sono presenti solo due blocchi di script, il secondo blocco viene mappato al blocco process. Se sono presenti tre o più blocchi di script, il primo blocco di script viene sempre mappato al begin blocco, l'ultimo blocco viene mappato al end blocco e i blocchi intermedi vengono tutti mappati al process blocco.
Proprietà dei parametri
| Tipo: | |
| Valore predefinito: | None |
| Supporta i caratteri jolly: | False |
| DontShow: | False |
Set di parametri
ScriptBlockSet
| Posizione: | 0 |
| Obbligatorio: | True |
| Valore dalla pipeline: | False |
| Valore dalla pipeline in base al nome della proprietà: | False |
| Valore dagli argomenti rimanenti: | False |
-RemainingScripts
Specifica tutti i blocchi di script che non vengono utilizzati dal parametro Process .
Questo parametro è stato introdotto in Windows PowerShell 3.0.
Proprietà dei parametri
| Tipo: | |
| Valore predefinito: | None |
| Supporta i caratteri jolly: | False |
| DontShow: | False |
Set di parametri
ScriptBlockSet
| Posizione: | Named |
| Obbligatorio: | False |
| Valore dalla pipeline: | False |
| Valore dalla pipeline in base al nome della proprietà: | False |
| Valore dagli argomenti rimanenti: | False |
-ThrottleLimit
Specifica il numero di blocchi di script in parallelo. Gli oggetti di input vengono bloccati fino a quando il numero di blocchi di script in esecuzione non scende al di sotto di ThrottleLimit. Il valore predefinito è 5.
Questo parametro è stato introdotto in PowerShell 7.0.
Proprietà dei parametri
| Tipo: | Int32 |
| Valore predefinito: | 5 |
| Supporta i caratteri jolly: | False |
| DontShow: | False |
Set di parametri
ParallelParameterSet
| Posizione: | Named |
| Obbligatorio: | False |
| Valore dalla pipeline: | False |
| Valore dalla pipeline in base al nome della proprietà: | False |
| Valore dagli argomenti rimanenti: | False |
-TimeoutSeconds
Specifica il numero di secondi di attesa per l'elaborazione di tutti gli input in parallelo. Dopo il timeout specificato, tutti gli script in esecuzione vengono arrestati. E tutti gli oggetti di input rimanenti da elaborare vengono ignorati. Il valore predefinito di 0 disabilita il timeout e ForEach-Object -Parallel può essere eseguito a tempo indeterminato. La digitazione di CTRL+C nella riga di comando arresta un comando in esecuzione ForEach-Object -Parallel . Questo parametro non può essere utilizzato insieme al parametro AsJob .
Questo parametro è stato introdotto in PowerShell 7.0.
Proprietà dei parametri
| Tipo: | Int32 |
| Valore predefinito: | 0 |
| Supporta i caratteri jolly: | False |
| DontShow: | False |
Set di parametri
ParallelParameterSet
| Posizione: | Named |
| Obbligatorio: | False |
| Valore dalla pipeline: | False |
| Valore dalla pipeline in base al nome della proprietà: | False |
| Valore dagli argomenti rimanenti: | False |
-UseNewRunspace
Fa sì che la chiamata parallela crei un nuovo spazio di esecuzione per ogni iterazione del ciclo anziché riutilizzare gli spazi di esecuzione dal pool di spazi di esecuzione.
Questo parametro è stato introdotto in PowerShell 7.1
Proprietà dei parametri
| Tipo: | SwitchParameter |
| Valore predefinito: | False |
| Supporta i caratteri jolly: | False |
| DontShow: | False |
Set di parametri
ParallelParameterSet
| Posizione: | Named |
| Obbligatorio: | False |
| Valore dalla pipeline: | False |
| Valore dalla pipeline in base al nome della proprietà: | False |
| Valore dagli argomenti rimanenti: | False |
-WhatIf
Mostra gli effetti dell'esecuzione del cmdlet. Il cmdlet non viene eseguito.
Proprietà dei parametri
| Tipo: | SwitchParameter |
| Valore predefinito: | False |
| Supporta i caratteri jolly: | False |
| DontShow: | False |
| Alias: | Wi |
Set di parametri
(All)
| Posizione: | Named |
| Obbligatorio: | False |
| Valore dalla pipeline: | False |
| Valore dalla pipeline in base al nome della proprietà: | False |
| Valore dagli argomenti rimanenti: | False |
CommonParameters
Questo cmdlet supporta i parametri comuni: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction e -WarningVariable. Per altre informazioni, vedi about_CommonParameters.
Input
PSObject
È possibile passare qualsiasi oggetto come input a questo cmdlet.
Output
PSObject
Questo cmdlet restituisce oggetti determinati dall'input.
Note
Il cmdlet ForEach-Object funziona in modo analogo all'istruzione Foreach, ad eccezione del fatto che non è possibile inviare tramite pipe l'input a un'istruzione Foreach. Per altre informazioni sull'istruzione Foreach, vedere about_Foreach.
A partire da PowerShell 4.0, sono stati aggiunti metodi Where e ForEach per l'uso con le raccolte. Altre informazioni su questi nuovi metodi sono disponibili qui about_arrays
Utilizzo di ForEach-Object -Parallel:
Il
ForEach-Object -Parallelset di parametri usa l'API interna di PowerShell per eseguire ogni blocco di script in un nuovo spazio di esecuzione. Si tratta di un sovraccarico significativamente maggiore rispetto all'esecuzioneForEach-Objectnormale con l'elaborazione sequenziale. È importante utilizzare Parallel quando il sovraccarico dell'esecuzione in parallelo è ridotto rispetto al lavoro eseguito dal blocco di script. Per esempio:- Script a elevato utilizzo di calcolo in computer multi-core
- Script che impiegano tempo in attesa dei risultati o che eseguono operazioni di file
L'uso del parametro Parallel può causare l'esecuzione degli script molto più lenta rispetto alla normale. Soprattutto se gli script paralleli sono semplici. Sperimentare con Parallel per scoprire dove può essere utile.
Quando vengono eseguiti in parallelo, non è possibile garantire il corretto funzionamento degli oggetti decorati con ScriptProperties o ScriptMethods se vengono eseguiti in uno spazio di esecuzione diverso da quello in cui gli script erano originariamente collegati.
La chiamata di Scriptblock tenta sempre di eseguire nello spazio di esecuzione principale , indipendentemente dalla posizione in cui viene effettivamente richiamata. Tuttavia,
ForEach-Object -Parallelcrea spazi di esecuzione temporanei che vengono eliminati dopo l'uso, quindi non c'è più spazio di esecuzione per gli script da eseguire in.Questo comportamento può funzionare finché lo spazio di esecuzione principale esiste ancora. Tuttavia, è possibile che non si ottenga il risultato desiderato se lo script dipende da variabili esterne presenti solo nello spazio di esecuzione del chiamante e non nello spazio di esecuzione principale .
Gli errori non irreversibili vengono scritti nel flusso di errore del cmdlet man mano che si verificano in blocchi di script in esecuzione paralleli. Poiché l'ordine di esecuzione di scriptblock parallelo non è deterministico, l'ordine in cui gli errori vengono visualizzati nel flusso di errori è casuale. Analogamente, i messaggi scritti in altri flussi di dati, ad esempio avvisi, verbose o informazioni vengono scritti in tali flussi di dati in un ordine indeterminato.
Gli errori di terminazione, ad esempio le eccezioni, terminano la singola istanza parallela dei blocchi di script in cui si verificano. Un errore irreversibile in uno scriptblocks potrebbe non causare la chiusura del
Foreach-Objectcmdlet. Gli altri scriptblock, in esecuzione in parallelo, continuano a essere eseguiti a meno che non si verifichino anche un errore irreversibile. L'errore di terminazione viene scritto nel flusso dei dati di errore come ErrorRecord con fullyQualifiedErrorId diPSTaskException. Gli errori fatali possono essere convertiti in errori non fatali usando i blocchi try/catch o trap di PowerShell.PipelineVariable variabili di parametro comuni non sono supportate in scenari paralleli anche con la parola chiave
$using:.Importante
Il
ForEach-Object -Parallelset di parametri esegue blocchi di script in parallelo su thread di processo separati. La parola chiave$using:consente di passare riferimenti a variabili dal thread di chiamata del cmdlet a ogni thread di blocco di script in esecuzione. Poiché i blocchi di script vengono eseguiti in thread diversi, le variabili oggetto passate per riferimento devono essere usate in modo sicuro. In genere è sicuro leggere da oggetti referenziati che non cambiano. Tuttavia, se lo stato dell'oggetto viene modificato, è necessario usare oggetti thread-safe, ad esempio i tipi .NET System.Collection.Concurrent (vedere l'esempio 11).