
En Windows 8.1, el Test-NetConnection
cmdlet es útil para comprobar el estado de un puerto de red en un sistema remoto. Sin embargo, a veces puede resultar innecesariamente lento. Me gustaría saber si hay algunas opciones que pueda modificar, o un comando de PowerShell alternativo que pueda usar, para acelerar este proceso.
Test-NetConnection
Puede tardar unos 10 segundos en devolver resultados si un sistema remoto no responde. Cada vez que se especifica un puerto, ejecuta dos pruebas de conexión que tardan unos 5 segundos cada una en expirar. La primera prueba es una verificación de eco ICMP básica. Esto expirará si el sistema está fuera de línea o si (o cualquier infraestructura intermedia) está configurado para bloquear o no responder a las solicitudes de eco ICMP. La segunda prueba es la verificación real con el puerto especificado. Esto expirará si el sistema está fuera de línea o si hay un firewall a lo largo de la ruta que está bloqueando el puerto.
En mi caso de uso actual, el sistema remoto está a solo dos saltos de distancia con una conexión Gigabit Ethernet confiable. Por lo tanto, un tiempo de espera de cinco segundos para cualquier solicitud es bastante excesivo: ¡probablemente aún podría obtener resultados confiables con un tiempo de espera de 30 ms o menos! Además, se sabe que el sistema no responde al eco ICMP aunque esté en línea y tenga todos los demás servicios disponibles. Por lo tanto, sería fantástico si pudiera prescindir por completo de la prueba de eco ICMP y reducir el tiempo de espera de la prueba de conexión TCP para acelerar los scripts que uso Test-NetConnection
para este propósito.
¿ Test-NetConnection
Tiene opciones para cambiar estos comportamientos? (Leí el archivo de ayuda detallado y la respuesta parece ser no, pero me encantaría que me dijeran que me he perdido algo). ¿O hay otra manera de usar PowerShell para ejecutar las mismas comprobaciones? ¿pero más rápido?
Por varias razones, prefiero mantener mis scripts limitados al uso de funciones integradas en el sistema operativo siempre que sea posible. Supongamos que el entorno es una versión nueva de Windows 8.1, con todas las actualizaciones de Windows apropiadas aplicadas y que las herramientas de terceros no son una opción.
Respuesta1
Muy básico (tiempo de espera de 100 ms):
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
Respuesta2
La forma más corta de probar un puerto TCP que he visto es:
(New-Object System.Net.Sockets.TcpClient).ConnectAsync("google.com", 80).Wait(100)
o
[System.Net.Sockets.TcpClient]::new().ConnectAsync("google.com", 80).Wait(100)
La espera está en ms. Este es un método antiguo compatible con PowerShell 2.0.
Respuesta3
Puedes usar esto para probar la conexión.Tomado de laRepositorio de códigos de PowerShell(autor 'BSonPosh'):
"Test-Port crea una conexión TCP al puerto especificado. De forma predeterminada, se conecta al puerto 135 con un tiempo de espera de 3 segundos".
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}
Puede ir a esa página del repositorio para realizar seguimientos (esta respuesta ya es demasiado trabajo de copia)
Respuesta4
Una forma aún más rápida podría ser:
param($ip,$port)
New-Object System.Net.Sockets.TCPClient -ArgumentList $ip, $port
El resultado sería:
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
El valor interesante es "Conectado"
editar: una razón más: Test-NetConnection solo funciona desde Powershell v5 (si no recuerdo mal), mientras que esta solución funciona desde v2 :)