Invoke-Command执行缓慢,含1万台电脑的PowerShell脚本如何提速?
加速批量执行Invoke-Command的PowerShell脚本优化方案
原脚本核心问题是串行逐个发起远程调用,面对10000台机器时执行效率极低。利用Invoke-Command支持批量传入计算机数组的特性,结合并行执行可大幅提速,具体优化方案如下:
关键优化措施
- 批量并行执行:将需要处理的计算机一次性传给
Invoke-Command,通过-ThrottleLimit参数控制并发数(默认32,可根据网络和服务器负载调整,比如设为80-100),让多台机器同时执行远程命令 - 预筛选目标机器:先从CSV中过滤出未获取过数据(
Appx为空)或标记为不可达的机器,只对这些机器发起远程调用,避免重复操作 - 远程端处理数据:在远程脚本块内直接把所有Appx包名拼接成字符串,仅传回最终结果,减少网络传输的数据量
- 统一错误处理:用
-ErrorVariable收集批量执行中的错误,后续统一生成不可达标记,替代逐个try/catch的冗余逻辑
修改后的脚本
# 导入计算机列表 $computers = Import-Csv "C:\temp\computers.csv" # 筛选出需要处理的机器:Appx为空或标记为不可达 $targetComputers = $computers | Where-Object { $null -eq $_.Appx -or $_.Appx -eq 'Port closed or computer unreachable' } | Select-Object -ExpandProperty Name # 批量执行远程命令,设置并发数 $remoteResults = Invoke-Command -ComputerName $targetComputers -ScriptBlock { # 在远程机器上直接拼接所有Appx包名 $appxNames = (Get-AppxPackage -AllUsers).Name -join ";" [pscustomobject]@{ ComputerName = $env:COMPUTERNAME Appx = $appxNames } } -ErrorAction SilentlyContinue -ErrorVariable remoteErrors -ThrottleLimit 100 # 处理执行失败的机器,生成不可达记录 $errorResults = $remoteErrors | ForEach-Object { [pscustomobject]@{ ComputerName = $_.TargetObject Appx = "Port closed or computer unreachable" } } # 合并结果:原CSV已有有效记录 + 远程成功记录 + 错误记录 $allResults = @( # 原CSV中已获取到有效Appx数据的记录 $computers | Where-Object { $null -ne $_.Appx -and $_.Appx -ne 'Port closed or computer unreachable' } | Select-Object ComputerName, Appx # 远程执行成功的记录 $remoteResults # 执行失败的记录 $errorResults ) # 导出最终结果 $allResults | Export-Csv -Path "C:\Temp\MSStoreReport.csv" -NoTypeInformation -Encoding UTF8
额外优化建议
- 预检测在线状态:如果离线机器占比高,可先对
$targetComputers做ping测试,只保留在线机器再发起远程调用,减少无效的WinRM连接尝试:$onlineComputers = $targetComputers | Where-Object { Test-Connection -ComputerName $_ -Count 1 -Quiet -ErrorAction SilentlyContinue } - 调整WinRM超时:针对响应慢的机器,可通过
-SessionOption设置更长的超时时间:$sessionOptions = New-PSSessionOption -OperationTimeout 60000 # 60秒超时 Invoke-Command -ComputerName $onlineComputers -ScriptBlock {...} -SessionOption $sessionOptions ... - 分批处理超大规模列表:若10000台机器一次性处理压力大,可将
$targetComputers分成多个批次(比如每批200台)依次执行,避免单次并发过高导致网络拥堵
内容的提问来源于stack exchange,提问作者Arbelac
相关产品推荐
相关产品推荐

