Error Handling with PowerShell Try Catch Block: Demystified!

As a PowerShell user, I’m sure you’ve encountered your fair share of errors. Dealing with errors is an inevitable part of writing PowerShell scripts. But what do you do when an error occurs? Well, with the use of Try Catch blocks, you can improve your error handling and ensure that your scripts run smoothly. Without proper error handling, your scripts can fail silently or crash spectacularly. To make your code more robust and production-ready, you need to be able to gracefully catch and handle errors to keep your script running smoothly.

PowerShell’s error handling can save you a lot of time and headaches. Try/Catch allows you to encapsulate sections of risky code and take action when errors occur in that code. In this comprehensive guide, I’ll cover everything you need to know about handling errors in PowerShell, including the “try catch finally” blocks, specific error handling, and best practices. So let’s get started!

Introduction to PowerShell Error Handling

PowerShell is a powerful tool that can automate tasks and save you time. However, with great power comes great responsibility. When you’re working with PowerShell, errors can occur. These errors can be caused by a variety of factors, including syntax errors, missing parameters, invalid data, or unexpected issues with the environment. PowerShell error handling is the process of catching and handling these errors in a way that allows your script to continue running smoothly.

We’ll start by covering the basic syntax and usage of Try/Catch blocks. Then, we’ll explore PowerShell-specific best practices for catching errors like validating input, handling specific exception types, documenting expected errors, and logging details. I’ll also demonstrate real-world examples of using Try/Catch when processing files and data.

Understanding PowerShell Errors and Exception Handling

Before we dive into PowerShell error handling, let’s take a closer look at PowerShell errors and exception handling. When an error occurs in PowerShell, it generates an error record. This error record contains information about the error, including the error message, category, and stack trace. When an error occurs, it can cause the script to fail or produce unexpected results.

PowerShell exception handling is the process of catching and handling exceptions, which are a type of error that can be recovered from. Exceptions occur when a script encounters an unexpected condition, such as a divide-by-zero error or an out-of-memory exception.

What is Try Catch in PowerShell?

A Try Catch block in PowerShell is an error handling mechanism used to handle terminating errors in PowerShell scripting. When you include a Try Catch block in your script, you can catch and handle errors that occur during the execution of your script.

The Try block contains the code that you want to execute, while the Catch block or Trap statement is used to contain the code that you want to execute when an error is generated in the try block. If an error occurs in the Try block, PowerShell will execute the code in the Catch block. This allows you to handle the error gracefully and take appropriate action.

Why Use Try Catch in PowerShell?

Error handling is an essential part of PowerShell scripting. Without proper error handling, your scripts may fail or produce unexpected results, causing confusion or problems for users. By using Try Catch blocks, you can catch and handle errors in a more controlled manner, improving the reliability and usability of your scripts.

Using Try Catch blocks in your PowerShell scripts has several benefits. Firstly, it helps to prevent your script from crashing due to errors. Secondly, it allows you to handle errors gracefully and take appropriate action. Finally, it provides you with more control over the error-handling process, allowing you to customize error messages and log errors. By following the PowerShell error handling methods, you can ensure your PowerShell scripts are robust and error-free.

How to Use Try Catch in PowerShell?

To use Try Catch blocks in PowerShell, you need to include them in your script. The Try block contains the code that you want to execute, while the Catch block contains the code that you would like to execute when an error occurs. The Catch block is your opportunity to take action when an error occurs. It’s here where you’ll write the code to manage the error and possibly recover from it. This could be logging the error message to a file, displaying a user-friendly error message, or taking corrective action.

PowerShell Try Catch Syntax

Here’s the basic syntax for PowerShell Try Catch blocks:

Try {
    # Code to execute goes here
    # Statement List
}
Catch {
    # Code to execute when an error occurs goes here
}

The key points:

  • The code inside the try block is executed.
  • If an error occurs, execution immediately jumps to the catch block.
  • The catch block can access the error record in the automatic $_ variable.
  • After the catch block handles the error, execution continues as normal.

This allows your script to gracefully recover when things go wrong instead of unceremoniously crashing.

Let’s see an example:

try {
    # Some code that may cause an error
    Get-Content -Path C:\nonexistentfile.txt -ErrorAction Stop
}
catch {
    # Logging the error to a file
    Write-host -f foregroundcolor red "Encountered Error:"$_.Exception.Message
    $Error[0] | Out-File -FilePath C:\Logs\Errorlog.txt -Append
}

