Invoke-Command的LastExitCode不符合预期,Jenkins脚本未正确报错
解决Jenkins中PowerShell远程执行netsh命令退出码未正确传递的问题
这个问题我之前也碰到过,核心问题在于远程会话的$LastExitCode不会自动同步到本地PowerShell会话,你当前脚本里判断的$LastExitCode其实是Invoke-Command这个cmdlet本身的执行结果(只要远程会话能正常执行脚本块,它的退出码就是0),而不是远程机器上netsh命令的退出码,这就导致文件存在时无法触发预期的exit 1。
问题分析
当你用Invoke-Command执行远程脚本块时,脚本块里的外部命令(比如netsh)的退出码只存在于远程会话中,本地的$LastExitCode记录的是Invoke-Command是否成功完成了远程调用,而非远程命令的执行结果。所以即使远程的netsh因为文件存在返回了退出码1,本地的$LastExitCode依然是0,自然不会进入判断分支。
解决方案:手动传递远程命令的退出码
你需要在远程脚本块里捕获netsh的退出码,然后将其返回给本地会话,再根据返回值决定是否退出。修改后的脚本如下:
$Time = $args[1] $Server = $args[2] $username = $args[3] $password = $args[4] $pass="$password"|ConvertTo-SecureString -AsPlainText -Force $Cred = New-Object System.Management.Automation.PsCredential("ad\$username",$pass) $session = New-PSSession -ComputerName $Server -Credential $Cred -ErrorAction Stop # 执行netsh trace start并获取远程退出码 $startExitCode = Invoke-Command -Session $session -ScriptBlock { netsh trace start capture=yes tracefile=C:\Traces\netsh.etl return $LastExitCode # 将远程netsh的退出码返回给本地 } If ($startExitCode -eq 1) { Write-Host "netsh trace start failed: 文件已存在" exit 1 } write-host "hello world" start-sleep -Seconds $Time # 执行netsh trace stop并获取远程退出码 $stopExitCode = Invoke-command -Session $session -ScriptBlock { netsh trace stop return $LastExitCode } If ($stopExitCode -eq 1) { Write-Host "netsh trace stop failed" exit 1 } exit 0
额外说明
- 如果你希望在远程命令失败时直接终止脚本,还可以在远程脚本块中设置
$ErrorActionPreference = 'Stop',但注意外部命令(如netsh)的失败不会触发PowerShell的错误流,所以还是需要手动返回退出码来做判断。 - 确保远程机器上的
C:\Traces目录存在,否则netsh也会因为无法写入文件返回错误,这个场景也可以用同样的方式捕获退出码。
内容的提问来源于stack exchange,提问作者YeBoi
相关产品推荐
相关产品推荐

