ForEach-Object
針對輸入物件集合中的每個項目執行操作。
Syntax
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>]
Description
Cmdlet ForEach-Object
會對輸入物件集合中的每個專案執行作業。 輸入物件可以使用管線傳送至 Cmdlet,或使用 InputObject 參數來指定。
從 Windows PowerShell 3.0 開始,有兩種不同的方法來建構ForEach-Object
命令。
腳本區塊。 您可以使用指令碼區塊來指定操作。 在腳本區塊內
$_
,使用變數來表示目前的物件。 指令碼區塊是 Process 參數的值。 腳本區塊可以包含任何 PowerShell 腳本。例如,下列命令會取得電腦上每個處理程序之 ProcessName 屬性的值。
Get-Process | ForEach-Object {$_.ProcessName}
ForEach-Object
支援begin
、process
和end
區塊,如 about_functions中所述。注意
腳本區塊會在呼叫端的範圍中執行。 因此,區塊可以存取該範圍內的變數,而且可以在 Cmdlet 完成之後,建立保存在該範圍中的新變數。
Operation 語句。 您也可以撰寫作業語句,這更像是自然語言。 您可以使用操作陳述式來指定屬性值或呼叫方法。 操作陳述式是在 Windows PowerShell 3.0 中導入。
例如,下列命令會一併取得電腦上每個處理程序之 ProcessName 屬性的值。
Get-Process | ForEach-Object ProcessName
範例
範例 1:在陣列中分割整數
此範例會採用三個整數的數位,並將其中每一個整數除以 1024。
30000, 56798, 12432 | ForEach-Object -Process {$_/1024}
29.296875
55.466796875
12.140625
範例 2:取得目錄中所有檔案的長度
此範例會處理 PowerShell 安裝目錄中的檔案和目錄 $PSHOME
。
Get-ChildItem $PSHOME |
ForEach-Object -Process {if (!$_.PSIsContainer) {$_.Name; $_.Length / 1024; " " }}
如果物件不是目錄,腳本區塊會取得檔案的名稱、將其 Length 屬性的值除以 1024,並將空格 (“ ”) “,將它與下一個專案分開。 Cmdlet 會使用 PSISContainer 屬性來判斷物件是否為目錄。
範例 3:在最新的系統事件上操作
此範例會將 1000 個最新的事件從系統事件記錄檔寫入文字檔。 目前的時間會顯示在處理事件之前和之後。
$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
會從系統事件記錄檔中取得1000個最新的事件,並將其儲存在變數中 $Events
。 $Events
接著會使用管線傳送至 ForEach-Object
Cmdlet。 Begin 參數會顯示目前的日期和時間。 接下來, Process 參數會 Out-File
使用 Cmdlet 來建立名為 events.txt 的文本檔,並將每個事件的訊息屬性儲存在該檔案中。 最後,會使用 End 參數,在所有處理都已完成之後顯示日期和時間。
範例 4:變更登錄機碼的值
本範例會將機碼下HKCU:\Network
所有子機碼中的 RemotePath 登錄專案值變更為大寫文字。
Get-ItemProperty -Path HKCU:\Network\* |
ForEach-Object {Set-ItemProperty -Path $_.PSPath -Name RemotePath -Value $_.RemotePath.ToUpper();}
您可以使用這個格式來變更登錄項目值的形式或內容。
Network 機碼中的每個子機碼代表在登入時將重新連線的連線網路磁碟機。
RemotePath 項目包含連線的磁碟機的 UNC 路徑。 例如,如果您將 E: 磁碟驅動器對應至 \\Server\Share
,則 E 子機碼會是 ,HKCU:\Network
而 E 子機碼\\Server\Share
中的 RemotePath 登錄專案值為 。
此命令會 Get-ItemProperty
使用 Cmdlet 來取得 網路 機 Set-ItemProperty
碼和 Cmdlet 的所有子機碼,以變更每個機碼中的 RemotePath 登錄專案值。
在 Set-ItemProperty
命令中,路徑是登錄機碼 的 PSPath 屬性值。 這是代表登錄機碼而非登錄專案之 Microsoft .NET Framework 對象的屬性。 此命令會使用 RemotePath 值的 ToUpper () 方法,這是字串 (REG_SZ) 。
因為 Set-ItemProperty
正在變更每個索引鍵的 屬性,所以 ForEach-Object
需要 Cmdlet 才能存取屬性。
範例 5:使用$Null自動變數
此範例顯示將自動變數管線傳送 $Null
至 ForEach-Object
Cmdlet 的效果。
1, 2, $null, 4 | ForEach-Object {"Hello"}
Hello
Hello
Hello
Hello
因為 PowerShell 會將 null 視為明確的佔位符,所以 ForEach-Object
Cmdlet 會產生的值 $Null
,就像對管線傳送給它的其他物件所做的一樣。
範例 6:取得屬性值
此範例會使用 Cmdlet 的 MemberName 參數,取得所有已安裝 PowerShell 模組的 ForEach-Object
Path 屬性值。
Get-Module -ListAvailable | ForEach-Object -MemberName Path
Get-Module -ListAvailable | Foreach Path
第二個命令同等於第一個命令。 它會使用 Foreach
Cmdlet 的 ForEach-Object
別名,並省略 MemberName 參數的名稱,這是選擇性的。
Cmdlet ForEach-Object
對於取得屬性值非常有用,因為它會取得值而不變更類型,不同於 Format Cmdlet 或 Select-Object
Cmdlet,這會變更屬性值類型。
範例 7:將模組名稱分割成元件名稱
此範例示範將兩個點分隔模組名稱分割成其元件名稱的三種方式。
"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
命令呼叫字串的 Split 方法。 這三個命令使用不同的語法,但它們是相等的並且可交換使用。
第一個命令會使用傳統的語法,其中包括腳本區塊和目前的物件運算子 $_
。 它使用點語法來指定要括住分隔符號引數的方法和括號。
第二個命令使用 MemberName 參數來指定 Split 方法,並使用 ArgumentName 參數來將點 (".") 識別為分隔符號。
第三個命令會使用 Cmdlet 的 ForEach-Object
Foreach 別名,並省略 MemberName 和 ArgumentList 參數的名稱,這是選擇性的。
範例 8:搭配兩個腳本區塊使用 ForEach-Object
在此範例中,我們會以位置傳遞兩個腳本區塊。 所有腳本區塊都會系結至 Process 參數。 不過,它們會被視為已傳遞至 Begin 和 Process 參數。
1..2 | ForEach-Object { 'begin' } { 'process' }
begin
process
process
範例 9:搭配兩個以上的腳本區塊使用 ForEach-Object
在此範例中,我們會以位置傳遞兩個腳本區塊。 所有腳本區塊都會系結至 Process 參數。 不過,它們會被視為已傳遞至 Begin、 Process 和 End 參數。
1..2 | ForEach-Object { 'begin' } { 'process A' } { 'process B' } { 'end' }
begin
process A
process B
process A
process B
end
注意
第一個腳本區塊一律會對應至 begin
區塊,最後一個區塊會對應至 end
區塊,而之間的區塊全都對應至 process
區塊。
範例 10:針對每個管線專案執行多個腳本區塊
如先前範例所示,使用 Process 參數傳遞的多個腳本區塊會對應至 Begin 和 End 參數。 若要避免此對應,您必須提供 Begin 和 End 參數的明確值。
1..2 | ForEach-Object -Begin $null -Process { 'one' }, { 'two' }, { 'three' } -End $null
one
two
three
one
two
three
參數
-ArgumentList
指定方法呼叫的自變數陣列。 如需 ArgumentList 行為的詳細資訊,請參閱 about_Splatting。
此參數是在 Windows PowerShell 3.0 引進。
Type: | Object[] |
Aliases: | Args |
Position: | Named |
Default value: | None |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-Begin
指定在此 Cmdlet 處理任何輸入物件之前執行的腳本區塊。 此腳本區塊只會針對整個管線執行一次。 如需 區塊的詳細資訊 begin
,請參閱 about_Functions。
Type: | ScriptBlock |
Position: | Named |
Default value: | None |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-Confirm
在執行 Cmdlet 前提示您確認。
Type: | SwitchParameter |
Aliases: | cf |
Position: | Named |
Default value: | False |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-End
指定在此 Cmdlet 處理所有輸入物件之後執行的腳本區塊。 此腳本區塊只會針對整個管線執行一次。 如需 區塊的詳細資訊 end
,請參閱 about_Functions。
Type: | ScriptBlock |
Position: | Named |
Default value: | None |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-InputObject
指定輸入物件。 ForEach-Object
在每個輸入對象上執行腳本區塊或 operation 語句。 輸入包含物件的變數,或輸入可取得物件的命令或運算式。
當您搭配 使用 InputObject 參數搭配 ForEach-Object
時,會將 InputObject 值視為單一物件,而不是將命令結果管線傳送至 ForEach-Object
。 即使值是命令結果的集合,例如 -InputObject (Get-Process)
,也是如此。
由於 InputObject 無法從物件的陣列或集合傳回個別屬性,因此,如果您用來 ForEach-Object
對定義屬性中具有特定值之物件的物件集合執行作業,請在 ForEach-Object
管線中使用,如本主題中的範例所示。
Type: | PSObject |
Position: | Named |
Default value: | None |
Required: | False |
Accept pipeline input: | True |
Accept wildcard characters: | False |
-MemberName
指定要取得的屬性或要呼叫的方法。
允許通配符,但只有在產生的字串解析為唯一值時,才能運作。
例如,如果您執行 Get-Process | ForEach -MemberName *Name
,而且有多個成員具有包含字串 Name 的名稱,例如 ProcessName 和 Name 屬性,命令就會失敗。
此參數是在 Windows PowerShell 3.0 引進。
Type: | String |
Position: | 0 |
Default value: | None |
Required: | True |
Accept pipeline input: | False |
Accept wildcard characters: | True |
-Process
指定在每個輸入物件上執行的操作。 此腳本區塊會針對管線中的每個物件執行。 如需 區塊的詳細資訊 process
,請參閱 about_Functions。
當您將多個腳本區塊提供給 Process 參數時,第一個腳本區塊一律會對應至 begin
區塊。 如果只有兩個腳本區塊,則第二個區塊會對應至 process
區塊。 如果有三個以上的腳本區塊,則第一個腳本區塊一律會對應至 begin
區塊,最後一個區塊會對應至 end
區塊,而兩者之間的區塊全都對應至 process
區塊。
Type: | ScriptBlock[] |
Position: | 0 |
Default value: | None |
Required: | True |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-RemainingScripts
指定 Process 參數未採用的所有腳本區塊。
此參數是在 Windows PowerShell 3.0 引進。
Type: | ScriptBlock[] |
Position: | Named |
Default value: | None |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
-WhatIf
顯示執行 Cmdlet 後會發生的情況。 Cmdlet 並不會執行。
Type: | SwitchParameter |
Aliases: | wi |
Position: | Named |
Default value: | False |
Required: | False |
Accept pipeline input: | False |
Accept wildcard characters: | False |
輸入
您可以使用管線將任何物件傳送至此 Cmdlet。
輸出
此 Cmdlet 會傳回輸入所決定的物件。
備註
Cmdlet
ForEach-Object
的運作方式與 Foreach 語句非常類似,不同之處在於您無法使用管線將輸入傳送至 Foreach 語句。 如需 Foreach 語句的詳細資訊,請參閱 about_Foreach。從 PowerShell 4.0 開始,
Where
已ForEach
新增方法以搭配集合使用。 您可以在這裡深入了解這些新方法 about_arrays