Skip to content

Error Handling

Try/Catch/Finally Blocks

PowerShell's try/catch/finally blocks allow you to handle exceptions explicitly. The try block contains code that might throw an error, catch handles specific exceptions, and finally executes cleanup code regardless of errors.

Example: Handling File Operations

try {
    $content = Get-Content -Path "C:\temp\missingfile.txt"
    Write-Output "File content: $content"
} catch {
    Write-Error "Failed to read file: $_"
} finally {
    Write-Host "Cleanup complete."
}
  • The catch block captures errors (e.g., file not found) and provides the error message via $_.
  • The finally block ensures resources are released or logs are flushed, even if an exception occurs.

Custom Error Objects

PowerShell's built-in error handling is flexible, but you can create custom error objects for richer diagnostics. Use the throw keyword with a custom exception object to define structured error data.

Example: Throwing a Custom Error

$errorMessage = "Invalid user credentials"
$customError = [System.Management.Automation.ErrorRecord]::new(
    [System.Management.Automation.PSException]::new($errorMessage),
    "InvalidCredentials",
    [System.Management.Automation.ErrorCategory]::InvalidArgument,
    "C:\scripts\auth.ps1"
)
throw $customError
  • The ErrorRecord class allows you to specify error messages, categories, and source locations.
  • Use -ErrorAction in cmdlets to control how errors are handled (e.g., Stop, Continue, SilentlyContinue).

Exit Codes

Exit codes are integers returned by commands to indicate success or failure. PowerShell uses $LASTEXITCODE to store the exit code of the last executed command. This is particularly useful for scripts running in non-interactive environments.

Example: Checking Exit Codes

# Run an external command and capture exit code
certutil.exe -generateSelfSignedCert "C:\cert\test.cer" > $null 2>&1
if ($LASTEXITCODE -ne 0) {
    Write-Error "Command failed with exit code: $LASTEXITCODE"
}
  • Exit codes are often used in conjunction with if statements or switch blocks to determine next steps.
  • Always validate exit codes after external commands (e.g., net.exe, certutil.exe).

Key takeaways

  • Use try/catch/finally blocks to handle exceptions and ensure cleanup.
  • Create custom error objects with [ErrorRecord] for detailed diagnostics.
  • Leverage exit codes ($LASTEXITCODE) for script reliability in non-interactive contexts.
  • Combine try/catch with -ErrorAction to control error propagation.
  • Always validate exit codes after external commands to avoid silent failures.