使用HostName更好地测试连接性能 [英] Test-Connection Performance Better with HostName
问题描述
使用IP地址运行Test-Connection
所花费的时间比使用服务器的主机名运行相同的命令要长得多.
但是;如果我添加-quiet
参数,则性能大致相同(如您所料,IP速度要快一小部分).
使用Measure-Command
不会显示此异常;大概有些奇怪的输出没有显示.
下面的代码更准确地反映了所看到的异常:
$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
同事们在他们的机器上重现了同样的问题.
问题:有人知道这可能是什么原因引起的吗? 即我怀疑这是一个错误(并且已经这样报告了),但这意味着在某种程度上聪明的事情使PowerShell可能根据输出是否显示/导致类似量子的作用而有所不同;因此,它不仅运行命令中给出的命令,而且还在幕后进行一些(反)优化.
我的环境
操作系统: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错误
我只是在运行Test-Connection
时使用和不使用Quiet
开关参数进行了Wireshark跟踪,为Computername
参数提供了IPv4地址. /p>
当省略Quiet
开关时,PowerShell似乎不会向目标计算机发送1个,而是向目标计算机发送6个NetBIOS名称查询,之后它会返回格式化的输出.
如果我 assign 从Test-Connection
的输出,它会立即返回,但是一旦我将其通过管道传输到Format-Table
,它就会挂起并再次发送NBSTAT查询
根本原因实际上不是Test-Connection
cmdlet本身,而是格式化的输出.属性(IPV4Address
)之一是ScriptProperty
,具有以下定义:
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;}
因此,当显示输出时,将调用[System.Net.Dns]::GetHostEntry(10.0.0.101)
来计算IPV4Address
-这就是导致等待时间的原因
如果您不关心IP地址的模拟分辨率,请使用Select-Object
阻止IPV4Address
的计算和输出:
Test-Connection -ComputerName 10.0.0.101 -Count 1 | Select Address,StatusCode
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
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
这篇关于使用HostName更好地测试连接性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!