ForEach-Object
Esegue un'operazione su ogni elemento in una raccolta di oggetti di input.
Sintassi
ForEach-Object
[-InputObject <PSObject>]
[-Begin <ScriptBlock>]
[-Process] <ScriptBlock[]>
[-End <ScriptBlock>]
[-RemainingScripts <ScriptBlock[]>]
[-WhatIf]
[-Confirm]
[<CommonParameters>]
ForEach-Object
[-InputObject <PSObject>]
[-MemberName] <String>
[-ArgumentList <Object[]>]
[-WhatIf]
[-Confirm]
[<CommonParameters>]
Descrizione
Il ForEach-Object
cmdlet 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 usando il parametro InputObject .
A partire da Windows PowerShell 3.0, esistono due modi diversi per costruire un ForEach-Object
comando.
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-Object
supporta ibegin
blocchi ,process
eend
come descritto in about_functions.Nota
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 persistono in tale ambito al termine del cmdlet.
Istruzione Operation. È anche possibile scrivere un'istruzione di operazione, molto più simile al linguaggio naturale. È possibile usare l'istruzione di operazione per specificare un valore di proprietà o chiamare un metodo. Le istruzioni di operazione 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 ProcessName
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 $PSHOME
di installazione di PowerShell .
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.
Get-EventLog -LogName System -Newest 1000 |
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 invia tramite pipe al ForEach-Object
cmdlet . Il parametro Begin visualizza la data e l'ora correnti. Il parametro Process usa quindi il Out-File
cmdlet per creare un file di testo denominato events.txt e archivia la proprietà del messaggio di ogni evento in tale file. Infine, il parametro End viene usato per visualizzare la data e l'ora dopo il completamento dell'elaborazione.
Esempio 4: Modificare il valore di una chiave del Registro di sistema
In questo esempio viene modificato il valore della voce del Registro di sistema RemotePath in tutte le sottochiavi nella HKCU:\Network
chiave in testo maiuscolo.
Get-ItemProperty -Path HKCU:\Network\* |
ForEach-Object {
Set-ItemProperty -Path $_.PSPath -Name RemotePath -Value $_.RemotePath.ToUpper()
}
È possibile usare questo formato per modificare la forma o il contenuto del valore di una 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à a , viene creata una sottochiave E in HKCU:\Network
con il valore del Registro di sistema RemotePath impostato su \\Server\Share
.\\Server\Share
E:
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. Set-ItemProperty
Nel comando 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 usa il metodo ToUpper() del valore RemotePath , ovvero una stringa REG_SZ.
Poiché Set-ItemProperty
sta modificando la proprietà di ogni chiave, il ForEach-Object
cmdlet è necessario per accedere alla proprietà .
Esempio 5: Usare la variabile automatica $null
In questo esempio viene illustrato l'effetto del piping della $null
variabile automatica al ForEach-Object
cmdlet .
1, 2, $null, 4 | ForEach-Object {"Hello"}
Hello
Hello
Hello
Hello
Poiché PowerShell considera $null
come segnaposto esplicito, il ForEach-Object
cmdlet genera un valore per $null
come avviene per altri oggetti inviati tramite pipe.
Esempio 6: Ottenere i valori delle proprietà
Questo esempio ottiene 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 è equivalente 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 $_
dell'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 ForEach-Object
cmdlet e omette i nomi dei parametri MemberName e ArgumentList , che sono 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 quattro 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
Nota
Il primo blocco di script viene sempre mappato al begin
blocco, l'ultimo blocco viene mappato al end
blocco e i due blocchi intermedi vengono 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
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.
Tipo: | Object[] |
Alias: | Args |
Posizione: | Named |
Valore predefinito: | None |
Necessario: | False |
Accettare l'input della pipeline: | False |
Accettare caratteri jolly: | 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.
Tipo: | ScriptBlock |
Posizione: | Named |
Valore predefinito: | None |
Necessario: | False |
Accettare l'input della pipeline: | False |
Accettare caratteri jolly: | False |
-Confirm
Richiede conferma prima di eseguire il cmdlet.
Tipo: | SwitchParameter |
Alias: | cf |
Posizione: | Named |
Valore predefinito: | False |
Necessario: | False |
Accettare l'input della pipeline: | False |
Accettare caratteri jolly: | 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.
Tipo: | ScriptBlock |
Posizione: | Named |
Valore predefinito: | None |
Necessario: | False |
Accettare l'input della pipeline: | False |
Accettare caratteri jolly: | False |
-InputObject
Specifica gli oggetti di input. ForEach-Object
esegue il blocco di script o l'istruzione dell'operazione su ogni oggetto di input. Immettere una variabile che contiene 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 è una raccolta che rappresenta il risultato di un comando, ad esempio -InputObject (Get-Process)
.
Poiché InputObject non può restituire singole proprietà da una matrice o da una raccolta di oggetti, è consigliabile usare ForEach-Object
per eseguire operazioni su una raccolta di oggetti per gli oggetti con valori specifici nelle proprietà definite, come ForEach-Object
illustrato negli esempi di questo argomento.
Tipo: | PSObject |
Posizione: | Named |
Valore predefinito: | None |
Necessario: | False |
Accettare l'input della pipeline: | True |
Accettare caratteri jolly: | False |
-MemberName
Specifica il nome della proprietà del membro da ottenere o il metodo membro da chiamare. I membri devono essere membri dell'istanza, non membri statici.
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.
Tipo: | String |
Posizione: | 0 |
Valore predefinito: | None |
Necessario: | True |
Accettare l'input della pipeline: | False |
Accettare caratteri jolly: | True |
-Process
Specifica l'operazione 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 process
blocco. 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 mappati al process
blocco.
Tipo: | ScriptBlock[] |
Posizione: | 0 |
Valore predefinito: | None |
Necessario: | True |
Accettare l'input della pipeline: | False |
Accettare caratteri jolly: | False |
-RemainingScripts
Specifica tutti i blocchi di script non acquisiti dal parametro Process .
Questo parametro è stato introdotto in Windows PowerShell 3.0.
Tipo: | ScriptBlock[] |
Posizione: | Named |
Valore predefinito: | None |
Necessario: | False |
Accettare l'input della pipeline: | False |
Accettare caratteri jolly: | False |
-WhatIf
Mostra gli effetti dell'esecuzione del cmdlet. Il cmdlet non viene eseguito.
Tipo: | SwitchParameter |
Alias: | wi |
Posizione: | Named |
Valore predefinito: | False |
Necessario: | False |
Accettare l'input della pipeline: | False |
Accettare caratteri jolly: | False |
Input
È possibile inviare tramite pipe qualsiasi oggetto a questo cmdlet.
Output
Questo cmdlet restituisce oggetti determinati dall'input.
Note
Windows PowerShell include gli alias seguenti per ForEach-Object
:
%
foreach
Il ForEach-Object
cmdlet funziona in modo molto simile 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 Where
ForEach
stati aggiunti metodi per l'uso con le raccolte. Altre informazioni su questi nuovi metodi sono disponibili qui about_arrays