The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Write a non-terminating errorWrite-Error 'The record is invalid'View examples
Make a command error terminatingGet-Item -LiteralPath $Path -ErrorAction StopView examples
Hide a command errorGet-Item -LiteralPath $Path -ErrorAction ` SilentlyContinueView examples
Catch a failurecatch { Write-Warning $_.Exception.Message }View examples
Catch one exception typecatch [System.IO.FileNotFoundException] { Write-Warning ` 'Missing file' }View examples
Order specific handlers firstcatch [System.UnauthorizedAccessException] { ` Write-Warning 'Access denied' }View examples
Inspect the caught error$_.Exception.MessageView examples
Inspect the category$_.CategoryInfo.CategoryView examples
Read the newest error$Error[0]View examples
Capture command errorsGet-Item missing.txt -ErrorVariable lookupErrors ` -ErrorAction SilentlyContinueView examples
Always run cleanupfinally { $stream.Dispose() }View examples
Raise a terminating errorthrow 'Configuration is invalid'View examples
Re-throw the current errorthrowView examples
Set a scoped default action$ErrorActionPreference = 'Stop'View examples
Write a warningWrite-Warning 'Using fallback configuration'View examples
Read a native exit codeif ($LASTEXITCODE -ne 0) { throw ` "Tool failed: $LASTEXITCODE" }View examples
Inspect command successif (-not $?) { Write-Warning 'The last operation failed' ` }View examples

Reliable PowerShell distinguishes non-terminating command errors, terminating exceptions, and native executable exit codes. Convert only the errors you intend to catch, inspect the ErrorRecord rather than parsing display text, and keep cleanup independent from success or failure.

Step by step

Detailed examples

01

Know which errors stop execution

Cmdlets often report recoverable problems as non-terminating errors and continue processing remaining input. try/catch handles terminating errors, so apply -ErrorAction Stop to the specific command whose failure must transfer control. Avoid broad suppression: SilentlyContinue hides presentation but can still populate $Error, while Ignore also avoids adding the error to the error stream for that invocation.

Promote one lookup failure into catch
$Path = 'C:\missing\settings.json'
try {
    Get-Item -LiteralPath $Path -ErrorAction Stop
    'Loaded'
}
catch {
    Write-Warning "Cannot read $Path"
}
Output
WARNING: Cannot read C:\missing\settings.json
Capture a suppressed lookup error
Get-Item -LiteralPath 'missing.txt' `
    -ErrorAction SilentlyContinue `
    -ErrorVariable lookupErrors
$lookupErrors[0].CategoryInfo.Category
Output
ObjectNotFound
Back to quick reference ↑
02

Catch the narrowest useful exception

catch receives a terminating error as $_, an ErrorRecord. Typed handlers match the exception or its derived types and should precede an untyped fallback. The effective exception can be wrapped by a cmdlet, so verify the real type from an observed ErrorRecord before relying on a narrow handler. Keep the try block small so it does not catch unrelated failures accidentally.

Handle access and missing-path failures separately
try {
    [IO.File]::ReadAllText($Path)
}
catch [System.IO.FileNotFoundException] {
    Write-Warning 'The configuration file is missing.'
}
catch [System.UnauthorizedAccessException] {
    Write-Warning 'The configuration file is not readable.'
}
catch {
    Write-Error -ErrorRecord $_
}
Output
# Exactly one matching handler runs for a terminating exception.
Back to quick reference ↑
03

Use structured ErrorRecord data

Inside catch, $_ contains the current ErrorRecord, including Exception, CategoryInfo, FullyQualifiedErrorId, InvocationInfo, and ScriptStackTrace. These fields are more stable and useful than formatted console text. $Error is newest-first session history and can contain unrelated records, so prefer the catch variable or -ErrorVariable when associating an error with one operation.

Create a compact diagnostic object
try {
    Get-Item -LiteralPath 'missing.txt' -ErrorAction Stop
}
catch {
    [pscustomobject]@{
        Message = $_.Exception.Message
        Category = $_.CategoryInfo.Category
        ErrorId = $_.FullyQualifiedErrorId
        Target = $_.TargetObject
    }
}
Output
Message  : Cannot find path 'missing.txt' because it does not exist.
Category : ObjectNotFound
ErrorId  : PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand
Target   : missing.txt
Back to quick reference ↑
04

Release resources on every exit path

finally runs whether try succeeds, a catch handles an error, or control leaves the block. It is suitable for cleanup that must happen unconditionally, but it should not return or throw casually because that can hide the original result. Initialize the resource before try and guard cleanup when acquisition itself can fail.

Dispose a stream with finally
$stream = $null
try {
    $stream = [IO.File]::OpenRead($Path)
    $stream.Length
}
finally {
    if ($null -ne $stream) { $stream.Dispose() }
}
Output
# The stream is disposed even when reading its length fails.
Back to quick reference ↑
05

Throw only when the operation cannot fulfill its contract

throw creates a terminating error, so use it for invalid state or input that prevents the function from producing its promised result. A bare throw within catch rethrows the current failure and retains its context. When adding context, preserve the original ErrorRecord in logging or exception data rather than replacing every failure with an untraceable generic message.

Validate input and rethrow unexpected failures
function Get-RequiredSetting {
    param([hashtable]$Settings, [string]$Name)
    if (-not $Settings.ContainsKey($Name)) {
        throw "Required setting is missing: $Name"
    }
    $Settings[$Name]
}

try {
    Get-RequiredSetting -Settings @{} -Name 'Region'
}
catch {
    Write-Warning $_.Exception.Message
    throw
}
Output
WARNING: Required setting is missing: Region
# The original terminating error continues to the caller.
Back to quick reference ↑
06

Set preferences narrowly and choose the right stream

$ErrorActionPreference supplies a default for PowerShell's error stream, but a command's -ErrorAction value takes precedence. Change preferences inside the smallest practical scope and restore them when necessary. Use warnings for recoverable concerns, verbose output for opt-in operational detail, and errors for failed operations so callers can reason about behavior correctly.

Apply a temporary preference
& {
    $ErrorActionPreference = 'Stop'
    try {
        Get-Content -LiteralPath $Path
    }
    catch {
        Write-Warning $_.Exception.Message
    }
}
Write-Verbose 'The outer preference was not changed.'
Output
# The preference assignment is limited to the child scope.
Back to quick reference ↑
07

Check native programs by exit code

External programs communicate success primarily through process exit codes, exposed as $LASTEXITCODE. PowerShell's $? reports whether the immediately preceding pipeline succeeded and can be overwritten by the next command, so capture or test it immediately. Do not assume a particular nonzero value's meaning without the program's documentation.

Capture native status immediately
git diff --quiet
$lastPipelineSucceeded = $?
$gitExitCode = $LASTEXITCODE

if ($gitExitCode -gt 1) {
    throw "git diff failed (exit $gitExitCode)"
}
if ($gitExitCode -eq 1) {
    Write-Warning 'The working tree has changes.'
}
Output
# git diff --quiet uses 0 for no differences, 1 for differences, and values above 1 for errors.
Back to quick reference ↑

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. Microsoft Learnabout_Try_Catch_Finallylearn.microsoft.com
  2. Microsoft Learnabout_Error_Handlinglearn.microsoft.com
  3. Microsoft Learnabout_CommonParameterslearn.microsoft.com
  4. Microsoft Learnabout_Preference_Variableslearn.microsoft.com
  5. Microsoft Learnabout_Automatic_Variableslearn.microsoft.com

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback