I want my PowerShell script to stop when any of the commands I run fail (like set -e in bash). I'm using both Powershell commands (New-Object System.Net.WebClient) and programs (.\setup.exe).


$ErrorActionPreference = "Stop" will get you part of the way there (i.e. this works great for cmdlets).

However for EXEs you're going to need to check $LastExitCode yourself after every exe invocation and determine whether that failed or not. Unfortunately I don't think PowerShell can help here because on Windows, EXEs aren't terribly consistent on what constitutes a "success" or "failure" exit code. Most follow the UNIX standard of 0 indicating success but not all do. Check out the CheckLastExitCode function in this blog post. You might find it useful.

  • 2
    Does $ErrorActionPreference = "Stop" work for well-behaved programs (that return 0 on success)? – Andres Riofrio Mar 30 '12 at 20:56
  • 13
    No, it doesn't work at all for EXEs. It only works for PowerShell cmdlets which run in-process. It is kind of pain but you have to check $LastExitCode after every EXE invocation, check that against the expected exit code and if that test indicates failure, you have to throw to terminate execution of the script e.g. throw "$exe failed with exit code $LastExitCode" where $exe is just the path to the EXE. – Keith Hill Mar 30 '12 at 21:18
  • 2
    Accepted because it includes info on how to make it work with external programs. – Andres Riofrio Apr 22 '12 at 22:23
  • 4
    I put in a feature request about it here: connect.microsoft.com/PowerShell/feedback/details/751703/… – Helephant Jun 29 '12 at 14:12
  • 4
    note that psake has a commandlet called "exec" which can you can use to wrap calls to external programs with a check for LastExitCode and display an error (and stop, if desired) – enorl76 Nov 28 '12 at 20:01

You should be able to accomplish this by using the statement $ErrorActionPreference = "Stop" at the beginning of your scripts.

The default setting of $ErrorActionPreference is Continue, which is why you are seeing your scripts keep going after errors occur.

  • 17
    This does not affect programs, only cmdlets. – Joey Mar 30 '12 at 19:23

Sadly, due to buggy cmdlets like New-RegKey and Clear-Disk, none of these answers are enough. I've currently settled on the following lines at the top of any powershell script to maintain my sanity.

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

and then any native call gets this treatment:

$native_call_success = $?
if (-not $native_call_success)
    throw 'error making native call'

That native call pattern is slowly becoming common enough for me that I should probably look into options for making it more concise. I'm still a powershell newbie, so suggestions are welcome.


You need slightly different error handling for powershell functions and for calling exe's, and you need to be sure to tell the caller of your script that it has failed. Building on top of Exec from the library Psake, a script that has the structure below will stop on all errors, and is usable as a base template for most scripts.

Set-StrictMode -Version latest
$ErrorActionPreference = "Stop"

# Taken from psake https://github.com/psake/psake
  This is a helper function that runs a scriptblock and checks the PS variable $lastexitcode
  to see if an error occcured. If an error is detected then an exception is thrown.
  This function allows you to run command-line programs without having to
  explicitly check the $lastexitcode variable.
  exec { svn info $repository_trunk } "Error executing SVN. Please verify SVN command-line client is installed"
function Exec
        [Parameter(Position=1,Mandatory=0)][string]$errorMessage = ("Error executing command {0}" -f $cmd)
    & $cmd
    if ($lastexitcode -ne 0) {
        throw ("Exec: " + $errorMessage)

Try {

    # Put all your stuff inside here!

    # powershell functions called as normal and try..catch reports errors 
    New-Object System.Net.WebClient

    # call exe's and check their exit code using Exec
    Exec { setup.exe }

} Catch {
    # tell the caller it has all gone wrong

A slight modification to the answer from @alastairtree:

function Invoke-Call {
    param (
        [string]$ErrorAction = $ErrorActionPreference
    & @ScriptBlock
    if (($lastexitcode -ne 0) -and $ErrorAction -eq "Stop") {
        exit $lastexitcode

Invoke-Call -ScriptBlock { dotnet build . } -ErrorAction Stop

The key differences here are:

  1. it uses the Verb-Noun (mimicing Invoke-Command)
  2. implies that it uses the call operator under the covers
  3. mimics -ErrorAction behavior from built in cmdlets
  4. exits with same exit code rather than throwing exception with new message
  • 1
    The exit $lastexitcode; helped me a lot! Thanks. – Bruno Bieri Feb 6 at 6:53
  • 1
    How do you pass parameters / variables? e.g. Invoke-Call { dotnet build $something } – Michael Blake May 24 at 8:42
  • 1
    @MichaelBlake the inquiry of yours is so right, allowing a params passthrough would make this approach gold. I am inspecting adamtheautomator.com/pass-hashtables-invoke-command-argument to adjust the Invoke-Call to support params pass-through. If I succeed, I will post it as another answer here. – Maxim V. Pavlov Sep 7 at 17:35

I came here looking for the same thing. $ErrorActionPreference="Stop" kills my shell immediately when I'd rather see the error message (pause) before it terminates. Falling back on my batch sensibilities:


I found that this works pretty much the same for my particular ps1 script:

Import-PSSession $Session
If ($? -ne "True") {Pause; Exit}

I'm new to powershell but this seems to be most effective:

doSomething -arg myArg
if (-not $?) {throw "Failed to doSomething"}

Your Answer

