Categories
Development Powershell Tutorials

Powershell – Try to Catch me

In times like these when the real world is a bit crazy, it can be good to dive into something else and let the mind concentrate on learning a new skill.

So lets wash our hands and jump into a Powershell tutorial!
This time we’ll be talking about how we can easily handle errors that might occur in our scripts.
As always with Powershell, there are multitudes of different ways to do this but we’ll talk about the one I prefer, Try Catch.

Try{
    Get-Process "Wrong name of process" -ErrorAction Stop
}
Catch{
    Write-host "Oh oh error when getting process information!" -ForegroundColor Red
}

The above code is very bare bones what is needed but doesn’t really add much value.

Before we improve the example, lets talk about each block and also mention a third block that we are not using, called Finally.

The Try block comes first and within its script block (The wiggly brackets { } ) is the code that we want to catch errors from.

You’ll notice that we have added the parameter ErrorAction with value Stop to the Get-Process command.
This is because not all errors in Powershell is considered to be terminating errors, and only those kind of critical errors are caught by the Try Catch statement.
But we want all errors for Get-Process to be handled as terminating errors so we can apply our own logic and handling to them.

Script blocks will be something that you’ll come across a lot in Powershell, both when building scripts but also in one-liners.
They allow multiple lines (in a one-liner you’d separate the commands using semicolons ; ).

The Catch block is the second part of this statement and contains all the code that will be run once an error from the Try block occurs.

In the example above we only write to the console using Write-Host saying that we’ve found an error, not very useful at all!
Using Try Catch suppresses Powershell’s normal output to the console so based on our example, we wont know what error occurred since the only information we now receive is “found an error”.

We’ll add some more useful things to the Catch block later!

Try and Catch are both mandatory but there is a third part that is optional called Finally.

Try{
    Get-Process "Wrong name of process" -ErrorAction Stop
}
Catch{
    Write-host "Oh oh error when getting process information!" -ForegroundColor Red
}
Finally{
    Write-Host "Phew finally done!" -ForegroundColor Green
}

The code in the Finally block will always be run, even if the error stops the script from continuing or if you yourself have added a exit or return command to the Catch script block.

Personally I don’t use Finally that much, very rarely actually, but it can be useful if you have code that you need to run regardless of the success of the code in the Try block.

Lets improve!

# Name of the process we want to gather information about using Get-Process. Seems to be misspelled hmm..? 
$processName = "Shellpower"

# Get information about process
Try{
    $process = Get-Process $processName -ErrorAction Stop
}
# Only comments are allowed to be between the Try block and the Catch block
Catch{
    # Exception message, the actual error reported by Powershell
    $exception = $_.Exception.Message

    # Output a warning to the console about the error
    Write-Warning "Error when trying to get information about the process $processName. Error message was: $exception"    
}

So we’ve obviously added a bunch of comments and changed the process name to use a variable with the value “Shellpower” which is a name we wont be finding among our processes.

Those things aside, we now have a variable called $exception.
This variable will pull the current exception message, saved in the variable we can use it to output or save the information easily.

If we didn’t use the Try Catch block we’d receive something like this:

With our example, we instead receive this:

WARNING: Error when trying to get information about the process Shellpower. Error message was: Cannot find a process with the name “Shellpower”. Verify the process name and call the cmdlet again.

With this method you can add a more customized error message while still retaining the original error message.

You can add several commands to the Try block which can be enough if all you want to do is catch and report/log the errors.
I personally try to keep them to one command each and then add a customized error text which gives more information, since the exception messages can be a bit lacking.

Another option could be to store the information in a log file, write it to a SQL database or maybe even have the script do something when it encounters specific errors.

There are loads of possibilities with this but for the sake of keeping this bite sized we’ll stop here.

As always, continue to learn and evolve your skills, see you in the next one!

Do you want to know more? Here is a list of tutorials to check next

Leave a Reply

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