How to capture error output only in a variable in PowerShell
Asked Answered
N

4

30

I want to store the stderr output of a PowerShell command in a variable. I don't want to store it in a file and I don't want standard output included, just the error output.

This redirects to a file named error.txt:

& $command $params 2> error.txt

This redirects both stderr and stdout to the $output variable:

$output = & $command $params 2>&1

But I want to store only the error output in a variable (the same as the content of the error.txt file above), without writing anything to file. How do I do that?

Nightstick answered 9/1, 2015 at 13:1 Comment(2)
#24222588Zak
@NoRefundsNoReturns I was looking to store only the error output, not the whole output.Nightstick
M
35

You can call the command a slightly different way and use the -ErrorVariable parameter in PowerShell:

Invoke-Expression "$command $params" -ErrorVariable badoutput

$badoutput will now contain the contents of the error string.

Maremma answered 9/1, 2015 at 13:13 Comment(2)
And, at least with the most recent version of Powershell, you can capture both stdout and stderr to separate variables and then suppress all output so that you can fully control what happens with the output with: Invoke-Expression "somecommand.exe" -ErrorVariable errOut -OutVariable succOut 2>&1 >$nullGnaw
@ZameerFouzan 1 is stdout, 2 is stderr, and 2>&1 combines stderr into stdout. Then >$null discards stdoutSnappish
S
20

Here is simpler solution by Simon Wahlin using sub expressions

$output = & $command $params 2>&1

Would be:

$errOutput = $( $output = & $command $params ) 2>&1
Selfness answered 29/3, 2021 at 20:34 Comment(0)
S
1

To add to arco444, the specific exception can be obtained by using $badoutput[0].Exception.

-ErrorAction and -ErrorVariable has more information on to effectively use the ErrorAction and ErrorVariable parameters built into PowerShell.

Here is the easiest way to show this working:

PS> Stop-Process 13,23
Stop-Process : Cannot find a process with the process identifier 13.
At line:1 char:13
+ Stop-Process  <<<< 13,23
Stop-Process : Cannot find a process with the process identifier 23.
At line:1 char:13
+ Stop-Process  <<<< 13,23

PS> Stop-Process 13,23 -ErrorAction Stop  # Only 1 error
Stop-Process : Command execution stopped because the shell variable “ErrorA
ctionPreference” is set to Stop: Cannot find a process with the process ide
ntifier 13.
At line:1 char:13
+ Stop-Process  <<<< 13,23 -ErrorAction Stop  # Only 1 error

PS> Stop-Process 13,23 -ErrorAction silentlycontinue  # No errors

PS> Stop-Process 13,23 -ErrorAction inquire  # ASK
Confirm
Cannot find a process with the process identifier 13.
[Y] Yes  [A] Yes to All  [H] Halt Command  [S] Suspend  [?] Help
(default is “Y”):h
Stop-Process : Command execution stopped because the user selected the Halt
 option.
At line:1 char:13
+ Stop-Process  <<<< 13,23 -ErrorAction inquire  # ASK
PS>
PS>
PS> Stop-Process 13,23 -ErrorVariable a -ErrorAction SilentlyContinue

PS> $a[0]
Stop-Process : Cannot find a process with the process identifier 13.
At line:1 char:13
+ Stop-Process  <<<< 13,23 -ErrorVariable a -ErrorAction SilentlyContinue

PS> $a[0] |fl * -Force

Exception             : Microsoft.PowerShell.Commands.ProcessCommandExcepti
                        on: Cannot find a process with the process identifi
                        er 13.
TargetObject          : 13
CategoryInfo          : ObjectNotFound: (13:Int32) [Stop-Process], ProcessC
                        ommandException
FullyQualifiedErrorId : NoProcessFoundForGivenId,Microsoft.PowerShell.Comma
                        nds.StopProcessCommand
ErrorDetails          :
InvocationInfo        : System.Management.Automation.InvocationInfo

PS> $a |ft TargetObject -force -auto
TargetObject
————
          13
          23

Now one thing that is not obvious to people is that you can specify a “+” in front of the variable name for ErrorVariable and we will ADD the errors to that variable.

PS> $err=@()
PS> stop-process 13 -ea silentlycontinue -ErrorVariable err
PS> $err.count
1

PS> stop-process 23 -ea silentlycontinue -ErrorVariable +err
PS> $err.count
2
PS> $err
Stop-Process : Cannot find a process with the process identifier 13.
At line:1 char:13
+ stop-process  <<<< 13 -ea silentlycontinue -ErrorVariable err
Stop-Process : Cannot find a process with the process identifier 23.
At line:1 char:13
+ stop-process  <<<< 23 -ea silentlycontinue -ErrorVariable +err

Lastly, you don’t need to type out –ErrorAction or –ErrorVariable, we have defined parameter aliases for these so you can just type –EA and -EV.

Sorel answered 20/7, 2016 at 23:35 Comment(0)
S
0

In case you still not sure how stdout and stderr works with PowerShell on Linux, see the following outputs:

Linux + PowerShell 7.2.16, PowerShell 7.3.2

PS> $s={ 
  /bin/echo "Hello"
  /bin/ls "/errortext"
  Write-Error "Booo"
  Write-Host "Bello"
  Write-Output "World"
  Write-Output "StdOut" > /dev/stdout
  Write-Output "StdErr" > /dev/stderr 
}
PS> $err456 = (Invoke-Command -ScriptBlock $s `
  -OutVariable out123 `
  -ErrorVariable err123 `
  1>$null ) 2>&1
Bello
StdOut
StdErr
PS> $out123
Hello
World
PS> $err123

Write-Error: Booo
PS> $err456
/bin/ls: cannot access '/errortext': No such file or directory
Write-Error: Booo

Also, the documentation was improved over the years:

Senskell answered 1/11, 2023 at 0:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.