ping.ps1

<#PSScriptInfo
 
.VERSION 1.2.0
 
.GUID 81a98bc4-d077-4dd7-ac9c-4a19a8c3246d
 
.AUTHOR saw-friendship
 
.COMPANYNAME
 
.COPYRIGHT
 
.TAGS
ping
 
.LICENSEURI
 
.PROJECTURI
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
 
#>


<#
 
.DESCRIPTION
 Fast alternate ping.exe
.EXAMPLE
Ping 8.8.8.8 -g
!!!!!!!!!!!!!!!!!!!! : 20 : 01:28:25
.EXAMPLE
Ping 8.8.8.8 -g -t -Fast
!!!!!!!!!!!!!!!!!!!! : 20 : 01:28:25
!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!!!!!!!!!!!!!!!!!.!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! : 98 : 01:29:34
!!!!!!!!!!!.!!!!!!!!!!!!!!!!!!!!!.!!!!!!!!!!!!!!!!!!!.!!!!!!!!!!!!!!!!!!!!!.!!!!!!!!!!!!!!!!!!!!.!!! : 95 : 01:29:36
!!!!!!!!!!!!
PS> ^C
 
.EXAMPLE
Ping 8.8.8.8 -c 2 | ft
Number TTL Status DontFragment Address RoundtripTime
------ --- ------ ------------ ------- -------------
     1 46 Success False 8.8.8.8 17
     2 46 Success False 8.8.8.8 17
      
#>
 

[CmdletBinding(DefaultParameterSetName='Limited')]
param(
        [Parameter(Mandatory=$true,Position=0)][alias('IPAddress')]$HostAddress,
        [Parameter(ParameterSetName='Limited')][ValidateRange(1,1099511627776)][alias('n')][Int64]$Count = 20,
        [Parameter(ParameterSetName='Unlimited')][alias('t')][switch]$infinity,
        [ValidateRange(1,10000)][alias('w','TimeOut')][int]$Delay = 255,
        [ValidateRange(1,65500)][alias('l','Size','Length')][int]$BufferSize = 16,
        [ValidateRange(1,255)][alias('i','TTL')][int]$TimeToLive = 255,
        [ValidateRange(0,10000)][alias('Throttle','ms')][int]$ThrottleMilliseconds = 255,
        [switch][alias('DateTime')]$Timestamp,
        [switch][alias('df','f')]$DontFragment,
        [switch]$Fast,
        [switch]$Graphic,
        [ValidateRange(1,500)][int]$WindowSize = 100,
        [switch][alias('a')]$ResolveDNS
    )
    
    [Hashtable[]]$select = @(
        ,@{Name = 'Number'; Expression = {$i}}
        ,@{Name = 'TTL'; Expression = {$_.Options.ttl}}
        ,@{Name = 'Status'; Expression = {$_.Status}}
        ,@{Name = 'DontFragment'; Expression = {$_.Options.DontFragment}}
        ,@{Name = 'Address'; Expression = {$_.Address}}
        ,@{Name = 'RoundtripTime'; Expression = {$_.RoundtripTime}}
    )
    if ($infinity) {$Count = 1tb}
    if ($Fast) {$ThrottleMilliseconds = 0}
    if ($Timestamp) {$select += @{Name = 'Timestamp'; Expression = {Get-Date}}}
    if ($ResolveDNS) {$select += @{Name = 'HostnamePTR'; Expression = {[System.Net.Dns]::GetHostEntry($_.Address).Hostname}}}

    
    if (!($HostAddress -as [System.Net.IPAddress])){
        $HostIP = [System.Net.Dns]::GetHostEntry($HostAddress).AddressList.IPAddressToString | Get-Random
        if(!$HostIP){break}
    } else {
        $HostIP = [System.Net.IPAddress]$HostAddress
    }
    # [byte[]]$Buffer = New-Object -TypeName Byte[] -ArgumentList $BufferSize
    [byte[]]$Buffer = [byte[]](1)*$BufferSize
    $GraphicStat = @()
    $IPStatusTable = @{
        [System.Net.NetworkInformation.IPStatus]::Success = '!'
        [System.Net.NetworkInformation.IPStatus]::DestinationNetworkUnreachable = 'U'
        [System.Net.NetworkInformation.IPStatus]::DestinationHostUnreachable = 'U'
        [System.Net.NetworkInformation.IPStatus]::DestinationProtocolUnreachable = 'U'
        [System.Net.NetworkInformation.IPStatus]::DestinationPortUnreachable = 'U'
        [System.Net.NetworkInformation.IPStatus]::NoResources = '.'
        [System.Net.NetworkInformation.IPStatus]::BadOption = 'U'
        [System.Net.NetworkInformation.IPStatus]::HardwareError = 'U'
        [System.Net.NetworkInformation.IPStatus]::PacketTooBig = 'U'
        [System.Net.NetworkInformation.IPStatus]::TimedOut = '.'
        [System.Net.NetworkInformation.IPStatus]::BadRoute = 'U'
        [System.Net.NetworkInformation.IPStatus]::TtlExpired = 'U'
        [System.Net.NetworkInformation.IPStatus]::TtlReassemblyTimeExceeded = 'U'
        [System.Net.NetworkInformation.IPStatus]::ParameterProblem = 'U'
        [System.Net.NetworkInformation.IPStatus]::SourceQuench = 'U'
        [System.Net.NetworkInformation.IPStatus]::BadDestination = 'U'
        [System.Net.NetworkInformation.IPStatus]::DestinationUnreachable = 'U'
        [System.Net.NetworkInformation.IPStatus]::TimeExceeded = '.'
        [System.Net.NetworkInformation.IPStatus]::BadHeader = 'U'
        [System.Net.NetworkInformation.IPStatus]::UnrecognizedNextHeader = 'U'
        [System.Net.NetworkInformation.IPStatus]::IcmpError = 'U'
        [System.Net.NetworkInformation.IPStatus]::DestinationScopeMismatch = 'U'
        [System.Net.NetworkInformation.IPStatus]::Unknown = '.'
    }
    $Ping = New-Object -TypeName System.Net.NetworkInformation.Ping
    $PingOptions = New-Object -TypeName System.Net.NetworkInformation.PingOptions -ArgumentList @($TimeToLive,$DontFragment)
    for($WindowBuffer = $i = 1; $i -le $Count; ++$i) {
        $Ping.Send($HostIP, $Delay, $Buffer, $PingOptions) | Select-Object -Property $select | % {
            if (!$Graphic) {
                $_.psobject.Typenames.Insert(0,'NetWork.Ping'); $_
            } else {
                $GraphicStat += $_
                Write-Host -Object $IPStatusTable[$_.Status] -NoNewline -ForegroundColor Yellow
                if ($Count -lt $WindowSize) {$WindowSize = $Count}
                if ($WindowBuffer -eq $WindowSize) {
                    $WindowBuffer = 0
                    $GraphicLine = $GraphicStat | Group-Object -Property Status -AsHashTable -AsString
                    Write-Host -Object $(' : '+([string]$GraphicLine['Success'].Count).PadLeft(3,' ')+' : '+(Get-Date).ToString('HH:mm:ss')) -NoNewline -ForegroundColor Yellow
                    Write-Host -Object ''
                    $GraphicStat = @()
                }
            }
            if ($ThrottleMilliseconds) {Start-Sleep -Milliseconds $ThrottleMilliseconds}
        }
        ++$WindowBuffer
    }