The essentials
Quick reference
One focused task per row. Jump to the related section for complete, working examples.
| Use | Syntax | Examples |
|---|---|---|
| Write a non-terminating error | Write-Error 'The record is invalid' | View examples |
| Make a command error terminating | Get-Item -LiteralPath $Path -ErrorAction Stop | View examples |
| Hide a command error | Get-Item -LiteralPath $Path -ErrorAction `
SilentlyContinue | View examples |
| Catch a failure | catch { Write-Warning $_.Exception.Message } | View examples |
| Catch one exception type | catch [System.IO.FileNotFoundException] { Write-Warning `
'Missing file' } | View examples |
| Order specific handlers first | catch [System.UnauthorizedAccessException] { `
Write-Warning 'Access denied' } | View examples |
| Inspect the caught error | $_.Exception.Message | View examples |
| Inspect the category | $_.CategoryInfo.Category | View examples |
| Read the newest error | $Error[0] | View examples |
| Capture command errors | Get-Item missing.txt -ErrorVariable lookupErrors `
-ErrorAction SilentlyContinue | View examples |
| Always run cleanup | finally { $stream.Dispose() } | View examples |
| Raise a terminating error | throw 'Configuration is invalid' | View examples |
| Re-throw the current error | throw | View examples |
| Set a scoped default action | $ErrorActionPreference = 'Stop' | View examples |
| Write a warning | Write-Warning 'Using fallback configuration' | View examples |
| Read a native exit code | if ($LASTEXITCODE -ne 0) { throw `
"Tool failed: $LASTEXITCODE" } | View examples |
| Inspect command success | if (-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
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.
$Path = 'C:\missing\settings.json'
try {
Get-Item -LiteralPath $Path -ErrorAction Stop
'Loaded'
}
catch {
Write-Warning "Cannot read $Path"
} WARNING: Cannot read C:\missing\settings.jsonGet-Item -LiteralPath 'missing.txt' `
-ErrorAction SilentlyContinue `
-ErrorVariable lookupErrors
$lookupErrors[0].CategoryInfo.Category ObjectNotFoundCatch 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.
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 $_
} # Exactly one matching handler runs for a terminating exception.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.
try {
Get-Item -LiteralPath 'missing.txt' -ErrorAction Stop
}
catch {
[pscustomobject]@{
Message = $_.Exception.Message
Category = $_.CategoryInfo.Category
ErrorId = $_.FullyQualifiedErrorId
Target = $_.TargetObject
}
} Message : Cannot find path 'missing.txt' because it does not exist.
Category : ObjectNotFound
ErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand
Target : missing.txtRelease 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.
$stream = $null
try {
$stream = [IO.File]::OpenRead($Path)
$stream.Length
}
finally {
if ($null -ne $stream) { $stream.Dispose() }
} # The stream is disposed even when reading its length fails.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.
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
} WARNING: Required setting is missing: Region
# The original terminating error continues to the caller.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.
& {
$ErrorActionPreference = 'Stop'
try {
Get-Content -LiteralPath $Path
}
catch {
Write-Warning $_.Exception.Message
}
}
Write-Verbose 'The outer preference was not changed.' # The preference assignment is limited to the child scope.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.
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.'
} # git diff --quiet uses 0 for no differences, 1 for differences, and values above 1 for errors.Sources and further reading
References
Authoritative documentation used to verify and expand this cheat sheet.
Help us improve
Found a typo or missing example?
Tell us what would make this cheat sheet clearer, more complete, or more useful.