In the above example, the Try statement contains the code that you want to execute, while the Catch block contains the code that you want to execute when an error occurs. In this case, if the Get-Content command fails due to a nonexistent file, the error message using the automatic variable $Error is appended to an error log file. Please note, that the $Error error variable contains a collection of all errors generated in the current Windows PowerShell session (You can clear the error variable using $Error.Clear(), if needed).

How to log the Error message to a Text File?

Logging error messages to a file in PowerShell is quite a common task, especially when automating processes where you may want to review errors later. There are multiple ways to achieve this. Below is a basic method to log error messages to a file using PowerShell:

# Define the log file path
$LogFile = "C:\Temp\AppLog.txt"

# Wrap your script or command in a try-catch block
Try {

    # Your PowerShell command that might generate an error
    Get-Content "C:\nonexistentfile.txt" -ErrorAction Stop

} Catch {

    # Log the error message to the log file
    Add-Content -Path $LogFile -Value $("[" + (Get-Date) + "] " + $_.Exception.Message)
}

Within a catch block, you can get the error message and add it to a text file for review.

Terminating Error vs. Non-Terminating Errors in PowerShell

Let’s understand the difference between the two types of errors: Terminating and non-terminating errors.

Terminating errors will stop/halt the script from further execution, while a non-terminating error will not stop the execution and can give the wrong output. Non-terminating errors are more dangerous than terminating errors because you don’t know what happened after executing the script. Also, it does not stop the pipeline execution. There is no error message or log to warn you.

Some good examples of terminating errors are memory and syntax errors, whereas unexpected errors and errors in programming logic come from non-terminating errors. Here are examples of handling terminating and non-terminating errors in PowerShell:

Terminating Error:

Here is an example of a script-terminating error:

try {
    # Code that may throw a terminating error because of the wrong Parameter
    Get-Item -Location "C:\Temp"
} catch {
    # Error handling code - powershell catch exception message
    Write-Host -foregroundcolor Red "An error occurred: $_"
}
PowerShell try catch

In this example, the try block contains the code that may throw a terminating error (in this case, it uses the wrong parameter “Location” with the cmdlet Get-Item). The catch block is executed when a terminating error occurs, and the error message ($_) is displayed.

Non-Terminating Errors:

The default value for $ErrorActionPreference variable is “Continue”. So, PowerShell treats non-terminating errors as “Continue” and continues executing the remaining code. However, by setting $ErrorActionPreference to “Stop” or using the -ErrorAction Stop parameter to a cmdlet, you can convert non-terminating errors into terminating errors.

Try {
    # Code that may produce non-terminating errors
    Get-ChildItem -Path "C:\NonexistentFolder" -ErrorAction Stop
} Catch {
    # Error handling code
    Write-Host -f Yellow "An error occurred: $_"
}
PowerShell Try Catch Error Handling

The try block contains the code that may produce a non-terminating error (in this case, attempting to list files in a non-existent folder using Get-ChildItem). We set the $ErrorAction variable to “Stop” to treat non-terminating errors as terminating errors, so they can be caught inside the “catch” block. We can also set the erroractionpreference variable to change the behavior throughout the script.

Here’s an example demonstrating the usage of $ErrorActionPreference:

# Set ErrorActionPreference to "Stop"
$ErrorActionPreference = "Stop"

try {
    # This command will fail because the file does not exist
    Get-Content "nonexistentfile.txt"
}
catch {
    Write-Host -f Red "Caught an error! Here's the message: $_"
}

# Reset ErrorActionPreference to default "Continue"
$ErrorActionPreference = "Continue"

# Try the same failed command again
Get-Content "nonexistentfile.txt"

Write-Output "Script continues here..."

In this example, We first set $ErrorActionPreference to “Stop”. This means any errors will halt the script. Then, we reset the $ErrorActionPreference to its default value (Continue). We attempt to read the non-existent file again. This time, you’ll see the error message, but the script won’t halt.

The Error Action Preference

PowerShell has a number of error action preferences that determine how errors are handled. These preferences include Stop, Continue, SilentlyContinue, and Inquire. The default error action preference is “Continue”, which means that errors are displayed, but the script continues to run. You can set the ErrorAction Parameter to treat non-terminating errors as terminating and catch them.

