批量并发执行是怎么回事
对多台机器执行同一条命令时,串行会非常慢,全速并发又可能压垮目标或域控认证。PowerShell 提供了两级控制:远程批量用 Invoke-Command 的 -ThrottleLimit(默认 32)限制同时进行的连接数;本机任务并行用 ForEach-Object -Parallel(PowerShell 7 起支持)配合 -ThrottleLimit。核心思路是“先限流跑通,再逐步提速”。
基本信息
| 适用平台 | Invoke-Command 全版本;ForEach-Object -Parallel 需 PowerShell 7+ |
|---|---|
| 远程并发 | Invoke-Command -ComputerName $hosts -ThrottleLimit 10 |
| 本机并行 | 1..10 | ForEach-Object -Parallel { ... } -ThrottleLimit 5 |
| 传参方式 | 并行块内引用外部变量需用 $using: 前缀 |
典型使用场景
- 批量检查:几百台机器上确认服务状态、磁盘剩余与补丁版本
- 批量变更:分批下发配置或重启服务,控制影响面
- 限流保护:域控认证压力大时把并发压到很低,避免登录风暴
- 耗时任务并行:本机对大量文件做压缩、哈希计算时用并行加速
- 分批推进:先跑 10 台验证,确认无误再放大到全部
常用示例
常用示例
# 远程批量:并发 10,收集服务状态
$hosts = (Get-Content D:\hosts.txt)
Invoke-Command -ComputerName $hosts -ThrottleLimit 10 -ScriptBlock {
Get-Service WinRM | Select-Object PSComputerName, Status
} -ErrorAction SilentlyContinue
# PowerShell 7 本机并行:并发 5(注意 $using: 传参)
$targets = 1..20
$targets | ForEach-Object -Parallel {
Start-Sleep -Milliseconds 200
"处理 $_"
} -ThrottleLimit 5
# 分批推进:每次 20 台一组
$hosts | ForEach-Object -Begin { $i = 0 } -Process { $i++ } | Out-Null并发参数对比
| 场景 | 参数 | 默认与建议 |
|---|---|---|
| 远程命令 | Invoke-Command -ThrottleLimit | 默认 32;生产变更建议 5-10 |
| 远程会话 | New-PSSession 批量建会话 | 会话数量同样要限流 |
| 本机并行 | ForEach-Object -Parallel -ThrottleLimit | 默认 5;CPU 密集任务按核数调 |
| SMB 复制 | robocopy /MT | 线程数过高反而拖慢存储 |
ThrottleLimit 是“同时进行”的上限,不是总数量上限。并发过高时最典型的后果是目标机 CPU 与网络被打满,或者域控因为同时处理大量认证而变慢,表现为随机几台超时。
ForEach-Object -Parallel 的脚本块运行在独立运行空间,父作用域变量必须用 $using: 传入,直接引用会得到空值而使脚本静默出错。
对生产系统做批量变更要留回滚路径:先在一台机器验证命令,再小批量(5-10 台)验证,再分批推进。一次性对全部机器下变更命令,出错时影响面不可控。