Stop a script when an error occurs in PowerShell

 
 
  • Gérald Barré

By default, PowerShell doesn't stop the script when an error occurs. Instead, it writes the error to the error stream and continues executing the script. You can change this behavior by setting the $ErrorActionPreference variable to Stop. When you do this, PowerShell stops the script when an error occurs.

PowerShell has two different kinds of commands: cmdlets and native commands. For example, Get-ChildItem is a cmdlet, and git is a native command. Since the first version of PowerShell, the $ErrorActionPreference variable has controlled the behavior of cmdlets. In PowerShell 7.3, the $PSNativeCommandUseErrorActionPreference variable was introduced to control the behavior of native commands.

When you set $ErrorActionPreference to Stop, PowerShell stops the script when a cmdlet throws an error. When you set $PSNativeCommandUseErrorActionPreference to true, PowerShell also stops the script when a native command throws an error. I think a good practice is to set both variables at the beginning of your scripts:

PowerShell
# Stop the script when a cmdlet or a native command fails
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true

You can override the behavior of $ErrorActionPreference per cmdlet by using the -ErrorAction parameter. For instance, the following command doesn't stop the script when Get-ChildItem fails:

PowerShell
Get-ChildItem dummy -ErrorAction SilentlyContinue

To bypass the behavior of $PSNativeCommandUseErrorActionPreference for a specific native command, you can use the & { } syntax to run the command inside a script block. Inside the script block, you can change the value of $PSNativeCommandUseErrorActionPreference to false. When the script block exits, the variable reverts to its previous value.

PowerShell
& {
    # Disable $PSNativeCommandUseErrorActionPreference for this scriptblock only
    $PSNativeCommandUseErrorActionPreference = $false
    robocopy.exe dummy1 dummy2
    if ($LASTEXITCODE -gt 8) {
        throw "robocopy failed with exit code $LASTEXITCODE"
    }
}

#Additional resources

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?Buy Me A Coffee💖 Sponsor on GitHub