Быстрее тестируйте сетевые порты с помощью PowerShell

В Windows 8.1 Test-NetConnection командлет полезен для проверки состояния сетевого порта в удаленной системе. Однако иногда это может быть неоправданно медленно. Я хотел бы знать, есть ли какие-то параметры, которые я мог бы настроить, или альтернативная команда PowerShell, которую я мог бы использовать, чтобы сделать этот процесс быстрее.

Test-NetConnection может занять около 10 секунд, чтобы вернуть результаты, если удаленная система не отвечает. Всякий раз, когда порт указан, он выполняет два теста соединения, которые занимают около 5 секунд каждый тайм-аут. Первый тест является базовой Эхо-проверкой ICMP. Это время ожидания истекает, если система находится в автономном режиме или если она (или любая промежуточная инфраструктура) настроена на блокировку или не отвечает на эхо-запросы ICMP.Второй тест-это фактическая проверка указанного порта. Это время ожидания истекает, если система находится в автономном режиме, или если есть брандмауэр вдоль пути, который блокирует порт.

в моем текущем случае использования удаленная система находится всего в двух прыжках от надежного Gigabit Ethernet соединение. Таким образом, пятисекундный тайм - аут для любого запроса довольно чрезмерен-я, вероятно, все еще могу получить надежные результаты с таймаутом 30 мс или меньше! Кроме того, система, как известно, не реагирует на ICMP echo, даже если она может быть в сети и иметь все другие доступные службы. Поэтому было бы здорово, если бы я мог обойтись без теста ICMP echo полностью и уменьшить тайм-аут для теста TCP-подключения, чтобы ускорить мои сценарии, которые используют Test-NetConnection для этого цель.

тут Test-NetConnection есть варианты, чтобы изменить такое поведение? (Я прочитал подробный файл справки, и ответ, похоже, нет, но я был бы счастлив сказать, что я что - то пропустил.) Или есть другой способ использовать PowerShell для выполнения тех же проверок, но быстрее?

по разным причинам я предпочитаю, чтобы мои скрипты были ограничены использованием функциональности, встроенной в операционную систему, где это возможно. Предположим, что среда является новой сборкой Windows 8.1, с применяются все соответствующие обновления Windows, а также средства сторонних производителей.

19
задан Iszi
26.03.2023 6:05 Количество просмотров материала 2710
Распечатать страницу

4 ответа

вы можете использовать это для проверки соединения -взято с Репозиторий Кода PowerShell (автор 'BSonPosh'):

"Test-Port создает TCP соединение с указанным портом. По умолчанию это соединяется с портом 135 с таймаутом 3secs."

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}

вы можете перейти на эту страницу репозитория для последующих действий (этот ответ уже слишком много для копирования)

3
отвечен Jan Doggen 2023-03-27 13:53

очень простой (тайм-аут 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
отвечен js2010 2023-03-27 16:10

еще более быстрый способ, могут быть :

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

значение interessting "Connected"

edit: еще одна причина: Test-NetConnection работает только с Powershell v5 (если я правильно помню), в то время как это решение работает с v2:)

1
отвечен laurent 2023-03-27 18:27

Я искал супер быстрый способ пинг много IP-адресов и наткнулся на этот вопрос (среди других).

в конце концов, я нашел скрипт, который легко интегрировать в то, что я хотел сделать. Парень называет это Быстрый Пинг Развертки Асинхронный.

даже будучи силовой оболочкой n00b, я смог передать ее выход, а затем изменить ее выход, чтобы включить только то, что я хотел. Я наткнулся на другие скрипты, но не смог расшифровать их скрипты, чтобы изменить их для моих целей.

Я не уверен, какая версия Power Shell для этого требуется, но она работает на v4 и v5.

Я видел большинство Powershell IP scanner, пинг подметания скрипты но ни один из них не использует метод PingASync."Проблема" с синхронные сценарии-это то, что они должны ждать ответа узла или время ожидания истекло, прежде чем перейти к следующему адресу.Используя этот подход может принимать s

