blog.powershell.no

On Windows PowerShell and other admin-related topics

Test-Connection error handling gotcha in PowerShell 2.0

The Test-Connection cmdlet in Windows PowerShell was introduced in version 2.0, with the purpose of sending ICMP echo request packets ("pings") to one or more computers as stated in the cmdlet`s documentation.

The cmdlet has a number of useful parameters, for example –Count to specify the number of request packets to send (the default is 4) and –Quiet to suppress errors and make the cmdlet return either true or false:

image

The –Quiet parameter is very useful when writing a script or function where you only want to perform an operation if the target computer responds to ping requests. A basic example of using this technique:

if (Test-Connection -ComputerName doesntexist -Count 1) {            
#Proceed with script operation            
}

A few weeks ago I stumbled upon a problem when trying to use a try/catch block in a PowerShell function. What I wanted to do was to catch a ping exception when using Test-Connection. Here is the code I was running:

try            
{            
Test-Connection -ComputerName doesntexist -Count 1 -ErrorAction stop            
}            
            
catch [System.Net.NetworkInformation.PingException]            
{            
'Catched PingException'            
}            
            
catch            
{            
'General catch'            
}

To my surprise, the PingException wasn`t catched:

image

I then tried setting up a new System.Net.NetworkInformation.Ping object, to see if the PingException catch worked when using the object`s Send-method:

image

This worked, so the problem seemed to be related to the Test-Connection cmdlet.

Earlier this week I attended the PowerShell Deep Dive conference in Frankfurt, which was part of The Experts Conference 2011. In the evening the organizers set up a Script Club, where the attendees could explore various PowerShell features together, as well as getting assistance in problem solving. Together with PowerShell MVP Jeff Hicks I sat down and looked into the issue with Test-Connection. As we couldn`t figure out why the PingException catch block didn`t work as expected, we got assistance from a PowerShell team member who was attending the conference, Jason Shirk.

Jason explained to us that there is a bug with Test-Connection`s ErrorAction parameter in PowerShell 2.0, which is resolved in PowerShell 3.0 (not in CTP 1). This means my example above will work in the next version of PowerShell. Until then, Jason showed us a workaround for PowerShell 2.0:

try            
{            
Test-Connection -ComputerName doesntexist -Count 1 -ErrorAction stop            
}            
            
catch [System.Management.Automation.ActionPreferenceStopException]            
{            
try {            
throw $_.exception            
}            
            
catch [System.Net.NetworkInformation.PingException] {            
'Catched PingException'            
}            
            
catch {            
'General catch'            
}            
}

The workaround is to go into the inner exception of ActionPreferenceStopException to perform the PingException catch.

Many thanks to Jason Shirk for the assistance. For others, I would highly recommend to attend the next PowerShell Deep Dive. In addition to great presentations, you also get to network with other PowerShell enthusiasts, as well as attending the very fun and exciting Script Club in the evenings.

 

Related resources

October 23, 2011 - Posted by | Windows PowerShell | , , ,

1 Comment »

  1. caught, not catched

    Comment by Joe B from Michigan, USA | March 29, 2012 | Reply


Leave a comment