In newer versions of PowerShell, the -Quiet
parameter on Test-Connection
does seem to always return either True
or False
. It didn't seem to work consistently on older versions, but either I'm doing something differently now or they've improved it:
$Ping = Test-Connection -ComputerName $ComputerName -Count 1 -Quiet
I haven't tested it recently when the network is simply unavailable, however.
Older answer:
Test-Connection
doesn't respond well when DNS doesn't respond with an address or when the network is unavailable. That is, if the cmdlet decides it can't send the ping at all, it errors in unpleasant ways that are difficult to trap or ignore. Test-Connection
is only useful, then, when you can guarantee that DNS will resolve the name to an address, and that the network will always be present.
I tend to use CIM Pings (Powershell v3+):
$Ping2 = Get-CimInstance -ClassName Win32_PingStatus -Filter "Address='$ComputerName' AND Timeout=1000";
Or WMI pings (Powershell v1 or v2):
$Ping = Get-WmiObject -Class Win32_PingStatus -Filter "Address='$ComputerName' AND Timeout=1000";
Either of which are basically the same, but return slightly different formats for things. Note that Get-WmiObject
is not available at all beginning in Powershell v6 because Get-CimInstance
was designed to supersede it.
The main disadvantage here is that you have to resolve the status code yourself:
$StatusCodes = @{
[uint32]0 = 'Success';
[uint32]11001 = 'Buffer Too Small';
[uint32]11002 = 'Destination Net Unreachable';
[uint32]11003 = 'Destination Host Unreachable';
[uint32]11004 = 'Destination Protocol Unreachable';
[uint32]11005 = 'Destination Port Unreachable';
[uint32]11006 = 'No Resources';
[uint32]11007 = 'Bad Option';
[uint32]11008 = 'Hardware Error';
[uint32]11009 = 'Packet Too Big';
[uint32]11010 = 'Request Timed Out';
[uint32]11011 = 'Bad Request';
[uint32]11012 = 'Bad Route';
[uint32]11013 = 'TimeToLive Expired Transit';
[uint32]11014 = 'TimeToLive Expired Reassembly';
[uint32]11015 = 'Parameter Problem';
[uint32]11016 = 'Source Quench';
[uint32]11017 = 'Option Too Big';
[uint32]11018 = 'Bad Destination';
[uint32]11032 = 'Negotiating IPSEC';
[uint32]11050 = 'General Failure'
};
$StatusCodes[$Ping.StatusCode];
$StatusCodes[$Ping2.StatusCode];
Alternately, I've used .Net Pings like @BenH described, too, which does a lot of that work for you. There was a reason I stopped using them in favor of WMI and CIM, but I can no longer remember what that reason was.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…