function Global:Ping-IPRange {
    <#
    .SYNOPSIS
        Sends ICMP echo request packets to a range of IPv4 addresses between two given addresses.

    .DESCRIPTION
        This function lets you sends ICMP echo request packets ("pings") to 
        a range of IPv4 addresses using an asynchronous method.

        Therefore this technique is very fast but comes with a warning.
        Ping sweeping a large subnet or network with many swithes may result in 
        a peak of broadcast traffic.
        Use the -Interval parameter to adjust the time between each ping request.
        For example, an interval of 60 milliseconds is suitable for wireless networks.
        The RawOutput parameter switches the output to an unformated
        [System.Net.NetworkInformation.PingReply[]].

    .INPUTS
        None
        You cannot pipe input to this funcion.

    .OUTPUTS
        The function only returns output from successful pings.

        Type: System.Net.NetworkInformation.PingReply

        The RawOutput parameter switches the output to an unformated
        [System.Net.NetworkInformation.PingReply[]].

    .NOTES
        Author  : G.A.F.F. Jakobs
        Created : August 30, 2014
        Version : 6

    .EXAMPLE
        Ping-IPRange -StartAddress 192.168.1.1 -EndAddress 192.168.1.254 -Interval 20

        IPAddress                                 Bytes                     Ttl           ResponseTime
        ---------                                 -----                     ---           ------------
        192.168.1.41                                 32                      64                    371
        192.168.1.57                                 32                     128                      0
        192.168.1.64                                 32                     128                      1
        192.168.1.63                                 32                      64                     88
        192.168.1.254                                32                      64                      0

        In this example all the ip addresses between 192.168.1.1 and 192.168.1.254 are pinged using 
        a 20 millisecond interval between each request.
        All the addresses that reply the ping request are listed.

    .LINK
        http://gallery.technet.microsoft.com/Fast-asynchronous-ping-IP-d0a5cf0e

    #>
    [CmdletBinding(ConfirmImpact='Low')]
    Param(
        [parameter(Mandatory = $true, Position = 0)]
        [System.Net.IPAddress]$StartAddress,
        [parameter(Mandatory = $true, Position = 1)]
        [System.Net.IPAddress]$EndAddress,
        [int]$Interval = 30,
        [Switch]$RawOutput = $false
    )

    $timeout = 2000

    function New-Range ($start, $end) {

        [byte[]]$BySt = $start.GetAddressBytes()
        [Array]::Reverse($BySt)
        [byte[]]$ByEn = $end.GetAddressBytes()
        [Array]::Reverse($ByEn)
        $i1 = [System.BitConverter]::ToUInt32($BySt,0)
        $i2 = [System.BitConverter]::ToUInt32($ByEn,0)
        for($x = $i1;$x -le $i2;$x++){
            $ip = ([System.Net.IPAddress]$x).GetAddressBytes()
            [Array]::Reverse($ip)
            [System.Net.IPAddress]::Parse($($ip -join '.'))
        }
    }

    $IPrange = New-Range $StartAddress $EndAddress

    $IpTotal = $IPrange.Count

    Get-Event -SourceIdentifier "ID-Ping*" | Remove-Event
    Get-EventSubscriber -SourceIdentifier "ID-Ping*" | Unregister-Event

    $IPrange | foreach{

        [string]$VarName = "Ping_" + $_.Address

        New-Variable -Name $VarName -Value (New-Object System.Net.NetworkInformation.Ping)

        Register-ObjectEvent -InputObject (Get-Variable $VarName -ValueOnly) -EventName PingCompleted -SourceIdentifier "ID-$VarName"

        (Get-Variable $VarName -ValueOnly).SendAsync($_,$timeout,$VarName)

        Remove-Variable $VarName

        try{

            $pending = (Get-Event -SourceIdentifier "ID-Ping*").Count

        }catch [System.InvalidOperationException]{}

        $index = [array]::indexof($IPrange,$_)

        Write-Progress -Activity "Sending ping to" -Id 1 -status $_.IPAddressToString -PercentComplete (($index / $IpTotal)  * 100)

        Write-Progress -Activity "ICMP requests pending" -Id 2 -ParentId 1 -Status ($index - $pending) -PercentComplete (($index - $pending)/$IpTotal * 100)

        Start-Sleep -Milliseconds $Interval
    }

    Write-Progress -Activity "Done sending ping requests" -Id 1 -Status 'Waiting' -PercentComplete 100 

    While($pending -lt $IpTotal){

        Wait-Event -SourceIdentifier "ID-Ping*" | Out-Null

        Start-Sleep -Milliseconds 10

        $pending = (Get-Event -SourceIdentifier "ID-Ping*").Count

        Write-Progress -Activity "ICMP requests pending" -Id 2 -ParentId 1 -Status ($IpTotal - $pending) -PercentComplete (($IpTotal - $pending)/$IpTotal * 100)
    }

    if($RawOutput){

        $Reply = Get-Event -SourceIdentifier "ID-Ping*" | ForEach { 
            If($_.SourceEventArgs.Reply.Status -eq "Success"){
                $_.SourceEventArgs.Reply
            }
            Unregister-Event $_.SourceIdentifier
            Remove-Event $_.SourceIdentifier
        }

    }else{

        $Reply = Get-Event -SourceIdentifier "ID-Ping*" | ForEach { 
            If($_.SourceEventArgs.Reply.Status -eq "Success"){
                $_.SourceEventArgs.Reply | select @{
                      Name="IPAddress"   ; Expression={$_.Address}},
                    @{Name="Bytes"       ; Expression={$_.Buffer.Length}},
                    @{Name="Ttl"         ; Expression={$_.Options.Ttl}},
                    @{Name="ResponseTime"; Expression={$_.RoundtripTime}}
            }
            Unregister-Event $_.SourceIdentifier
            Remove-Event $_.SourceIdentifier
        }
    }
    if($Reply -eq $Null){
        Write-Verbose "Ping-IPrange : No ip address responded" -Verbose
    }

    return $Reply
}
0
отвечен YetAnotherRandomUser 2023-03-27 20:44

Постоянная ссылка на данную страницу: [ Скопировать ссылку | Сгенерировать QR-код ]

Ваш ответ

Опубликуйте как Гость или авторизуйтесь

Имя
Вверх