invoke-fastping.ps1
<#
.SYNOPSIS Performs a series of asynchronous pings against the target hosts. .PARAMETER HostName A string array of target hosts to ping. .PARAMETER PingCount The number of pings to send against each host. #> function Invoke-FastPing { [alias('FastPing', 'fping', 'fp')] param ( [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [Alias('Computer', 'ComputerName', 'Host')] [String[]] $HostName, [Int] $PingCount = 1 ) process { # Objects to hold items as we process pings $queue = [System.Collections.Queue]::new() $pingHash = @{} # Start an asynchronous ping against each computer foreach ($hn in $HostName) { if ($pingHash.Keys -notcontains $hn) { $pingHash.Add($hn, [System.Collections.ArrayList]::new()) } for ($i = 0; $i -lt $PingCount; $i++) { $ping = [System.Net.Networkinformation.Ping]::new() $object = @{ Host = $hn Ping = $ping Async = $ping.SendPingAsync($hn) } $queue.Enqueue($object) } } # Process the asynchronous pings while ($queue.Count -gt 0) { $object = $queue.Dequeue() if ($object.Async.IsCompleted -eq $true) { $null = $pingHash[$object.Host].Add(@{ Host = $object.Host RoundtripTime = $object.Async.Result.RoundtripTime Status = $object.Async.Status }) } else { $queue.Enqueue($object) } } # Using the ping results in pingHash, calculate the average RoundtripTime foreach ($key in $pingHash.Keys) { if (($pingHash.$key.Status | Select-Object -Unique) -eq 'RanToCompletion') { $online = $true } else { $online = $false } if ($online -eq $true) { $latency = [System.Collections.ArrayList]::new() foreach ($value in $pingHash.$key) { if ($value.RoundtripTime) { $null = $latency.Add($value.RoundtripTime) } } $average = $latency | Measure-Object -Average if ($average.Average) { $roundtripAverage = [Math]::Round($average.Average, 0) } else { $roundtripAverage = $null } } else { $roundtripAverage = $null } [PSCustomObject]@{ ComputerName = $key RoundtripAverage = $roundtripAverage Online = $online } } } # End Process } |