How can I make Powershell behave like Bash with its flag set -e? set -o errexit makes a Bash script “Exit immediately if a simple command exits with a non-zero status”.
I thought I could do this by setting $ErrorActionPreference="Stop" but this doesn’t seem to work. Suppose I have a script a.ps1
$ErrorActionPreference="Stop"
& cmd /c "exit 1"
echo "cmd exited `$LastExitCode=$LastExitCode and `$?=$?"
If I run it
.\a. ; echo "a.ps1 exited `$LastExitCode=$LastExitCode `$?=$?"
To my surprises it prints
cmd exited $LastExitCode=1 and $?=False
a.ps1 exited $LastExitCode=1 $?=True
What’s going on?! I expected a.ps1 to exit after the first line, throwing an error and setting $? to False.
Is there any official documentation explaining $ErrorActionPreference? All I found was this post on a blog about coffee.
$ErrorActionPreferenceworks as intended, it’s just that exit codes from native programs are not nearly as well-behaved as PowerShell cmdlets.For a
cmdletthe error condition is fairly easy to determine: Did an exception happen or not? So the following would not reach theWrite-Hoststatement with$ErrorActionPreferenceset toStop:or
For native programs an exit code of zero usually signals that no error occurred but that’s merely a convention, as is a non-zero exit code signalling an error. Would you say that if
choiceexists with an exit code of 1 that it was an error?The only robust way to handle this is to check the exit code after running a native command and handling it yourself, if needed. PowerShell doesn’t try to guess what the result meant because the conventions aren’t strong enough to warrant a default behaviour in this case.
You can use a function if you want to make your life easier:
But in general many programs need different handling because they don’t adhere to said convention.