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>]
说明
ForEach-Object
cmdlet 对输入对象集合中的每个项执行作。 可以通过管道将输入对象传递给 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 语句。 还可以编写一个作语句,这更像是自然语言。 可以使用 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 个最新事件从系统事件日志写入文本文件。 当前时间显示在处理事件之前和之后。
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
从系统事件日志获取 1000 个最新事件,并将其传递给 ForEach-Object
cmdlet。
Begin 参数显示当前日期和时间。 接下来,Process 参数使用 Out-File
cmdlet 创建一个名为 events.txt 的文本文件,并将每个事件的消息属性存储在该文件中。 最后,End 参数用于显示完成所有处理后的日期和时间。
示例 4:更改注册表项的值
本示例将 RemotePath 注册表项的值更改为大写文本,将 HKCU:\Network
键下的所有子项的值更改为大写。
Get-ItemProperty -Path HKCU:\Network\* |
ForEach-Object {
Set-ItemProperty -Path $_.PSPath -Name RemotePath -Value $_.RemotePath.ToUpper()
}
可以使用此格式更改注册表项值的窗体或内容。
网络 密钥中的每个子项都表示在登录时重新连接的映射网络驱动器。
RemotePath 条目包含连接的驱动器的 UNC 路径。 例如,如果将 E:
驱动器映射到 \\Server\Share
,则会在 HKCU:\Network
中创建一个 E 子项,并将 RemotePath 注册表值设置为 \\Server\Share
。
该命令使用 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:获取属性值
此示例使用 ForEach-Object
cmdlet 的 MemberName 参数获取所有已安装 PowerShell 模块的 Path 属性的值。
Get-Module -ListAvailable | ForEach-Object -MemberName Path
Get-Module -ListAvailable | Foreach 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
第一个命令使用传统语法,其中包括脚本块和当前对象运算符 $_
。 它使用点语法来指定方法和括号以将分隔符参数括起来。
第二个命令使用 MemberName 参数指定 Split 方法和 ArgumentList 参数,以将点(.
)标识为拆分分隔符。
第三个命令使用 ForEach-Object
cmdlet 的 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 中引入的。
类型: | Object[] |
别名: | Args |
Position: | Named |
默认值: | None |
必需: | False |
接受管道输入: | False |
接受通配符: | False |
-Begin
指定在此 cmdlet 处理任何输入对象之前运行的脚本块。 此脚本块仅针对整个管道运行一次。 有关 begin
块的详细信息,请参阅 about_Functions。
类型: | ScriptBlock |
Position: | Named |
默认值: | None |
必需: | False |
接受管道输入: | False |
接受通配符: | False |
-Confirm
在运行 cmdlet 之前,提示你进行确认。
类型: | SwitchParameter |
别名: | cf |
Position: | Named |
默认值: | False |
必需: | False |
接受管道输入: | False |
接受通配符: | False |
-End
指定在此 cmdlet 处理所有输入对象之后运行的脚本块。 此脚本块仅针对整个管道运行一次。 有关 end
块的详细信息,请参阅 about_Functions。
类型: | ScriptBlock |
Position: | Named |
默认值: | None |
必需: | False |
接受管道输入: | False |
接受通配符: | False |
-InputObject
指定输入对象。
ForEach-Object
在每个输入对象上运行脚本块或作语句。 输入包含对象的变量,或键入获取对象的命令或表达式。
将 InputObject 参数用于 ForEach-Object
时,InputObject 值将视为单个对象,而不是将命令结果传递给 ForEach-Object
。 即使值是命令的结果(如 -InputObject (Get-Process)
),也是如此。
由于 InputObject 无法从对象数组或对象集合中返回单个属性,因此,如果使用 ForEach-Object
对那些在定义属性中具有特定值的对象的对象集合执行作,则可以在管道中使用 ForEach-Object
,如本主题中的示例所示。
类型: | PSObject |
Position: | Named |
默认值: | None |
必需: | False |
接受管道输入: | True |
接受通配符: | False |
-MemberName
指定要获取的成员属性的名称或要调用的成员方法。 成员必须是实例成员,而不是静态成员。
允许通配符,但仅在生成的字符串解析为唯一值时才起作用。
例如,如果运行 Get-Process | ForEach -MemberName *Name
,则通配符模式匹配多个成员,导致命令失败。
此参数是在 Windows PowerShell 3.0 中引入的。
类型: | String |
Position: | 0 |
默认值: | None |
必需: | True |
接受管道输入: | False |
接受通配符: | True |
-Process
指定对每个输入对象执行的作。 此脚本块针对管道中的每个对象运行。 有关 process
块的详细信息,请参阅 about_Functions。
向 Process 参数提供多个脚本块时,第一个脚本块始终映射到 begin
块。 如果只有两个脚本块,第二个块将映射到 process
块。 如果有三个或更多个脚本块,则第一个脚本块始终映射到 begin
块,最后一个块映射到 end
块,中间块映射到 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 返回由输入确定的对象。
备注
Windows PowerShell 包含以下 ForEach-Object
别名:
%
foreach
ForEach-Object
cmdlet 的工作方式与 foreach 语句 非常类似,不同之处在于无法通过管道将输入传递给 Foreach 语句。 有关 Foreach 语句 的详细信息,请参阅 about_Foreach。
从 PowerShell 4.0 开始,添加了用于集合的 Where
和 ForEach
方法。 可以在此处阅读有关这些新方法的详细信息,about_arrays