Invoke-Command中Start-Process需-Wait才不闪退,如何继续执行脚本?
解决远程运行Windows Update Assistance Installer的阻塞/进程终止问题
问题分析
远程执行Windows升级程序时陷入两难:
- 使用
Start-Process -Wait会让Invoke-Command持续等待升级完成(耗时数小时),直接阻塞遍历其他电脑的循环 - 移除
-Wait参数后,远程PowerShell会话执行完脚本块就会关闭,导致升级进程被强制终止
解决方案
方案1:将远程任务转为后台作业(保留-Wait,不阻塞循环)
借助Invoke-Command的-AsJob参数,把每台电脑的升级任务转为后台作业,循环可继续处理下一台设备,后续再统一查看作业状态。
示例代码:
$computers | ForEach-Object { # 省略建立会话等前置代码... # 启动后台作业执行升级 $job = Invoke-Command -Session $Session -ScriptBlock { $upgradeExe = "C:\windows\temp\Windows10Upgrade9252(21H2).exe" $args = '/quietinstall /skipeula /auto upgrade /copylogs' Start-Process -FilePath $upgradeExe -ArgumentList $args -Wait } -AsJob -JobName "WinUpgrade_$_" Write-Host "已启动电脑 $_ 的升级作业,作业ID:$($job.Id)" } # 后续查看所有升级作业状态 Get-Job -Name WinUpgrade_* # 接收指定作业的执行结果(用于排查错误) Receive-Job -Id <作业ID> -Keep
方案2:用WMI/CIM启动独立进程(脱离远程会话,无需-Wait)
通过WMI/CIM启动的进程属于系统级会话,不会随PowerShell远程会话结束而终止,脚本块执行后即可继续处理其他电脑,无需等待升级完成。
示例代码:
$computers | ForEach-Object { # 省略建立会话等前置代码... Invoke-Command -Session $Session -ScriptBlock { $upgradeExe = "C:\windows\temp\Windows10Upgrade9252(21H2).exe" $fullArgs = "$upgradeExe /quietinstall /skipeula /auto upgrade /copylogs" # 用CIM启动进程(WMI的现代替代方案) Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{ CommandLine = $fullArgs } } }
注意事项
- 方案1的后台作业可保留升级过程输出,便于后续排查问题;方案2更轻量化,但需通过目标机器的日志或进程列表手动确认升级状态。
- 确保目标机器的WMI/CIM服务正常运行,且执行账户拥有创建系统进程的权限。
- 提前验证升级程序的参数有效性,避免因参数错误导致进程意外退出。
内容的提问来源于stack exchange,提问作者DrixlRey
相关产品推荐
相关产品推荐

