Error Handling In PowerShell

In this post I’m going to bring together a few odds and ends relating to error handling in PowerShell. I sometimes forget some of the features and it will be handy for future me and hopefully someone else to have it all in one place.

Terminating vs Non-Terminating Errors
In PowerShell errors can be terminating or non-terminating. Terminating errors will terminate the pipeline and your script will end if you didn’t catch the error in a try..catch block. Non-terminating errors will by default write an error message but continue with the next line of the script. You can control the behaviour of non-terminating errors using the $ErrorActionPreference variable at script level or -ErrorAction parameter at command level. The possible values are Stop, Inquire, Continue (*default), Suspend and SilentlyContinue. Stop will raise a terminating error from non-terminating errors, Inquire will prompt the user to continue, SilentlyContinue will not display the error but will continue executing. Under the covers non-terminating errors call the WriteError method while terminating errors call the ThrowTerminatingError method or raises an exception, there are some guidelines here to implement proper error reporting in your own scripts.

Try..Catch blocks
You can use try..catch blocks to catch terminating errors and handle them gracefully without your script terminating. By default non-terminating errors will not be caught by try..catch blocks. You have to use -ErrorAction or $ErrorActionPreference to change their error behaviour to Stop, which will give the same behaviour as terminating errors. Terminating errors caught by try..catch blocks will not display the usual red error message, which makes your script output look much better and you can control how you want to display the errors.

Storing And Retrieving Errors
PowerShell will keep errors that occurred in your script in the $Error variable, it appends errors to this array so you have to clear it yourself if need be by calling $Error.Clear(). You can for instance set the $ErrorActionPreference to SilentlyContinue to prevent error messages on screen and get the errors from the $Error array when you need them. You can also pass a variable to cmdlets that they can use to store errors that occurred during execution by specifying the
-ErrorVariable parameter and the name of your error variable. By default this variable will only show errors that occurred in the last command executed. It is cleared before every execution unless you specify that it should append errors to the variable by adding a plus sign to the variable name when you pass it to the command. Note: You pass in the variable name without the $ sign:

Get-ChildItem -path 'C:\DoesNotExist' -ErrorVariable +MyErrorVar

Viewing Error Details
By default you will not see much detail when you view an error object but you can pipe it to a list and pass the -force parameter to see all the properties.

$Error[0] | fl -Force

Or in this case I used the Show-Object command from the PowerShell CookBook module. There is quite a lot going on here, the objects in the array are ErrorRecords, they have an exception property that is the underlying .NET exception and it can contain an inner exception which is also an .NET exception.

Error Handling In PowerShell

These exceptions can be nested quite deep and can be a valuable source of information when tracking down errors.

Francois Delport