Windows Server 2022中Invoke-Command内Start-Process无法触发问题
问题分析与解决方案
问题概述
禁用UAC后通过Invoke-Command远程安装VMware Tools时,Shutdown.exe能正常触发重启定时器,但Start-Process在Windows Server 2022标准版无用户(RDP/本地控制台)登录时无法执行;仅当有用户登录时脚本正常,且该脚本在Windows Server 2012 R2/2016/2019上运行无问题。
涉及脚本片段:
$upgradeInvoke = Invoke-Command -Session $session -ScriptBlock { try { Shutdown.exe /r /f /t 1200 /d p:4:2 /c "Triggerd Reboot Timer for 20 minitus" $arguments = "/s", "/v`"/qn REBOOT=ReallySuppress`"" $process = Start-Process -FilePath $using:setupFullPath -ArgumentList $arguments -PassThru -Wait -Verb runas Write-Output $process.ExitCode } catch { Write-Output "An error occurred: $($_.Exception.Message)" } } -WarningAction SilentlyContinue -ErrorAction Stop
可能原因
Windows Server 2022对非交互式远程会话的权限管控进一步收紧:
- 即使禁用UAC,
-Verb runas参数会强制尝试提权,而无交互式桌面会话时,系统无法完成提权验证,导致进程静默失败。 - 低版本Server对非交互式会话的提权限制更宽松,因此脚本能正常运行。
解决方案
1. 移除-Verb runas参数
既然已禁用UAC,远程会话使用的管理员账户默认拥有足够权限,无需额外提权。修改后的Start-Process命令:
$process = Start-Process -FilePath $using:setupFullPath -ArgumentList $arguments -PassThru -Wait -ErrorAction Stop
添加-ErrorAction Stop可以让异常被try/catch捕获,方便排查后续问题。
2. 直接调用安装程序(替代Start-Process)
对于VMware Tools的MSI安装包,可直接用&执行或调用msiexec,减少Start-Process的封装层问题:
# 假设setupFullPath是VMware Tools的MSI文件路径 $exitCode = & msiexec.exe /i $using:setupFullPath /qn REBOOT=ReallySuppress Write-Output $exitCode
3. 验证远程会话权限
确保用于Invoke-Command的账户是目标服务器的本地管理员组成员,且在Windows Server 2022上已启用:
- 远程执行权限(通过
Enable-PSRemoting确认) - 非交互式登录权限(在本地安全策略→用户权限分配中,确保账户拥有“允许通过远程桌面服务登录”权限)
4. 增强错误排查
在脚本中添加更详细的日志输出,确认Start-Process的执行状态:
try { Shutdown.exe /r /f /t 1200 /d p:4:2 /c "Triggerd Reboot Timer for 20 minitus" $arguments = "/s", "/v`"/qn REBOOT=ReallySuppress`"" Write-Output "Attempting to start process: $using:setupFullPath with args: $($arguments -join ' ')" $process = Start-Process -FilePath $using:setupFullPath -ArgumentList $arguments -PassThru -Wait -ErrorAction Stop Write-Output "Process exit code: $($process.ExitCode)" } catch { Write-Output "Error details: $_" Write-Output "Exception message: $($_.Exception.Message)" Write-Output "Script stack trace: $($_.ScriptStackTrace)" }
内容的提问来源于stack exchange,提问作者SpicerLabs
相关产品推荐
相关产品推荐

