Test-Connection Performance Better with HostName

2020-07-22 10:22发布

问题:

Running Test-Connection with an IP address takes considerably longer than running the same command with the server's hostname.

However; if I add the -quiet parameter then performance is roughly the same (IP is a fraction faster, as you may expect).

Using Measure-Command this anomaly does not show up; presumably some quirk of the output not being displayed.

The below code more accurately reflects the anomaly seen:

$begin=(get-date).ticks;test-connection '123.45.67.89'; $a=((get-date).ticks - $begin)
$begin=(get-date).ticks;test-connection 'MyHostName'; $b=((get-date).ticks - $begin)
$a-$b

Colleagues have reproduced the same issue on their machines.

Question: is anyone aware of what may cause this? i.e. I suspect it's a bug (and have reported it as such), but it implies that there's something clever going on where PowerShell may work differently depending on whether output is to be displayed or not / causing a quantum-like effect; so it's not just running the commands given in order, but is doing some (de)optimisation under the covers.

My Environment

OS: MS Windows 7 Pro SP1

$PSVersionInfo:

Name                           Value                                  
----                           -----                                                                                                                                                  
PSVersion                      4.0                                     
WSManStackVersion              3.0                                     
SerializationVersion           1.1.0.1                                 
CLRVersion                     4.0.30319.18444                         
BuildVersion                   6.3.9600.16406                          
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0}                    
PSRemotingProtocolVersion      2.2

MS Connect Bug

https://connect.microsoft.com/PowerShell/feedbackdetail/view/1578010/test-connection-performance-with-ip-and-output

回答1:

I just did a Wireshark trace while running Test-Connection with and without the Quiet switch parameter, supplying an IPv4 address for the Computername parameter.

When the Quiet switch is omitted, PowerShell seems to send not 1, but 6 NetBIOS Name Queries to the target machine, after which it returns the formatted output.

If I assign the output from Test-Connection, it returns right away, but as soon as I pipe it to Format-Table, it hangs and sends the NBSTAT queries again


The root cause is actually not the Test-Connection cmdlet itself, but the formatted output. One of the properties (IPV4Address) is a ScriptProperty and has the following definition:

PS C:\> $ping = Test-Connection -ComputerName 10.0.0.101 -Count 1
PS C:\> Get-Member -InputObject $ping -Name IPV4Address | Select-Object -ExpandProperty Definition
System.Object IPV4Address {get=$iphost = [System.Net.Dns]::GetHostEntry($this.address)
                    $iphost.AddressList | ?{ $_.AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetwork } | select -first 1;}

So, when the output shown, [System.Net.Dns]::GetHostEntry(10.0.0.101) is called to calculate IPV4Address - this is what causes the waiting time


If you don't care about the moot resolution of the IP address, use Select-Object to prevent the calculation and output of IPV4Address:

Test-Connection -ComputerName 10.0.0.101 -Count 1 | Select Address,StatusCode