The Stop error action preference, on the other hand, stops the script when an error occurs. SilentlyContinue suppresses all error messages, while Inquire prompts the user to decide how to handle the error.

PowerShell Suppress Error Messages

Sometimes, you may want to suppress error messages in PowerShell. You can do this using the SilentlyContinue error action preference.

Here’s an example of how to suppress error messages in PowerShell:

Get-ChildItem C:\Windows\System32\config -ErrorAction SilentlyContinue

Ignoring Errors in PowerShell

In some cases, you may want to ignore errors in PowerShell. You can do this using the ErrorAction preference.

Here’s an example of how to ignore errors in PowerShell:

Get-ChildItem C:\Windows\System32\config -ErrorAction Ignore

Try Catch Finally Block in PowerShell

In addition to Try Catch blocks, you can also use Finally blocks in PowerShell. The Finally block contains the code that you want to execute after the Try and Catch blocks have been completed. This code will always execute, regardless of whether an error occurred or not. Here is the basic structure of Try-Catch-Finally blocks:

Try Block

The Try block contains the code that you want to execute. This can be any valid PowerShell code, such as a command, function, or script. When an error occurs within the Try block, PowerShell jumps to the Catch block and executes the code within it. Single or multiple statements follow the Try keyword in the outermost brackets. Typically, contains statements you want PowerShell to monitor for errors.

Catch Block

The Catch block contains the code that you want to execute if an error occurs within the Try block. There can be multiple Catch blocks, each handling a specific type of error. When an error occurs, PowerShell searches the Catch blocks in order until it finds one that matches the error type. The code within that catch block is then executed. The catch keyword is followed by an optional list of error type specifications and a list of statements.

Finally Block

The Finally block is optional and contains code that is executed regardless of whether an error occurs or not. This can be useful to release resources or clean up after the main logic, such as closing open files or connections, used to free a resource that is no longer needed, etc. The optional finally block executes after the try and catch blocks, regardless of whether an error occurred.

Here’s an example of a PowerShell Try Catch Finally block:

Try {
    # Code that may generate an error
}
Catch {
    # Code to handle the error
}
Finally {
    # Code to execute regardless of whether an error occurred or not
}

In the above example, the Finally block contains the code that you want to execute after the Try and Catch blocks have been completed. The Finally keyword is followed by a list of statements, that runs every time when the script is executed. Finally blocks run even when the script is stopped with CTRL+C. In addition, the block will execute if the script is stopped using the Exit keyword within a Catch statement.

PowerShell Try-Catch-Finally Examples

Let’s take a look at some real-world examples of PowerShell try-catch-finally blocks. The PowerShell Try Catch block can be used to handle errors that occur during file operations, such as copying or deleting files.

Try {
    Copy-Item C:\Temp\file.txt D:\Backup -ErrorAction Stop
}
Catch {
    Write-Host "An Error Occured on copying file: $_.Exception.Message"
}
Finally {
    Write-Host "Copying process complete"
}

The try-catch block cannot handle non-terminating errors by default. By using the ErrorAction parameter, you can convert non-terminating errors into terminating errors.

Validating Inputs instead of Error Handling

Many errors can be prevented by validating input values before passing them into cmdlets. For example, first test if a file exists:

$Path = "C:\Temp\AppLog.txt'"

if (!(Test-Path $path)) {
  Write-host "File does not exist: $path"
  return
}

try {
  Get-Content -Path $path
}
catch {
  # Handle error
}

This prevents useless error-handling code from even being needed for a common scenario.

Handling Specific Errors with PowerShell Try-Catch

A bare catch block will capture any error that occurs. It’s better to catch only operation-specific errors by specifying an error type. In addition to the try-catch-finally block, PowerShell allows you to handle specific errors with the catch block. This is useful when you want to handle different types of errors in different ways.

The following example shows, how to handle a specific error in PowerShell:

Try {
    # Block of code to execute
}
Catch [System.IO.FileNotFoundException] {
    # Code to execute if a file not found error occurs
}

In the above example, the Catch block will only execute if a System.IO.FileNotFoundException error occurs within the Try block. This allows you to handle the error in a specific way, such as displaying a message to the user or taking corrective action.

