Как измерить время соединения Tcp и Icmp на удаленной машине: как Ping - PullRequest
0 голосов
/ 28 ноября 2018

Мне нужно одновременно измерять время соединения tcp и icmp на удаленной машине, когда другая машина напрягает его загрузкой и выгрузкой.Знаете ли вы хороший метод для тестирования каждую секунду?

1 Ответ

0 голосов
/ 29 ноября 2018

Я переписываю Пинг (в PS)

вывод

DateTime              IP       Status  hasChanged      ICMP  ICMP-Ttl Tcp-53
--------              --       ------  ----------      ----  -------- ------
2018-11-29 12:13:44   8.8.8.8  50%           True  TimedOut               35
2018-11-29 12:13:46   8.8.8.8  100%          True        20  116          20
2018-11-29 12:13:48   8.8.8.8  100%         False        18  116          18

код

function Ping {
    <#
        .SYNOPSIS
            Implementation PS du ping + tcp-Ping
        .DESCRIPTION
            retourne les temps de reponce ICMP (port 0) et TCP (port 1-65535)
        .PARAMETER DestNode
            HostName ou IP a tester,
            pour le HostName une resolution DNS est faite a chaque boucle
        .PARAMETER ports
            Liste des ports TCP-IP a tester, le port 0 pour l'ICMP
        .PARAMETER timeout
            TimeOut des test individuel
        .PARAMETER loop
            nombre de boucle a effectuer, par defaut Infini
        .PARAMETER Intervale
            intervale entre chaque series de test
        .PARAMETER ComputerName
            permet de faire ce Ping en total remote,
            si ComputerName est fournis, joignable et different de localhost alors c'est lui qui executera ce code et retourne le resultat
            Requiere "Enable-PSRemoting -force"
        .EXAMPLE
            Ping sur ICMP + TCP:53,80,666 timeout 80ms (par test)
            Ping 8.8.8.8 -ports 0,53,80,666 -timeout 80 | ft
        .EXAMPLE
            3 ping en remote depuis le serveur vdiv05 sur ICMP,3389,6516 le tous dans une jolie fenetre
            ping 10.48.50.27 0,3389,6516 -ComputerName vdiv05 -count 3 | Out-GridView
        .NOTES
            Alban LOPEZ 2018
            alban.lopez @t gmail.com
        #>
    Param(
        [string]$DestNode = 'vps.opt2', 
        [ValidateRange(0, 65535)]
        [int[]]$ports = @(0, 22, 135), 
        [ValidateRange(0, 2000)]
        [int]$timeout = 200,
        [alias("count")][int32]$loop = [int32]::MaxValue, # 68 annees !
        [ValidateSet(250, 500, 1000, 2000, 4000, 10000)]
        [int]$Intervale = 2000,
        $size = 1Kb,
        $ComputerName = $null
    )
    begin {
        if ($computerName -and $computerName -notmatch "^(\.|localhost|127.0.0.1)$|^$($env:computername)" -and (Test-TcpPort -DestNodes $computerName -ConfirmIfDown)) {
            $pingScriptBlock = Include-ToScriptblock -functions 'write-logStep', 'write-color', 'Write-Host', 'ping', 'Test-TcpPort', 'Include-ToScriptblock'
        } else {
            $ComputerName = $null
            $ObjPing = [pscustomobject]@{
                DateTime   = $null
                IP         = $null
                Status     = $null
                hasChanged = $null
            }
            $ObjPings = $test = @()
            if (!$ports) {$ports = @(0)}
            $Ports | ForEach-Object {
                if ($_) {
                    # TCP
                    $ObjPing | Add-Member -MemberType NoteProperty -Name "Tcp-$_" -Value $null
                    $test += "Tcp-$_"
                }
                else {
                    # ICMP
                    $ping = new-object System.Net.NetworkInformation.Ping
                    $ObjPing | Add-Member -MemberType NoteProperty -Name ICMP -Value $null

                    $ObjPing | Add-Member -MemberType NoteProperty -Name 'ICMP-Ttl' -Value $null
                    # $ObjPing | Add-Member -MemberType NoteProperty -Name 'ICMP-Size' -Value $size
                    $buffer = [byte[]](1..$size | ForEach-Object {get-random -Minimum 20 -Maximum 255})
                    $test += "ICMP ($size Octs)"
                }
            }
            # Write-LogStep -prefixe 'L.%Line% Ping' "Ping [$DestNode] ", ($test -join(' + ')) ok
        }
    }
    process {
        if(!$ComputerName){
            While ($loop--) {
                $ms = (Measure-Command {
                    try {
                        $ObjPing.DateTime = (get-date)
                        $ObjPing.status = $ObjPing.haschanged = $null
                        $ObjPing.IP = [string][System.Net.Dns]::GetHostAddresses($DestNode).IPAddressToString
                        #Write-LogStep -prefixe 'L.%Line% Ping' "Ping $DestNode", $ObjPing.IP wait
                            foreach ($port in $ports) {
                                if ($port) {
                                    # TCP
                                    $ObjPing."Tcp-$port" = $iar = $null
                                    try {
                                        $tcpclient = new-Object system.Net.Sockets.TcpClient # Create TCP Client
                                        $iar = $tcpclient.BeginConnect($ObjPing.IP, $port, $null, $null) # Tell TCP Client to connect to machine on Port
                                        $timeMs = (Measure-Command {
                                                $wait = $iar.AsyncWaitHandle.WaitOne($timeout, $false) # Set the wait time
                                            }).TotalMilliseconds
                                    }
                                    catch {
                                        # Write-verbose $_
                                    }
                                    # Write-LogStep -prefixe 'L.%Line% Ping' "Tcp-$port", $x.status, $timeMs ok
                                    # Check to see if the connection is done
                                    if (!$wait) {
                                        # Close the connection and report timeout
                                        $ObjPing."Tcp-$port" = 'TimeOut'
                                        $tcpclient.Close()
                                    }
                                    else {
                                        try {
                                            $ObjPing."Tcp-$port" = [int]$timeMs
                                            $ObjPing.status ++
                                            # Write-LogStep -prefixe 'L.%Line% Ping' 'TCP ', "$($ObjPing."Tcp-$port") ms" ok
                                            $tcpclient.EndConnect($iar) | out-Null
                                            $tcpclient.Close()
                                        }
                                        catch {
                                            # $ObjPing."Tcp-$port" = 'Unknow Host'
                                        }
                                    }
                                    if ($tcpclient) {
                                        $tcpclient.Dispose()
                                        $tcpclient.Close()
                                    }
                                }
                                else {
                                    # ICMP
                                    $ObjPing.ICMP = $ObjPing."ICMP-Ttl"  = $null # $ObjPing."ICMP-Size"
                                    try {
                                        $x = $ping.send($ObjPing.IP, $timeOut, $Buffer)
                                        if ($x.status -like 'Success') {
                                            $ObjPing."ICMP" = [int]$x.RoundtripTime
                                            $ObjPing."ICMP-Ttl" = $x.Options.Ttl
                                            # $ObjPing."ICMP-Size" = $x.Buffer.Length
                                            $ObjPing.status ++
                                            # Write-LogStep -prefixe 'L.%Line% Ping' 'ICMP ', "$($x.RoundtripTime) ms", $x.Options.Ttl, $x.Buffer.Length ok
                                        }
                                        else {
                                            # Write-LogStep -prefixe 'L.%Line% Ping' 'ICMP ', "$($x.RoundtripTime) ms", $x.Options.Ttl, $x.Buffer.Length Warn
                                            $ObjPing."ICMP" = $x.status
                                            $ObjPing."ICMP-Ttl" = $ObjPing."ICMP-Size" = '-'
                                        }
                                    }
                                    catch {
                                        # $ObjPing.ICMP =  'Unknow Host'
                                    }
                                }
                            }
                        }
                        catch {
                            # Write-LogStep -prefixe 'L.%Line% Ping' '', 'Inpossible de determiner le noeud de destination !' error
                            $ObjPing.Status = 0
                        }
                        $ObjPing.status = "$([int]([Math]::Round($ObjPing.status / $ports.count,2) * 100))%"
                        $ObjPing.hasChanged = !($ObjPing.Status -eq $last -and $ObjPing.IP -eq $IP )
                        $last = $ObjPing.Status
                        $IP = $ObjPing.IP
                        ipconfig /flushdns
                    }).TotalMilliseconds

                $ObjPings += $ObjPing
                $ObjPing

                if ($loop -and $Intervale - $ms -gt 0) {
                    start-sleep -m ($Intervale - $ms)
                }
            }
        }
    }
    end {
        if ($computerName) {
            $pingScriptBlock = $pingScriptBlock | Include-ToScriptblock -StringBlocks "Ping -DestNode $DestNode -ports $($ports -join(',')) -timeout $timeout -loop $loop -Intervale $Intervale"
            Invoke-Command -ComputerName $ComputerName -ScriptBlock $pingScriptBlock | Select-Object -Property * -ExcludeProperty RunspaceID
        }
    }
}

