首页/系统/Windows 运维速查/ForEach-Object 逐项处理
PowerShell 基础66 条

ForEach-Object 逐项处理

对管道中每个对象执行操作:可直接调用方法,也可在脚本块里用 $_ 计算(PS7 起支持 -Parallel 并发)。

Windows 运维速查系统更新于 2026-10-13

ForEach-Object 是什么

ForEach-Object 对管道里的每个对象执行一次操作,是「拿到一批对象后逐个动手」的通用工具。它既能做纯计算,也能产生副作用,比如调用方法、启动服务、写文件、调用外部程序。脚本块里用 $_ 指代当前对象,也可以用 -Begin、-Process、-End 三个块分别做初始化、逐项处理与收尾。PowerShell 7 起还支持并发参数,让互不依赖的逐项任务同时跑,这在批量巡检大量主机时能显著缩短耗时。

基本信息

适用平台Windows PowerShell 5.1 与 PowerShell 7 及以上(并发参数仅 7 及以上)
语法ForEach-Object { 处理逻辑 } 或 ForEach-Object -Begin {} -Process {} -End {}
别名百分号(交互时常用,脚本里建议写全名)
并发参数-Parallel 并行执行、-ThrottleLimit 控制并发数量(PowerShell 7 及以上)
当前对象脚本块里用 $_,也可以显式声明参数名接收当前对象
与语句的区别ForEach-Object 走管道流式处理,foreach 语句会先取完整集合再循环

典型使用场景

  • 批量重启或停止服务:先筛选出目标再从管道逐项执行
  • 批量落盘:为每条记录生成单独的文件或追加写入日志
  • 批量调用外部程序:对每个目标主机执行一次探测命令
  • 逐项计算:把对象的某个属性做换算或拼接成新字符串
  • 带初始化的处理:用开始块建立计数器或连接,结束时统一收尾
  • 并发执行:对互不依赖的主机列表并行做巡检

常用示例

常用示例
# 逐项取下运行中服务的名称
Get-Service | Where-Object Status -eq Stopped | ForEach-Object { $_.Name }
# 逐项计算:把字节数换算成 KB
Get-ChildItem *.log | ForEach-Object { $_.Length / 1KB }
# 带初始化与收尾:统计处理条数
$count = 0
Get-ChildItem C:\Logs -File | ForEach-Object -Begin { $count = 0 } -Process { $count++ } -End { "共处理 $count 个文件" }
# 批量重启:先筛选,再逐项执行
Get-Service -Name Spooler, W32Time | ForEach-Object { Restart-Service $_.Name }
# 并发处理多个主机(PowerShell 7 及以上)
1..4 | ForEach-Object -Parallel { "主机 $_" } -ThrottleLimit 2

参数与用法对照

用法作用注意点
-Process 块对每个对象执行处理逻辑默认块,省略时整段脚本块即处理逻辑
-Begin 块处理开始前执行一次适合初始化累加器或连接
-End 块处理结束后执行一次适合输出汇总结果
-Parallel并行处理管道对象(版本要求较高)脚本块内变量需用 using 前缀传入
-ThrottleLimit限制并发数量并发过高会压垮目标主机与网络
-InputObject直接传入集合而非走管道会作为单个对象处理,行为与管道不同

与 foreach 语句的差异

对比项ForEach-Objectforeach 语句
数据来源管道逐个流入先取出完整集合
内存占用流式处理,占用小集合全量在内存中
能否提前退出可在脚本块内使用返回或中断控制支持 break 与 continue
适用位置管道中任意位置脚本语句块中
只做纯取值与换算时,优先用 Select-Object,它不需要为每条记录执行完整脚本块,速度更快;需要副作用时才交给 ForEach-Object。
并发参数只适合互不依赖的任务。若脚本块内要修改共享变量或写同一个文件,并发会带来竞争,应改用串行处理或在每个分支里独立写目标。
脚本块里也能直接调用对象的方法,例如对每个服务对象调用停止方法。方法与属性不同,必须带上括号;如果只是想取值,用属性即可,不必包一层循环。

易错点

  • 脚本块里忘写 $_ 却以为在取值:结果输出为空或全是常量,先去掉外层命令单独验证一段逻辑再上批量
  • 把 ForEach-Object 当成 foreach 语句用:管道中不支持 break 与 continue,需要中断逻辑时要改写结构
  • 并发处理里直接引用外部变量:不会自动传值,需用 using 前缀显式传入,否则脚本块里取到的是空值
  • 并发写同一文件:多线程互相覆盖,输出内容错乱,需为每个分支指定独立目标或改回串行
  • 在管道中做重活:逐项远程调用或启动进程会让整条管道变慢,能前置筛选就不要在循环里筛

数据来源与参考

  • Microsoft Learn:ForEach-Object

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