Error Handling with Multiple Catch Blocks

Did you know you can specify different catch blocks for different types of errors? This allows you to tailor your response depending on the error that occurs. Let’s see an example where we handle FileNotFoundException and UnauthorizedAccessException differently:

PowerShell continues to look for appropriate Catch blocks or Trap statements in the parent scopes if the Try statement does not contain a matching Catch statement. Here is another example with Multiple Catch blocks to handle different types of exceptions:

try {
    # Code that may cause an error
    Get-Content -Path C:\nonexistentfile.txt -ErrorAction Stop
}
catch [System.IO.FileNotFoundException] {
    Write-Host "Error: The file does not exist."
}
catch [System.UnauthorizedAccessException] {
    Write-Host "Error: You do not have the necessary permissions to access this file."
}
catch {
    Write-Host "An unknown error occurred."
}

By using specific Catch blocks, you can handle multiple exceptions with an appropriate catch block! Here, we have separate catch blocks handling two catch blocks: File not found as the first catch block and unauthorized access scenarios as the second catch block and a general catch block for other unforeseen errors. You can also add multiple exception types to the same catch statement.

Limiting Try Block Size

It’s better to have multiple small try/catch blocks rather than oversized blocks encapsulating dissimilar operations.

Bad Example:

Try {
  $user = Get-User -Name $name
  $file = Get-File -Path $path
  Write-Log -Message "Processing $file for $user"
  Copy-Item -Path $path -Destination $dest
  Remove-Item -Path $path
}
catch {
  # Massive block handling many possible errors
  Write-host -f Red $_.Exception.Message
}

Good Example:

$user = Get-User -Name $name
$file = Get-File -Path $path

try {
  Write-Log -Message "Processing $file for $user" 
}
catch {
  # Handle write error
}

try {
  Copy-Item -Path $path -Destination $dest
}
catch {
  # Handle copy error  
}

try {
  Remove-Item -Path $path
}
catch {
  # Handle remove error
}

PowerShell Throw Exception Command

Sometimes, you may want to generate your own error in PowerShell. You can do this using the throw command. The throw command creates an error record and stops the script.

Here’s an example of how to use the throw command in PowerShell:

if ($null -eq $someVariable) {
    throw "SomeVariable is null"
}

Catch Error Messages in PowerShell Scripts

When you’re handling errors in PowerShell, you may want to display the error message to the user. You can do this by accessing the ErrorRecord object, which contains information about the error. Inside the catch block, the $_ automatic variable contains an object with details about the error.

The most useful properties are:

  • $_.Exception.Message: The error message text.
  • $_.Exception.ItemName: The input that caused the error.
  • $_.Exception.PSMessageDetails: Additional info about the error.
  • $_.CategoryInfo: The category of the error, such as InvalidArgument.
  • $_.FullyQualifiedErrorId: The full ID of the error, such as NativeCommandError.
  • $_.Exception.GetType().FullName – Gets you the full name of the exception

Here’s an example of how to display the error message in PowerShell:

Try {
    # Code that may generate an error
    $Service = Get-Service -Name "My Fake Service Name" -ErrorAction Stop 
}
Catch {
    #Output Error details: Exception message
    Write-Host $_.Exception.Message
}

The $_ variable contains the current error object that caused the error (You can also get the same using $PSItem). This can be useful for displaying detailed error information or taking corrective action. When catching errors, output or log details like messages, exception types, stack traces, and input values. To find details about exceptions and errors, there are a few exception properties:

try {
  $proc = Get-Process -Name MyFakeProcess -ErrorAction Stop
}
catch {
  # Find the Exception Details 
  Write-Warning $_.Exception.Message 
  Write-Warning $_.CategoryInfo
  Write-Warning $_.FullyQualifiedErrorId
  Write-Warning ($_.ScriptStackTrace -replace '^')
}

Finding the location of the error

Try Catch blocks can be used for debugging scripts by providing detailed error information. When an error occurs, PowerShell displays the error message in the console. However, this message may not provide enough information to identify the cause of the error. By using Try-Catch statements, you can catch the error object and display detailed error information, such as the line number and error type. In the following code, the error object is caught, and the line number and error message are displayed in the console.

