PsTools 学习笔记(7.4):PsExec —— 远程进程的退出与控制台输出重定向
PsTools 学习笔记(7.4):PsExec —— 远程进程的退出与控制台输出重定向
- PsTools 学习笔记(7.4):PsExec —— 远程进程的退出与控制台输出重定向
- 1. 退出码是什么,PsExec 怎么返回?
- 1.1 标准范式(等待并获取退出码)
- 1.2 不要这样做(`-d` 会让你拿不到退出码)
- 1.3 “程序秒退但实际还在跑”的坑
 
- 2. 标准输出/错误输出是怎么回来的?
- 2.1 回传到本地并保存(本地重定向)
- 2.2 写到远端磁盘(远端重定向)
- 2.3 “本地还是远端?”一眼分辨
 
- 3. 三种常见重定向场景做法
- 场景 A:要**拿退出码**,也要**在本地留日志**
- 场景 B:要**异步跑**(后台),**日志写远端**
- 场景 C:**大输出**的命令(避免卡管道)
 
- 4. 常用选项与退出/输出的关系
- 5. 批量化模板:标准、稳健、可审计
- 5.1 批量执行并收集退出码(本地留痕)
- 5.2 PowerShell 版(拿 `$LASTEXITCODE`)
 
- 6. 进阶细节 & 常见坑
- 7. 一图记忆:选项对“退出/输出”的影响
- 结语
 
 
PsTools 学习笔记(7.4):PsExec —— 远程进程的退出与控制台输出重定向
本篇聚焦两个最常用、也最易踩坑的主题:如何正确拿到远程进程退出码,以及如何把远程程序的标准输出/错误输出按需重定向到本地或远端。把这两点吃透,你的批量自动化稳定性会直线上升。
1. 退出码是什么,PsExec 怎么返回?
-  退出码(Exit Code):进程结束时返回给调用者的整数结果, 0通常代表成功,非 0 代表失败/异常。
-  PsExec 行为:默认情况下,PsExec 会等待远程进程结束,并将远程进程的退出码作为 PsExec 自己的退出码 返回到本地会话。 - 在 cmd中:echo %ERRORLEVEL%
- 在 PowerShell 中:$LASTEXITCODE
 
- 在 
1.1 标准范式(等待并获取退出码)
psexec \\PC-001 -accepteula -nobanner cmd /c "robocopy D:\Src E:\Dst /MIR"
echo 远程退出码=%ERRORLEVEL%
1.2 不要这样做(-d 会让你拿不到退出码)
 
:: -d = 不等待远程进程结束(detached)
psexec \\PC-001 -d cmd /c "do_something.exe"
echo %ERRORLEVEL%   :: 这里只是 PsExec 启动是否成功,不是远程程序的退出码
结论:凡是需要准确拿结果的任务,不要用 -d。
1.3 “程序秒退但实际还在跑”的坑
一些启动器/包装器拉起子进程后立刻退出,导致 PsExec 误以为任务已完成、返回码不等于最终作业的返回码。
 解决:在远端用 start /wait 包住真正的可执行文件。
