Welcome PowerShell User! This recipe is just one of the hundreds of useful resources contained in the PowerShell Cookbook.

If you own the book already, login here to get free, online, searchable access to the entire book's content.

If not, the Windows PowerShell Cookbook is available at Amazon, or any of your other favourite book retailers. If you want to see what the PowerShell Cookbook has to offer, enjoy this free 90 page e-book sample: "The Windows PowerShell Interactive Shell".

15.6 Handle Warnings, Errors, and Terminating Errors

Problem

You want to handle warnings, errors, and terminating errors generated by scripts or other tools that you call.

Solution

To control how your script responds to warning messages, set the $warningPreference variable. In this example, to ignore them:

$warningPreference = "SilentlyContinue"

To control how your script responds to nonterminating errors, set the $errorActionPreference variable. In this example, to ignore them:

$errorActionPreference = "SilentlyContinue"

To control how your script responds to terminating errors, you can use either the try/catch/finally statements or the trap statement. In this example, we output a message and continue with the script:

try
{
    1 / $null
}
catch [DivideByZeroException]
{
    "Don't divide by zero: $_"
}
finally
{
    "Script that will be executed even if errors occur in the try statement"
}

Use the trap statement if you want its error handling to apply to the entire scope:

trap [DivideByZeroException] { "Don't divide by zero!"; continue }
1 / $null

Discussion

PowerShell defines several preference variables that help you control how your script reacts to warnings, errors, and terminating errors. As an example of these error management techniques, consider the following script.

##############################################################################
##
## Get-WarningsAndErrors
##
## From PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################

<#

.SYNOPSIS

Demonstrates the functionality of the Write-Warning, Write-Error, and throw
statements

#>

Set-StrictMode -Version 3

Write-Warning "Warning: About to generate an error"
Write-Error "Error: You are running this script"
throw "Could not complete operation."

For more information about running scripts, see Recipe 1.2.

You can now see how a script might manage those separate types of errors:

PS > $warningPreference = "Continue"
PS > Get-WarningsAndErrors
WARNING: Warning: About to generate an error
Exception: C:\scripts\Get-WarningsAndErrors.ps1:23
Line |
  23 |  throw "Could not complete operation."
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Could not complete operation.

Once you modify the warning preference, the original warning message gets suppressed. A value of SilentlyContinue is useful when you’re expecting an error of some sort.

PS > $warningPreference = "SilentlyContinue"
PS > Get-WarningsAndErrors
Write-Error: Error: You are running this script
Exception: C:\scripts\Get-WarningsAndErrors.ps1:23
Line |
  23 |  throw "Could not complete operation."
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Could not complete operation.

When you modify the error preference, you suppress errors and exceptions as well:

PS > $errorActionPreference = "SilentlyContinue"
PS > Get-WarningsAndErrors
PS >

In addition to the $errorActionPreference variable, all cmdlets let you specify your preference during an individual call. With an error action preference of SilentlyContinue, PowerShell doesn’t display or react to errors. It does, however, still add the error to the $error collection for futher processing. If you want to suppress even that, use an error action preference of Ignore.

PS > $errorActionPreference = "Continue"
PS > Get-ChildItem IDoNotExist
Get-ChildItem : Cannot find path '...\IDoNotExist' because it does not exist.
At line:1 char:14
+ Get-ChildItem  <<<< IDoNotExist
PS > Get-ChildItem IDoNotExist -ErrorAction SilentlyContinue
PS >

If you reset the error preference back to Continue, you can see the impact of a try/catch/finally statement. The message from the Write-Error call makes it through, but the exception does not:

PS > $errorActionPreference = "Continue"
PS > try { Get-WarningsAndErrors } catch { "Caught an error" }
WARNING: Warning: About to generate an error
Get-WarningsAndErrors: Error: You are running this script
Caught an error

The try/catch/finally statement acts like the similar statement in other programming languages. First, it executes the code inside of its script block. If it encounters a terminating error, it executes the code inside of the catch script block. It executes the code in the finally statement no matter what—an especially useful feature for cleanup or error-recovery code.

A similar technique is the trap statement:

PS > $errorActionPreference = "Continue"
PS > trap { "Caught an error"; continue }; Get-WarningsAndErrors
WARNING: Warning: About to generate an error
Get-WarningsAndErrors: Error: You are running this script
Caught an error

Within a catch block or trap statement, the $_ (or $PSItem) variable represents the current exception or error being processed.

Unlike the try statement, the trap statement handles terminating errors for anything in the scope that defines it. For more information about scopes, see Recipe 3.6.

Note

After handling an error, you can also remove it from the system’s error collection by typing $error.RemoveAt(0).

For more information about PowerShell’s automatic variables, type Get-Help about_automatic_variables. For more information about error management in PowerShell, see “Managing Errors”. For more detailed information about the valid settings of these preference variables, see Appendix A.

See Also

Recipe 1.2, “Run Programs, Scripts, and Existing Tools”

Recipe 3.6, “Control Access and Scope of Variables and Other Items”

“Managing Errors”

Appendix A, PowerShell Language and Environment