Properly using try/catch to handle errors

Error handling is easily one of the most overlooked things about Powershell in my opinion, it seems like I see a ton of well written scripts with just improper error handling, but why? It's actually not that hard of a concept, until you aren't sure whether or not something produces a terminating error... Unless you know 1 extremely simple tip:

First let's briefly breakdown the syntax, you generally only need a try/catch and the two are mutually inclusive, i.e. anytime you use try you must use catch as well, both just wrap your code in scriptblocks. The try block is simply where you are executing your code, and if there is a terminating error your code automatically stops at it's point in the try block and falls to the catch scriptblock to handle your error as desired. Here is a quick example:

try{
    $ProfilePaths = (Get-CimInstance win32_userprofilse -ErrorAction SilentlyContinue).LocalPath
} catch {
    Write-Host -ForegroundColor Red "Error: Unable to query user profiles"
}

So if you haven't noticed already you can see that we mistyped our class name. Therefore if we run our code in theory we should fall to our catch block, right? Well, here is the output of this code:

That's not right, it ran the code but didn't display our error. That's because our Get-CimInstance cmdlet didn't produce a terminating error. Luckily, by using throw within our try block we can force it to fall to the catch block. Therefore since we are capturing the output of our command to a variable we can simply test to see if we have an empty variable or not. Let's take a look at what our code looks like now:

try{
    $ProfilePaths = (Get-CimInstance win32_userprofilse -ErrorAction SilentlyContinue).LocalPath

    if(!$ProfilePaths){ throw }
} catch {
    Write-Host -ForegroundColor Red "Error: Unable to query user profiles"
}

So now if we run this code we get the error message we were expecting:

That's really it, you can explore things such as finally blocks that go after the catch block and happen no matter what the result of the code is, however the try/catch concept is the foundation to it all and with this extremely simple tip you can properly handle nearly any command without having to guess and check to see if it produces a terminating error or not. 

Nathan Kasco