Capturing standard out and error with Start-Process Capturing standard out and error with Start-Process powershell powershell

Capturing standard out and error with Start-Process


That's how Start-Process was designed for some reason. Here's a way to get it without sending to file:

$pinfo = New-Object System.Diagnostics.ProcessStartInfo$pinfo.FileName = "ping.exe"$pinfo.RedirectStandardError = $true$pinfo.RedirectStandardOutput = $true$pinfo.UseShellExecute = $false$pinfo.Arguments = "localhost"$p = New-Object System.Diagnostics.Process$p.StartInfo = $pinfo$p.Start() | Out-Null$p.WaitForExit()$stdout = $p.StandardOutput.ReadToEnd()$stderr = $p.StandardError.ReadToEnd()Write-Host "stdout: $stdout"Write-Host "stderr: $stderr"Write-Host "exit code: " + $p.ExitCode


In the code given in the question, I think that reading the ExitCode property of the initiation variable should work.

$process = Start-Process -FilePath ping -ArgumentList localhost -NoNewWindow -PassThru -Wait$process.ExitCode

Note that (as in your example) you need to add the -PassThru and -Wait parameters (this caught me out for a while).


I also had this issue and ended up using Andy's code to create a function to clean things up when multiple commands need to be run.

It'll return stderr, stdout, and exit codes as objects. One thing to note: the function won't accept .\ in the path; full paths must be used.

Function Execute-Command ($commandTitle, $commandPath, $commandArguments){    $pinfo = New-Object System.Diagnostics.ProcessStartInfo    $pinfo.FileName = $commandPath    $pinfo.RedirectStandardError = $true    $pinfo.RedirectStandardOutput = $true    $pinfo.UseShellExecute = $false    $pinfo.Arguments = $commandArguments    $p = New-Object System.Diagnostics.Process    $p.StartInfo = $pinfo    $p.Start() | Out-Null    $p.WaitForExit()    [pscustomobject]@{        commandTitle = $commandTitle        stdout = $p.StandardOutput.ReadToEnd()        stderr = $p.StandardError.ReadToEnd()        ExitCode = $p.ExitCode    }}

Here's how to use it:

$DisableACMonitorTimeOut = Execute-Command -commandTitle "Disable Monitor Timeout" -commandPath "C:\Windows\System32\powercfg.exe" -commandArguments " -x monitor-timeout-ac 0"