A Look at Try/Catch in PowerShell

My article here wraps up PowerShell Blogging Week (#PSBlogWeek), which has been a series of articles on Windows PowerShell Advanced Functions. We hope that you have enjoyed this series and hope you will supply us with more ideas so we can continue to provide fun and useful material for you!

When working with errors and trying to get a handle on them, you need to use what is available to not only catch them, but also to determine what the next course of action is after you have caught them. In this article, I am focusing solely on Try/Catch (along with Finally) and how you can use these to perform some essential error handing in your scripts.

Let’s break down each of these statements and what they accomplish.

Try

Try is where you are going to place your code block in that you want to watch for errors that will be handled later on in the script. Know that wherever the error occurs, it will immediately stop at that point and move onto the Catch keyword (assuming that the error is a terminating error). During this you need to ensure that you either have $ErrorActionPreference=’Stop’ so every error that occurs is considered a terminating error (useful when working with outside commands that do not throw terminating errors by default) or you can make use of –ErrorAction ‘Stop’ in a cmdlet to force the cmdlet to throw a terminating error.

Note: Did you know that using the Throw keyword says that the error being thrown is a terminating error? Try it in a Try/Catch and see what happens!

Here is an action of what be in a Try statement:

Try {
    Write-Verbose "[TRY] Checking for OS" -Verbose
    $OS = Get-WmiObject -ComputerName RemoteServer -Class Win32_OperatingSystem -ErrorAction Stop
    Write-Verbose "[TRY] No issues found" -Verbose
}

Assuming that I can connect to this remote system, I should see the Verbose output afterwards, otherwise based on the ErrorAction of Stop, it will send the execution down to the Catch statement.

Catch

Here is where the execution of code continues after an error occurs within the Try statement. One of the neat things about using Catch is that you can have multiple Catch statements based on the error type that you want to handle. If you want to take a different action on an Access Denied error, you can specify the System.UnauthorizedAccessException type and anytime the error record relates to an unauthorized access exception, it will be handled in that statement while all other errors will be handles by the Catch statement with no exception type defined. Think of this one as the ‘catch all’ Catch block. Here is an example of such a Catch statement.

Catch [System.UnauthorizedAccessException] {
    Write-Warning "[CATCH] You do not have the proper access to this system!"
    BREAK
}
Catch [System.Runtime.InteropServices.COMException] {
    Write-Warning "[CATCH] Communications Exception occurred!"
    BREAK
}
Catch {
    Write-Warning "[CATCH] Errors found during attempt:`n$_"
    BREAK
}

Finally

This keyword performs an action regardless of what happens in the Try/Catch statements. This allows you to perform a sort of cleanup of resources or anything else that you may want to do. Even if we specify BREAK in our Catch block, this will still run any code that happens to be in the Finally block. In fact, even adding Exit to my Catch block will not prevent anything in the Finally block from running before the session is closed.

Finally {
    Write-Verbose "[FINALLY] Performing cleanup actions." -Verbose
}
Write-Verbose "Doing something outside of Try/Catch/Finally" -Verbose

Note that I added some verbose output to run outside of the Finally block. If something throws a terminating error, you will see the Verbose output in the Finally block, but nothing beyond that.

Putting it all together

Putting this all together, we can see how these all come together to work just like we want them to. First let’s see a good attempt with our code:

clip_image002

Now let’s try this with a known issue happening:

clip_image004

Notice that we did not see the verbose output that exists outside of the Try/Catch/Finally blocks. You can also notice that it caught the System.Runtime.InteropServices.ComException exception rather than the ‘catch all’ block. Had I run into an issue where I was getting access denied, the System.UnauthorizedAccessException would have caught the error, otherwise my last Catch block will get the error.

With that, you can see how to use Try/Catch/Finally to control the flow of your code in the event of errors during execution. Of course, this wasn’t an exhaustive look at error handling but is still helpful to get your going!

Hungry for more information about Try/Catch and error handling? Check out the following links for more information about this topic:

#PSBlogWeek Articles:

About Boe Prox

Microsoft PowerShell MVP working as a Senior Systems Administrator
This entry was posted in powershell and tagged , , , , . Bookmark the permalink.

8 Responses to A Look at Try/Catch in PowerShell

  1. Pingback: #PSBlogWeek - Dynamic Parameters and Parameter Validation - Adam, the Automator

  2. Pingback: Free eBook on PowerShell Advanced Functions | Mike F Robbins

  3. Pingback: Quick Hits: Finding Exception Types with PowerShell | Learn Powershell | Achieve More

  4. Pingback: SAPIEN Technologies » Blog Archive » Advanced Help for Advanced Functions – #PSBlogWeek

  5. Pingback: PowerShell Advanced Functions: Can we build them better? With parameter validation, yes we can! | Mike F Robbins

  6. The first time I saw a multiple catch statement was in the MSFT_xADUser module, that blew my mind! I was like “Wait, you can do that?” Certainly helps with drilling down to a specific error.

  7. Pingback: #PSBlogWeek 6 – A Look at Try / Catch in PowerShell by Boe Prox |

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s