如何在PowerShell脚本中调用exe并将输出写入同一份日志文件
嘿,这个需求我经常碰到,给你分享几种实用的实现方式,都能把你的exe输出和脚本里的其他内容统一写到同一份日志里~
方法1:全局重定向所有输出(最简单)
这种方式不用改太多脚本,直接通过执行时的重定向,把脚本里所有内容(包括exe的输出、脚本自身的日志)一股脑写入日志文件,适合快速实现。
比如你的脚本RunMyExe.ps1内容:
# 脚本自身的日志内容 Write-Output "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] 开始执行脚本..." # 运行你的exe程序,替换成实际路径和参数 & "C:\Tools\MySmallProgram.exe" "input.txt" "output.txt" # 脚本后续的日志内容 Write-Output "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] EXE执行完成,继续处理后续逻辑..."
然后执行脚本的时候,用以下命令把所有输出追加到日志:
.\RunMyExe.ps1 *>> "C:\Logs\MyScriptLog.log" -Encoding UTF8
*>>表示把所有输出流(标准输出、错误输出)追加到日志文件;如果想覆盖旧日志,换成*>即可。-Encoding UTF8是为了避免日志出现乱码,尤其是你的exe输出包含中文或特殊字符时。
方法2:捕获EXE输出后手动处理(更灵活)
如果你想给EXE的输出加前缀(比如时间戳、标记),或者过滤某些内容,就可以先捕获EXE的输出,再和脚本日志一起写入文件。
示例脚本:
# 定义日志路径和EXE路径 $logFile = "C:\Logs\MyScriptLog.log" $myExe = "C:\Tools\MySmallProgram.exe" # 先写入脚本启动日志 $currentTime = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' "[$currentTime] 脚本启动,准备运行EXE..." | Out-File -FilePath $logFile -Append -Encoding UTF8 # 捕获EXE的所有输出(包括错误信息) # 2>&1 是把错误输出重定向到标准输出,这样能一起捕获 $exeOutput = & $myExe "参数1" "参数2" 2>&1 # 遍历EXE的每一行输出,加上时间戳后写入日志 foreach ($line in $exeOutput) { "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] EXE输出: $line" | Out-File -FilePath $logFile -Append -Encoding UTF8 } # 写入脚本完成日志 $currentTime = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' "[$currentTime] EXE执行完毕,脚本结束..." | Out-File -FilePath $logFile -Append -Encoding UTF8
这种方式的好处是可以对EXE输出做自定义处理,比如过滤掉无关的调试信息,或者给错误输出做特殊标记区分。
方法3:用Start-Process精细控制EXE运行
如果你的EXE需要特殊运行条件(比如以管理员权限启动、隐藏窗口),可以用Start-Process命令来启动EXE,同时捕获它的输出。
示例脚本:
$logFile = "C:\Logs\MyScriptLog.log" $myExe = "C:\Tools\MySmallProgram.exe" # 临时文件用来存EXE的输出,之后再写入日志 $tempStdout = "C:\Temp\ExeStdOut.txt" $tempStderr = "C:\Temp\ExeStdErr.txt" # 写入脚本启动日志 "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] 脚本启动,准备启动EXE..." | Out-File -FilePath $logFile -Append -Encoding UTF8 # 启动EXE,等待它执行完成,同时重定向输出到临时文件 Start-Process -FilePath $myExe ` -ArgumentList "参数1", "参数2" ` -NoNewWindow ` # 不在新窗口运行 -Wait ` # 等待EXE执行完再继续脚本 -RedirectStandardOutput $tempStdout ` -RedirectStandardError $tempStderr # 把临时文件里的EXE输出写入日志 Get-Content $tempStdout | ForEach-Object { "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] EXE标准输出: $_" | Out-File -FilePath $logFile -Append -Encoding UTF8 } Get-Content $tempStderr | ForEach-Object { "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] EXE错误输出: $_" | Out-File -FilePath $logFile -Append -Encoding UTF8 } # 清理临时文件 Remove-Item $tempStdout, $tempStderr -Force # 写入脚本完成日志 "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] EXE执行完毕,脚本结束..." | Out-File -FilePath $logFile -Append -Encoding UTF8
这种方式适合复杂场景,比如需要指定EXE的工作目录、环境变量,或者以不同用户身份运行时,Start-Process能提供更多参数来控制。
几个小提醒
- 如果你的EXE是GUI程序(没有控制台窗口),方法1和2可能捕获不到输出,这时候方法3的重定向是更可靠的选择。
- 确保脚本有日志文件所在目录的写入权限,不然会报错。
- 加时间戳是个好习惯,能让日志更容易排查问题,建议所有日志行都带上时间。
内容的提问来源于stack exchange,提问作者Tomasz M
相关产品推荐
相关产品推荐

