PowerShell脚本无法捕获EXE程序返回值问题求助
问题分析
你遇到的核心问题是用Start-Process -Verb RunAs启动的提升权限进程,无法通过$LASTEXITCODE获取退出码,这是因为:
-Verb RunAs会创建一个独立的、拥有管理员权限的进程会话,这个会话和当前PowerShell会话完全隔离,$LASTEXITCODE只会记录当前会话中直接执行的进程退出码,所以拿不到提升权限进程的返回值。- 你的原代码还存在两个小问题:
- 没有用
-PassThru参数获取进程对象,导致后续用Get-Process可能匹配到多个同名进程,准确性无法保证。 Start-Process默认不会捕获StandardOutput,直接访问.StandardOutput会返回null,而且你漏写了ToString()的括号。
- 没有用
解决方案
要正确捕获提升权限EXE的退出码,你需要通过Start-Process的-PassThru参数获取进程对象,然后读取其ExitCode属性。以下是修正后的完整脚本:
# 用Join-Path更安全地拼接路径(避免手动拼接的路径分隔符问题) $file = Join-Path $PSScriptRoot "executor.exe" # 假设$Logfile已经在脚本中定义过 $logfile = $Logfile # 启动提升权限的进程,返回Process对象并等待其完成 $process = Start-Process -FilePath $file ` -ArgumentList $logfile ` -Verb RunAs ` -WindowStyle Hidden ` -PassThru ` -Wait # 从进程对象中获取真实的退出码 $exitCode = $process.ExitCode # 根据你的EXE返回规则判断结果 if ($exitCode -eq 1) { LogWrite "Execution succeeded" } else { LogWrite "Execution Failed" }
关键说明
-PassThru:让Start-Process返回对应的System.Diagnostics.Process对象,而不是默认的无返回值。-Wait:让PowerShell暂停执行,直到目标进程完全结束,这样就能直接读取ExitCode(不需要额外调用Wait-Process)。$process.ExitCode:不管进程是否是提升权限的,只要能拿到进程对象,就能获取到它的真实退出码,这是最可靠的方式。
额外:如果需要捕获EXE的输出
如果你还需要获取EXE的StandardOutput,可以加上-RedirectStandardOutput参数将输出重定向到临时文件,再读取文件内容:
$outputFile = Join-Path $env:TEMP "executor_output.log" $process = Start-Process -FilePath $file ` -ArgumentList $logfile ` -Verb RunAs ` -WindowStyle Hidden ` -PassThru ` -Wait ` -RedirectStandardOutput $outputFile # 读取输出内容 $exeOutput = Get-Content $outputFile -Raw # 这里可以处理输出,比如打印或写入日志 Write-Host "EXE输出:$exeOutput" # 清理临时文件 Remove-Item $outputFile -Force -ErrorAction SilentlyContinue # 继续判断退出码 $exitCode = $process.ExitCode if ($exitCode -eq 1) { LogWrite "Execution succeeded" } else { LogWrite "Execution Failed" }
补充:非提升权限场景的简化写法
如果你的EXE不需要管理员权限,可以直接调用EXE,这时$LASTEXITCODE就能正常工作:
& $file $logfile $exitCode = $LASTEXITCODE if ($exitCode -eq 1) { LogWrite "Execution succeeded" } else { LogWrite "Execution Failed" }
内容的提问来源于stack exchange,提问作者Rem San




