
В Windows 8.1 Test-NetConnection
командлет полезен для проверки состояния сетевого порта на удаленной системе. Однако иногда он может быть неоправданно медленным. Я хотел бы узнать, есть ли какие-то параметры, которые я мог бы настроить, или альтернативная команда PowerShell, которую я мог бы использовать, чтобы ускорить этот процесс.
Test-NetConnection
может потребоваться около 10 секунд для возврата результатов, если удаленная система не отвечает. Всякий раз, когда указан порт, он запускает два теста соединения, каждый из которых требует около 5 секунд для тайм-аута. Первый тест — это базовая проверка эха ICMP. Он будет заблокирован, если система находится в автономном режиме или если она (или любая промежуточная инфраструктура) настроена на блокировку или отсутствие ответа на запросы эха ICMP. Второй тест — это фактическая проверка указанного порта. Он будет заблокирован, если система находится в автономном режиме или если на пути есть брандмауэр, блокирующий порт.
В моем текущем варианте использования удаленная система находится всего в двух шагах от надежного соединения Gigabit Ethernet. Таким образом, пятисекундный тайм-аут для любого запроса является довольно чрезмерным — я, вероятно, все еще мог бы получить надежные результаты с тайм-аутом 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
Интересное значение — «Подключено».
edit: еще одна причина: Test-NetConnection работает только из Powershell v5 (если я правильно помню), тогда как это решение работает из v2 :)