系统学习 Windows 学习路径:从 CMD 到 PowerShell、系统网络,再到 WSL 与 Server

ForEach-Object

对管道中的每个对象执行脚本块,用于转换、批量操作和带状态的遍历。

补充说明

ForEach-Object 逐个接收管道对象,对每个对象运行 -Process 脚本块,输出脚本块写出的任何内容;别名是 foreach 和 %。-Begin 在第一个对象前执行一次,-End 在全部对象后执行一次,适合计数、汇总和打开/关闭资源;-MemberName 可直接调用属性或方法。

管道:-InputObject 按值接收对象,也是该命令的主要输入方式;脚本块内用 $_(或 $PSItem)引用当前对象。权限:命令本身不需要权限,脚本块里的操作按目标资源的 ACL 判断。边界:它负责“对每个对象做事”,筛选用 Where-Object,选列用 Select-Object;foreach 关键字适合内存集合和需要 break/continue 的循环。

版本:5.1 没有并行参数,循环是串行执行;7.x 差异:提供 -Parallel 和 -ThrottleLimit,在独立运行空间中并发执行,变量必须用 $using: 传入,输出顺序不保证。

常用示例

# 1. 对数字序列逐个计算,验证脚本块输入输出
PS C:\> 1..5 | ForEach-Object { $_ * 2 }

# 2. 把文件对象转换成自定义结果,保留需要的字段
PS C:\> Get-ChildItem C:\Logs -File | ForEach-Object { [pscustomobject]@{ Name=$_.Name; KB=[math]::Round($_.Length/1KB,1) } }

# 3. 用 Begin/Process/End 统计行数,只输出一次汇总
PS C:\> Get-Content C:\Logs\app.log | ForEach-Object -Begin { $i=0 } -Process { $i++ } -End { "total=$i" }

# 4. 对每个匹配进程取 Id,供后续精确操作
PS C:\> Get-Process -Name chrome -ErrorAction SilentlyContinue | ForEach-Object { $_.Id }

# 5. 7.x 差异:并行处理,用 $using: 传入父作用域变量
PS C:\> $root = 'C:\Temp'; 1..3 | ForEach-Object -Parallel { Join-Path $using:root $_ } -ThrottleLimit 2

# 6. 对每个文件执行检查,并用 -ErrorAction Stop 暴露首个错误
PS C:\> Get-ChildItem C:\Data -File | ForEach-Object { Get-Content $_.FullName -TotalCount 1 -ErrorAction Stop }

易错点与排错

相关命令

参考链接

读完自测

合上页面,先回答,再展开对照。

  1. ForEach-Object 脚本块里的 return 会终止整个管道吗?
  2. 7.x 的 -Parallel 为什么不能直接读父作用域的普通变量?
  3. foreach 关键字和 ForEach-Object 各适合什么场景?
答案
  1. 不会;它只结束当前对象的这一轮,后续对象继续处理。
  2. 每个并行分支在独立运行空间中执行;需要用 $using: 显式传入父作用域变量。
  3. 关键字适合内存集合和需要 break/continue 的循环;cmdlet 适合流式管道处理。
微信小程序码:扫码打开命令速查小程序

小程序版

微信扫码,随时查命令