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}

  • 操作语句。 还可以编写操作语句,这更像是自然语言。 你可以使用该操作语句来指定属性值或调用方法。 Windows PowerShell 3.0 中引入了操作语句。

    例如,以下命令还将获取计算机上每个进程的 ProcessName 属性值。

    Get-Process | ForEach-Object ProcessName

    在使用脚本块格式时,除了使用描述了针对每个输入对象所执行的操作的脚本块外,你还可以提供其他两个脚本块。 Begin 脚本块( Begin 参数的值 )在此 cmdlet 处理第一个输入对象之前运行。 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 注册表条目的值更改为大写文本。 可以使用此格式更改注册表条目值的形式或内容。

Network 项中的每个子项都表示将在登录时重新连接的映射网络驱动器。 RemotePath 项包含连接的驱动器的 UNC 路径。 例如,如果将 E: 驱动器映射到 \\Server\Share,将存在 HKCU:\Network 的一个 E 子项,并且 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自动变量

1, 2, $null, 4 | ForEach-Object {"Hello"}

Hello
Hello
Hello
Hello

此示例演示将自动变量管道 $Null 传递到 ForEach-Object cmdlet 的效果。

由于 PowerShell 将 null 视为显式占位符,因此 cmdlet ForEach-Object 会为 $Null生成值,就像为传递给它的其他对象一样。

有关自动变量的详细信息 $Null ,请参阅 about_Automatic_Variables。

示例 6:获取属性值

Get-Module -ListAvailable | ForEach-Object -MemberName Path
Get-Module -ListAvailable | Foreach Path

这些命令获取所有已安装的 PowerShell 模块的 Path 属性的值。 它们使用 MemberName 参数来指定模块的 Path 属性。

第二个命令等效于第一个命令。 它使用 cmdlet 的 ForEach-ObjectForeach 别名,并省略 MemberName 参数的名称(可选)。

cmdlet ForEach-Object 对于获取属性值非常有用,因为它在不更改类型的情况下获取值,这与 格式 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 别名,并省略 MemberNameArgumentList 参数的名称,这些参数是可选的。

这三个命令的输出是相同的,如下所示。

Split 仅仅是许多有用的字符串方法之一。 若要查看字符串的所有属性和方法,请通过管道将字符串传递给 Get-Member cmdlet。

参数

-ArgumentList

指定方法调用的参数数组。

已在 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 处理任何输入对象之前运行的脚本块。

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 处理所有输入对象后运行的脚本块。

Type:ScriptBlock
Position:Named
Default value:None
Required:False
Accept pipeline input:False
Accept wildcard characters:False

-InputObject

指定输入对象。 ForEach-Object 在每个输入对象上运行脚本块或操作语句。 输入一个包含对象的变量,或键入可获取对象的命令或表达式。

InputObject 参数与 一起使用 ForEach-Object时,而不是将命令结果传递给 ForEach-Object时, InputObject 值被视为单个对象。 即使值是命令的结果(如 -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 的成员(如 ProcessNameName 属性),则命令将失败。

已在 Windows PowerShell 3.0 中引入了此参数。

Type:String
Position:0
Default value:None
Required:True
Accept pipeline input:False
Accept wildcard characters:True

-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

输入

PSObject

你可以通过管道将任何对象传递给此 cmdlet。

输出

PSObject

此 cmdlet 返回由输入确定的对象。

备注

  • cmdlet ForEach-Object 的工作方式与 Foreach 语句非常类似,只不过不能通过管道将输入传递给 Foreach 语句。 有关 Foreach 语句的详细信息,请参阅 about_Foreach
  • 从 PowerShell 4.0 开始, WhereForEach 添加了 用于集合的方法。
  • 可在此处阅读有关这些新方法 的详细信息about_arrays