foreach-object 是专为管道设计的 cmdlet,必须通过 | 接收输入,不能直接遍历数组;需写成 $arr | foreach-object { $_ },其中 $_ 代表当前管道对象,区别于语言关键字 foreach ($x in $arr)。
在 powershell 中,foreach-object 不是用来直接遍历普通数组变量的语法结构,而是专为**管道(pipeline)场景**设计的 cmdlet。它必须配合管道符 | 使用,作用对象是“流经管道的每个输入项”。如果你手头是一个已定义好的数组(比如 $arr = 1,2,3),想用 foreach-object 处理,得先把它送进管道——不能像 foreach ($x in $arr) 那样直接写在语句开头。
怎么把数组送进管道再用 Foreach-Object
最常用也最自然的方式是:用管道符把数组变量推给 Foreach-Object。PowerShell 会自动展开数组,逐个传递元素。
$numbers = 10, 20, 30-
$numbers | ForEach-Object { $_ * 2 }→ 输出20、40、60 - 其中
$_是当前管道对象的自动变量,代表正在处理的那个数
两种简洁写法:脚本块 vs 属性/方法名
从 PowerShell 3.0 起,Foreach-Object 支持更简短的调用形式,无需大括号和 $_:
- 取属性:
Get-Process | ForEach-Object ProcessName(等价于{ $_.ProcessName }) - 调用方法:
Get-ChildItem | ForEach-Object FullName或Get-ChildItem | ForEach-Object ToString - 注意:这种写法只适用于直接访问属性或无参方法;带参数的方法仍需用完整脚本块
常见误区:别和 foreach 语句混淆
foreach ($item in $collection) 是语言关键字,用于代码块内遍历任意集合(包括数组、哈希表、命令输出等),不依赖管道;而 Foreach-Object 是 cmdlet,只响应管道输入。
- ✅ 正确管道用法:
$files = Get-ChildItem C:\Temp; $files | ForEach-Object { Write-Host $_.Name } - ❌ 错误写法:
Foreach-Object $files { ... }(语法错误,缺少管道) - ⚠️ 性能提示:对大型数组,
foreach语句通常比管道 +Foreach-Object更快,因后者涉及管道开销
配合条件筛选时的典型组合
实际脚本中,Foreach-Object 常和 Where-Object 搭配使用,先过滤再处理:
Get-Service | Where-Object {$_.Status -eq 'Running'} | ForEach-Object { "$($_.Name) is running" }- 也可以把判断逻辑放进
Foreach-Object内部:... | ForEach-Object { if ($_.Status -eq 'Running') { $_.Name } } - 但推荐前者——职责分离更清晰,且
Where-Object会提前剪枝,减少后续处理量











