Last Update: Sep 04, 2024 | Published: Aug 05, 2022
Windows PowerShell has a robust error handling capability with PowerShell try catch blocks. And PowerShell 7 introduced new features, making troubleshooting even easier. In this article, I will show you how to use PowerShell’s built-in error handling features to help debug your scripts when there are problems.
First, it helps to have a good understanding of errors within PowerShell. A common operation is to test the network connection to another system using the Test-Connect cmdlet. The example is using a computer name of fakesystem
, that isn’t going to work, and only 1
ICMP ping is being sent to simplify testing (default is 4
ICMP pings).
Test-Connection "fakesystem" -Count 1
As expected the operation failed, but it would be nice to output a nicer error message then that. To “catch” the error, we use a try-catch
block. By wrapping our code in this block, any error will be caught and we can then output an appropriate message or take some other action. Let’s give this a try below. You should expect to see Error
in the output.
Try { Test-Connection "fakesystem" -Count 1 } Catch { "Error" }
Instead you see the same error message as before, ...No such host is known...
, but shouldn’t we see Error
? The Test-Connection
cmdlet outputs something called a non-terminating error. There are two types of errors, Terminating and Non-Terminating. Terminating errors stop execution whereas non-terminating writes to the error stream but does not stop the pipeline execution. The try-catch
block only catches terminating errors.
How do we make Test-Connection
throw a terminating error then? Thankfully there is a handy parameter available to most functions called, ErrorAction. You can configure the cmdlets error handling behavior to throw a terminating error by specifying Stop
as the value.
Try { Test-Connection "fakesystem" -Count 1 -ErroAction 'Stop' } Catch { "Error" }
Now when you run the above code, you will get Error
as the output. The output of just what we define for the error message is much more concise and opens up the door to customized error messages. Often though, instead of catching all errors equally, maybe you want to customize how each exception type is handled. try-catch
can do this, but you first need to know what the exception is.
After running the above code, you can inspect the global $Error
variable and as you can see below what exception type was thrown:
$Error[0].Exception.GetType().FullName
Now that we know the specific exception type is System.Net.NetworkInformation.PingException
we can catch just this error. The code below will output Ping Exception
and as you can tell we can chain multiple exception types with a default value at the end.
Try { Test-Connection "fakesystem" -Count 1 -ErrorAction 'Stop' } Catch [System.Net.NetworkInformation.PingException] { "Ping Exception" } Catch { "Unknown Exception" }
All this is very cool and useful but how does PowerShell 7 help us here? As you’ve no doubt noticed, unless you are turning everything into terminating errors using ErrorAction 'Stop'
, this will quickly become difficult to manage.
Related article: Understanding the PowerShell 7 Error Variable
PowerShell 7 has a brand new error view option called ConciseView
. Set the preference variable $ErrorView
to 'ConciseView'
or to get the same view as before set the variable to 'NormalView'
. With ConciseView
turned on (the default in PowerShell 7) let’s see what our output looks like now with the Test-Connection
example.
Test-Connection "fakesystem" -Count 1
Below is a view of each of the three ErrorView options and how they display the error of the Test-Connection
example.
That is a whole lot easier to digest! What if you need to dive into the error to understand what’s going on though? With PowerShell 7 there is a brand new cmdlet named Get-Error
. This cmdlet outputs a ton of very useful and interesting information.
If we run Get-Error
with no arguments, it outputs all the information on the last error to be shown. In this case, that of our Test-Connection
failure as shown below.
Get-Error
Woah, that is a lot more than expected! What’s great about this is that it displays not only the basic exception but also the InnerException
and a StackTrace
which dives into the internals and displays a lot of useful information, especially if we don’t really know what went wrong.
As you can tell, error handling in PowerShell is robust and can be well controlled. With the addition of a more concise view for errors in the console, and the additional added ability to easily dive into the underlying reasons for an error, PowerShell 7 has upped the game in helping you troubleshoot your functions, scripts, and modules!