在 Windows 8.1 中,Test-NetConnection
cmdlet 可用于检查远程系统上的网络端口状态。但是,有时它可能会不必要地变慢。我想知道是否有一些我可以调整的选项,或者我可以使用其他 PowerShell 命令来加快此过程。
Test-NetConnection
如果远程系统没有响应,则可能需要大约 10 秒钟才能返回结果。每当指定一个端口时,它都会运行两个连接测试,每个测试大约需要 5 秒钟才能超时。第一个测试是基本的 ICMP 回显检查。如果系统处于离线状态,或者它(或任何中间基础设施)配置为阻止或不响应 ICMP 回显请求,则该测试将超时。第二个测试是对指定端口的实际检查。如果系统处于离线状态,或者路径上有防火墙阻止端口,则该测试将超时。
在我当前的用例中,远程系统在可靠的千兆以太网连接上仅相隔两跳。因此,任何请求的五秒超时都太过分了 - 我可能仍然可以在 30 毫秒或更短的超时时间内获得可靠的结果!此外,即使系统可能在线并且所有其他服务都可用,它也对 ICMP 回显没有响应。因此,如果我可以完全不使用 ICMP 回显测试并减少 TCP 连接测试的超时时间,以加快用于Test-NetConnection
此目的的脚本的速度,那就太好了。
是否Test-NetConnection
有选项可以改变这些行为?(我已经阅读了详细的帮助文件,答案似乎是否定的 - 但我很高兴有人告诉我我错过了一些东西。)或者有没有另一种方法可以使用 PowerShell 来运行相同的检查,但速度更快?
出于各种原因,我倾向于尽可能将脚本限制为使用操作系统内置的功能。假设环境是 Windows 8.1 的全新版本,已应用所有适当的 Windows 更新,并且第三方工具不是一种选择。
答案1
非常基础(超时 100 毫秒):
function testport ($hostname='yahoo.com',$port=80,$timeout=100) {
$requestCallback = $state = $null
$client = New-Object System.Net.Sockets.TcpClient
$beginConnect = $client.BeginConnect($hostname,$port,$requestCallback,$state)
Start-Sleep -milli $timeOut
if ($client.Connected) { $open = $true } else { $open = $false }
$client.Close()
[pscustomobject]@{hostname=$hostname;port=$port;open=$open}
}
testport
hostname port open
-------- ---- ----
yahoo.com 80 True
答案2
我见过的测试 TCP 端口的最短方法是:
(New-Object System.Net.Sockets.TcpClient).ConnectAsync("google.com", 80).Wait(100)
或者
[System.Net.Sockets.TcpClient]::new().ConnectAsync("google.com", 80).Wait(100)
等待时间以毫秒为单位。这是一种与旧版 PowerShell 2.0 兼容的方法。
答案3
您可以使用它来测试连接 -摘自PowerShell 代码存储库(作者 'BSonPosh'):
“Test-Port 创建到指定端口的 TCP 连接。默认情况下,它连接到端口 135,超时时间为 3 秒。”
Param([string]$srv,$port=135,$timeout=3000,[switch]$verbose)
# Test-Port.ps1
# Does a TCP connection on specified port (135 by default)
$ErrorActionPreference = "SilentlyContinue"
# Create TCP Client
$tcpclient = new-Object system.Net.Sockets.TcpClient
# Tell TCP Client to connect to machine on Port
$iar = $tcpclient.BeginConnect($srv,$port,$null,$null)
# Set the wait time
$wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false)
# Check to see if the connection is done
if(!$wait)
{
# Close the connection and report timeout
$tcpclient.Close()
if($verbose){Write-Host "Connection Timeout"}
Return $false
}
else
{
# Close the connection and report the error if there is one
$error.Clear()
$tcpclient.EndConnect($iar) | out-Null
if(!$?){if($verbose){write-host $error[0]};$failed = $true}
$tcpclient.Close()
}
# Return $true if connection Establish else $False
if($failed){return $false}else{return $true}
您可以前往该存储库页面进行后续操作(这个答案已经是太多的复制工作了)
答案4
更快捷的方法可能是:
param($ip,$port)
New-Object System.Net.Sockets.TCPClient -ArgumentList $ip, $port
结果是:
Client : System.Net.Sockets.Socket
Available : 0
Connected : True
ExclusiveAddressUse : False
ReceiveBufferSize : 65536
SendBufferSize : 65536
ReceiveTimeout : 0
SendTimeout : 0
LingerState : System.Net.Sockets.LingerOption
NoDelay : False
有趣的值是“已连接”
编辑:还有一个原因:Test-NetConnection 仅适用于 Powershell v5(如果我没记错的话),而此解决方案适用于 v2:)