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