Teste as portas de rede mais rapidamente com o PowerShell

Teste as portas de rede mais rapidamente com o PowerShell

No Windows 8.1, o Test-NetConnectioncmdlet é útil para verificar o estado de uma porta de rede em um sistema remoto. No entanto, às vezes pode ser desnecessariamente lento. Gostaria de saber se há algumas opções que eu possa ajustar ou um comando alternativo do PowerShell que eu possa usar para tornar esse processo mais rápido.

Test-NetConnectionpode levar cerca de 10 segundos para retornar resultados se um sistema remoto não estiver respondendo. Sempre que uma porta é especificada, ele executa dois testes de conexão que levam cerca de 5 segundos cada para atingir o tempo limite. O primeiro teste é uma verificação básica de eco ICMP. Isso atingirá o tempo limite se o sistema estiver off-line ou se ele (ou qualquer infraestrutura interveniente) estiver configurado para bloquear ou não responder às solicitações de eco ICMP. O segundo teste é a verificação real na porta especificada. O tempo limite será excedido se o sistema estiver offline ou se houver um firewall no caminho que esteja bloqueando a porta.

No meu caso de uso atual, o sistema remoto está a apenas dois saltos de distância em uma conexão Gigabit Ethernet confiável. Portanto, um tempo limite de cinco segundos para qualquer solicitação é bastante excessivo - provavelmente ainda conseguirei resultados confiáveis ​​com um tempo limite de 30 ms ou menos! Além disso, sabe-se que o sistema não responde ao eco ICMP, mesmo que esteja online e tenha todos os outros serviços disponíveis. Portanto, seria ótimo se eu pudesse dispensar totalmente o teste de eco ICMP e reduzir o tempo limite do teste de conexão TCP, a fim de agilizar meus scripts que utilizo Test-NetConnectionpara esse fim.

Tem Test-NetConnectionopções para mudar esses comportamentos? (Li o arquivo de ajuda detalhado e a resposta parece ser não - mas ficaria feliz em saber que há algo que perdi.) Ou há outra maneira de usar o PowerShell para executar as mesmas verificações, mas mais rápido?

Por vários motivos, prefiro manter meus scripts limitados ao uso de funcionalidades integradas ao sistema operacional sempre que possível. Suponha que o ambiente seja uma versão nova do Windows 8.1, com todas as atualizações apropriadas do Windows aplicadas e que ferramentas de terceiros não sejam uma opção.

Responder1

Muito básico (tempo limite 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

Responder2

A maneira mais curta de testar uma porta TCP que vi é:

(New-Object System.Net.Sockets.TcpClient).ConnectAsync("google.com", 80).Wait(100)

ou

[System.Net.Sockets.TcpClient]::new().ConnectAsync("google.com", 80).Wait(100) 

Espere está em ms. Este é um método antigo compatível com o PowerShell 2.0.

Responder3

Você pode usar isso para testar a conexão -Retirado doRepositório de código do PowerShell(autor 'BSonPosh'):

"Test-Port cria uma conexão TCP para a porta especificada. Por padrão, ele se conecta à porta 135 com um tempo limite 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}

Você pode ir para a página do repositório para acompanhamento (esta resposta já é um trabalho de cópia demais)

Responder4

Uma maneira ainda mais rápida poderia ser:

param($ip,$port)
New-Object System.Net.Sockets.TCPClient -ArgumentList $ip, $port

O resultado seria:

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

O valor interessante é "Conectado"

editar: mais um motivo: Test-NetConnection só funciona no Powershell v5 (se bem me lembro), enquanto esta solução funciona na v2 :)

informação relacionada