
close
close
Among the many exciting features being introduced by PowerShell 7, there is a lot of new error display functionality as well! PowerShell already has a robust error handling capability and with these new features, it makes troubleshooting that much easier.
First, it helps to have a good understanding of errors within PowerShell. A common operation is to test the network connection to another system. 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).
advertisment
PS C:\> Test-Connection "fakesystem" -Count 1
Test-Connection : Testing connection to computer 'fakesystem' failed: Cannot resolve the target name.
At line:2 char:3
+ Test-Connection "fakesystem" -Count 1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (fakesystem:String) [Test-Connection], PingException
+ FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand
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.
PS C:\>
Try {
Test-Connection "fakesystem" -Count 1
} Catch {
"Error"
}
Test-Connection : Testing connection to computer 'fakesystem' failed: Cannot resolve the target name.
At line:2 char:3
+ Test-Connection "fakesystem" -Count 1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (fakesystem:String) [Test-Connection], PingException
+ FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand
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.
PS C:\>
Try {
Test-Connection "fakesystem" -Count 1 -ErroAction 'Stop'
} Catch {
"Error"
}
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.
advertisment
After running the above code, you can inspect the global $Error
variable and as you can see below what exception type was thrown:
PS C:\> $Error[0].Exception.GetType().FullName
System.Net.NetworkInformation.PingException
Now that we know the specific exception type is System.Net.NetworkInformation.PingException
we can catch just this error. The below code 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. What if you just want to output a simple error message for an operation? Using the Test-Connection
example from before:
PS C:> Test-Connection "fakesystem" -Count 1
Test-Connection : Testing connection to computer 'fakesystem' failed: Cannot resolve the target name.
At line:2 char:3
+ Test-Connection "fakesystem" -Count 1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (fakesystem:String) [Test-Connection], PingException
+ FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand
As you can see above, we get this very long error output for a simple Cannot resolve the target name
error message. 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.
advertisment
PS C:> Test-Connection "fakesystem" -Count 1
Test-Connection: Testing connection to computer 'fakesystem' failed: Cannot resolve the target name.
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.
PS C:\> Get-Error
Exception :
Message : Testing connection to computer 'fakesystem' failed: Cannot resolve the target name.
InnerException :
Message : No such host is known.
SocketErrorCode : HostNotFound
ErrorCode : 11001
NativeErrorCode : 11001
TargetSite :
Name : InternalGetHostByName
DeclaringType : System.Net.Dns
MemberType : Method
Module : System.Net.NameResolution.dll
StackTrace :
at System.Net.Dns.InternalGetHostByName(String hostName)
at System.Net.Dns.GetHostEntry(String hostNameOrAddress)
at Microsoft.PowerShell.Commands.TestConnectionCommand.InitProcessPing(String targetNameOrAddress, String& resolvedTargetName, IPAddress& targetAddress)
Source : System.Net.NameResolution
HResult : -2147467259
HResult : -2146233079
TargetObject : fakesystem
CategoryInfo : ResourceUnavailable: (fakesystem:String) [Test-Connection], PingException
FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand
InvocationInfo :
MyCommand : Test-Connection
ScriptLineNumber : 1
OffsetInLine : 1
HistoryId : 12
Line : Test-Connection "fakesystem" -Count 1
PositionMessage : At line:1 char:1
+ Test-Connection "fakesystem" -Count 1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
InvocationName : Test-Connection
CommandOrigin : Internal
ScriptStackTrace : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo :
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!
More from Adam Bertram
advertisment
Petri Newsletters
Whether it’s Security or Cloud Computing, we have the know-how for you. Sign up for our newsletters here.
advertisment
More in PowerShell
Microsoft’s New PowerShell Crescendo Tool Facilitates Native Command-Line Wraps
Mar 21, 2022 | Rabia Noureen
Most popular on petri
Log in to save content to your profile.
Article saved!
Access saved content from your profile page. View Saved
Join The Conversation
Create a free account today to participate in forum conversations, comment on posts and more.
Copyright ©2019 BWW Media Group