для удаленного использования с -computerName args add function:

function Include-ToScriptblock {
    <#
        .SYNOPSIS
            integre des fonctions dans un script-block
        .DESCRIPTION
            Ajoute au debut d'un scriptBlock (au niveau du marquage IncludeArea)
        .PARAMETER functions
            liste des fonctions a ajouter
        .PARAMETER ScriptBlock
            ScriptBlock a ettendre
        .EXAMPLE
            ettend un scriptBlock avec la finction test-TcpPort
            Include-ToScriptblock -ScriptBlock {
                    param($x = 2)
                    # Inclide Area #
                    run $x
                } -functions test-TcpPort
        .NOTES
            Alban LOPEZ 2018
            alban.lopez @t gmail.com
    #>

    param (
        [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [ScriptBlock]$ScriptBlock = [scriptBlock]{
                # Inclide Area #
            },
        [string[]]$Functions,
        [string[]]$StringBlocks,
        [string]$marker = '# Inclide Area #'
    )
    begin {
        $FuncTionSting = @()
    }
    process {
        $ScriptBlockStr = $ScriptBlock.ToString()
        if ($ScriptBlockStr -notmatch $marker) {
            throw "Ou inclure ce code dans le ScriptBlock ? : utiliser le marquage `"$marker`""
        }
        foreach ($function in ($functions | ?{$_})) {
            try {
                $function = Get-Item function:$function -ea stop
                $FuncTionSting += "`r`n# Imported from $($function.Source), V$($function.Version)`r`n $($function.CommandType) $($function.name){$($function.Definition)}`r`n`r`n"
            }
            catch {
                if ($function -notlike 'Write-Host') {
                    # Write-LogStep  -prefixe 'L.%Line% %Caller%' $function, $_ Error
                }
            }
        }
        foreach ($StringBlock in ($StringBlocks | ?{$_})) {
            try {
                $FuncTionSting += "`r`n$StringBlock`r`n`r`n"
            }
            catch {
                # Write-LogStep  -prefixe 'L.%Line% %Caller%' '', $_ Error
            }
        }
    }
    end {
        [ScriptBlock]::Create($ScriptBlockStr.Replace($marker, "$FuncTionSting`r`n`r`n$marker"))
    }
}
...