Try {
    # Block of code to execute
    throw "SomeVariable is null"
}
Catch {
    Write-Host "Error on line $($_.InvocationInfo.ScriptLineNumber): $($_.Exception.Message)"
}

This can help identify the cause of the error and improve script development.

Best Practices for PowerShell Try Catch Error Handling

Now that you know how to handle errors in PowerShell, let’s take a look at some best practices.

  1. Always use a try-catch-finally block when running potentially risky code.
  2. Use specific error handling when appropriate. This can improve script reliability and reduce confusion for users.
  3. Use the “Catch” blocks to handle errors gracefully and take appropriate action.
  4. Use the Stop error action preference when critical errors occur.
  5. Display error messages to the user when appropriate.
  6. Use Finally blocks to execute code that should always run, regardless of whether an error occurred or not. E.g., cleaning up resources.
  7. Log Errors – Log errors to a file or database to track the frequency and types of errors that occur. This can help identify and troubleshoot issues with a script.

Following these practices will improve the reliability, readability, and maintainability of your error handling. Here is the Microsoft documentation: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_try_catch_finally?view=powershell-7.3

Conclusion

In conclusion, using Try Catch blocks in PowerShell scripts is an essential mechanism for error handling. It helps to prevent your script from crashing due to errors, allows you to handle errors gracefully, and provides you with more control over the error-handling process. By using try-catch-finally blocks, you can catch and handle errors in a way that allows your script to continue running smoothly in your automation.

Whether you are a beginner or an experienced PowerShell user, mastering Try Catch is essential for developing robust and efficient scripts. As you can see, they offer flexible and powerful error-handling options that make your scripts more robust and user-friendly. Start using them today and feel the difference in your PowerShell scripting journey!

If you enjoyed this read, you might also like the following articles I’ve written for real-world scenarios.

How do I catch exception messages in PowerShell?

To catch exception messages in PowerShell, you can use a try-catch block. The try block contains the code that may throw an exception. If an exception occurs, PowerShell will look for a matching catch block to handle the exception. Here is an example:
Try {
Get-ChildItem -Path "C:\Nonexistent"
} catch {
Write-Host "An error occurred: $($_.Exception.Message)"
}

How do I raise exceptions in PowerShell?

To raise exceptions in PowerShell, you can use the throw keyword. The throw keyword allows you to create and throw a new exception in your code. When an exception is thrown, it can be caught by a try-catch block. Here is an example of raising an exception in PowerShell:
try {
if ($null -eq $varInput) {
throw [System.ArgumentNullException]::new("Input Value cannot be null!")
}
} catch {
Write-Host "Error occurred: $_"
}

How do I find the last error in PowerShell?

To find the last error in PowerShell, you can access the error variable: $Error. The $Error variable is an automatic global variable in PowerShell that contains an ArrayList of zero or more ErrorRecord objects. When a new error occurs, they are added to the beginning of this list, so you can always get information about the most recent error by looking at $Error. Here is an example of how to access the last error in PowerShell:
$Error[0]

What is the use of ErrorAction in PowerShell?

The ErrorAction parameter in PowerShell determines how PowerShell handles non-terminating errors. Non-terminating errors are errors that do not stop the script from running, but instead generate an error message and continue executing the script.  E.g., setting “-ErrorAction Stop” Stops the execution of the script when an error occurs.

What is the difference between try catch and if else in PowerShell?

The try-catch and if-else statements in PowerShell are used for different purposes and have different functionalities. However, In some cases, the If Else statement also helps to handle Exceptions. E.g., To check if a file exists before performing some operation such as File Open, You can use:
If (-not (Test-Path -Path C:\SomePath\FileDoesNotExist.txt)) {
Write-host "The file does not exist!"
} else {
Write-Host "The file does exist"
}

How do I catch exception messages in PowerShell?

In PowerShell, you can catch exception messages by using the Try-Catch block. This allows you to run a block of code and catch any exceptions that may occur. Within the Catch block, you can access the exception message using the $_.Exception.Message property.

Salaudeen Rajack

Salaudeen Rajack - Information Technology Expert with Two decades of hands-on experience, specializing in SharePoint, PowerShell, Microsoft 365, and related products. Passionate about sharing the deep technical knowledge and experience to help others, through the real-world articles!

Leave a Reply

Your email address will not be published. Required fields are marked *