psexec \\PC-001 cmd /c "start /wait C:\Tools\RealJob.exe /arg1 /arg2"
echo 最终退出码=%ERRORLEVEL%
2. 标准输出/错误输出是怎么回来的?
- 默认:远程进程的 STDOUT/STDERR 通过命名管道回传到本地控制台。
- 本地重定向:你在 PsExec 命令行末尾 写的 > out.txt 2>&1是在本地 shell 生效,输出会落到本地文件。
- 远端重定向:要在远端机器生成日志,必须把重定向写进远端的 cmd /c "..."内部。
2.1 回传到本地并保存(本地重定向)
psexec \\PC-001 -accepteula -nobanner ipconfig /all > ipconfig_PC-001.txt 2>&1
2.2 写到远端磁盘(远端重定向)
psexec \\PC-001 cmd /c "ipconfig /all > C:\Temp\ipconfig.log 2>&1"
远端路径可写即可。也可以写到共享路径(注意凭据与权限):
psexec \\PC-001 cmd /c "ipconfig /all > \\PC-001\C$\Temp\ipconfig.log 2>&1"
2.3 “本地还是远端?”一眼分辨
- 重定向在 PsExec 命令之外(末尾):本地文件
- 重定向放在 引号里的远端 cmd 命令:远端文件
3. 三种常见重定向场景做法
场景 A:要拿退出码,也要在本地留日志
psexec \\PC-001 cmd /c "C:\App\job.exe -q" > logs\PC-001_job.log 2>&1
echo 退出码=%ERRORLEVEL%
场景 B:要异步跑(后台),日志写远端
:: 用 start 把任务丢到远端后台跑,并写自己的日志
psexec \\PC-001 -d cmd /c ^"start /min cmd /c C:\App\job.exe -q >> C:\App\job.log 2>&1"
有意使用
-d:你就是不等这个任务;结果与日志在远端。
场景 C:大输出的命令(避免卡管道)
:: 让远端自己把大量输出写入本地盘,减少管道压力
psexec \\PC-001 cmd /c ^"powershell -NoP -C Get-ChildItem -Recurse C:\ > C:\scan.txt 2>&1"
4. 常用选项与退出/输出的关系
| 选项 | 作用 | 与退出/输出的关系 | |
|---|---|---|---|
| -d | 不等待远程进程结束 | 拿不到远程程序退出码;输出也来不及回传 | |
| -i [session] | 交互到远端指定会话 | 控制台输出到该会话窗口;脚本化不建议用 | |
| -h | 以高完整性令牌运行(需管理员) | 提升失败可能拿到“伪成功”(PsExec 成功、任务内部失败) | |
| -s | 以 SYSTEM运行 | 有助于写受限路径;注意访问共享时 SYSTEM 无网络凭据 | |
| -u/-p | 使用备用凭据 | 保障 Admin$ / 访问共享时权限正确 | |
| -w | 指定远端工作目录 | 很多应用依赖工作目录才能正确产生日志/退出码 | |
| `-c [-f | -v]` | 将本地程序复制到远端再执行 | 保证二进制一致;输出规则不变 | 
5. 批量化模板:标准、稳健、可审计
5.1 批量执行并收集退出码(本地留痕)
@echo off
setlocal enabledelayedexpansion
set HOSTS=PC-001 PC-002 PC-003
if not exist logs md logsfor %%H in (%HOSTS%) do (echo [%%H] Running ...psexec \\%%H -nobanner -accepteula ^cmd /c "C:\Tools\App.exe /run" > "logs\%%H.out" 2>&1set "rc=!ERRORLEVEL!"echo [%%H] ExitCode=!rc! >> logs\summary.csv
)
echo 完成,见 logs\summary.csv
5.2 PowerShell 版(拿 $LASTEXITCODE)
 
$hosts = 'PC-001','PC-002','PC-003'
New-Item -ItemType Directory -Force -Path logs | Out-Null
$sum   = @()foreach($h in $hosts){Write-Host "[$h] Running..."& psexec \\$h -nobanner -accepteula cmd /c "C:\Tools\App.exe /run" `*> "logs\$h.out"$sum += [pscustomobject]@{ Host=$h; ExitCode=$LASTEXITCODE }
}
$sum | Export-Csv logs\summary.csv -NoTypeInformation -Encoding UTF8
6. 进阶细节 & 常见坑
- 编码问题:回传输出在简体中文系统常是 OEM 936。若要在日志中统一 UTF-8,可在远端用 PowerShell 重定向:
 powershell -NoP -C 'your-cmd' | Out-File C:\log.txt -Encoding utf8
- stderr 合流:务必加上 2>&1,否则很多错误只在本地屏幕显示,日志里没有。
- 权限导致“成功假象”:PsExec 本身成功连接,但程序内部因权限不足立刻退出,退出码非 0。要看 ERRORLEVEL,不要只看 PsExec 有没有抛红。
- 写入共享:远端以 SYSTEM身份写 UNC 共享通常会失败(没有网络凭据)。要么用-u/-p指定有权限的帐户,要么写本地盘后再拉回。
- 输出过大导致卡顿:几百 MB 的文本经管道回传容易卡死。建议 远端落地 再异步回传。
7. 一图记忆:选项对“退出/输出”的影响
- 拿退出码:不要 -d;必要时start /wait。
- 回传输出到本地:重定向写在 PsExec 命令末尾。
- 远端日志:重定向写在 远端的 cmd /c "..."里。
- 需要权限:-h(管理员令牌)、-s(SYSTEM)、-u/-p(备用凭据)。
- 需要上下文:-w指定工作目录,避免相对路径踩坑。
结语
到这里,你已经掌握了 “等/不等、取/不取退出码、日志落哪儿” 的全部关键点。
 下一篇我们继续深入 7.5《PsExec 的备用凭据与安全基线》,聊聊怎么既稳又安全地在企业内大规模投送命令与程序。
