Carl Patenaude Poulin
Carl Patenaude Poulin

Reputation: 6570

PowerShell: fatal errors don't get sent to STDERR, how to log them?

I have a PowerShell script on my desktop:

Write-Output "Some output"
Write-Error "Non-fatal error"
$ErrorActionPreference = "Stop" # Any further errors should be treated as fatal
Write-Output "Some more output"
Write-Error "Fatal error"

I call it this way from powershell.exe:

PS C:\Users\me\Desktop> .\test.ps1 2> err.txt 1> out.txt

Output:

C:\Users\vmadmin\Desktop\test.ps1 : Fatal error
At line:1 char:1
+ .\test.ps1 2> err.txt 1> out.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,test.ps1

out.txt:

Some output
Some more output

err.txt:

C:\Users\vmadmin\Desktop\test.ps1 : Non-fatal error
At line:1 char:1
+ .\test.ps1 2> err.txt 1> out.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,test.ps1

I would like the fatal error to get logged to err.txt. How can I accomplish that?

Upvotes: 1

Views: 1009

Answers (1)

Carl Patenaude Poulin
Carl Patenaude Poulin

Reputation: 6570

PowerShell has two different channels for error-handling: the first is STDERR, to which non-fatal errors get written. The second is an exception mechanism, similar to what you would see in programming languages like C# or Java.

Here's the trick: any error is in either one channel or the other, never both. This means that fatal errors do not go through STDERR!

Here's a workaround: wrap your PowerShell calls in a cmd call. Since the cmd language does not have exceptions, any PowerShell exceptions that go through it get piped into STDERR.

Example usage:

PS C:\Users\me\Desktop> cmd.exe /c "powershell.exe .\test.ps1" 2> err.txt 1> out.txt

Upvotes: 1

Related Questions