Functions/Test-ConnectionAsync.ps1
function Test-ConnectionAsync { <# .SYNOPSIS Performs a ping test asynchronously .DESCRIPTION Performs a ping test asynchronously .PARAMETER ComputerName List of computers to test connection. Aliased to 'CN', 'Server' .PARAMETER Timeout Timeout in milliseconds. Default 2000 ms. .PARAMETER TimeToLive Sets a time to live on ping request. Default 128. .PARAMETER BufferSize How large you want the buffer to be. Valid range 32-65500, default of 32. If the buffer is 1501 bytes or greater then the ping can fragment. .PARAMETER IncludeSource A switch determining if you want the source computer name to appear in the output .PARAMETER Full A switch determining if full output appears .NOTES Inspired by Test-ConnectionAsync by 'Boe Prox' https://gallery.technet.microsoft.com/scriptcenter/Asynchronous-Network-Ping-abdf01aa * fixed logic around processing pipeline * removed $Buffer parameter * added $BufferSize parameter and dynamically create $Buffer from $BufferSize * added $IncludeSource so that source computer would be included in output * added $Full so that default output is brief * changed datatype of .IPAddress to [version] so that it can be sorted properly .OUTPUTS [pscustomobject] with output from Net.AsyncPingResult and optionally the source address .EXAMPLE Test-ConnectionAsync -ComputerName server1,server2 ComputerName IPAddress Result ------------ --------- ------ server1 192.168.1.31 Success server2 192.168.1.41 Success Description ----------- Performs asynchronous ping test against listed systems and lists brief output. .EXAMPLE Test-ConnectionAsync -ComputerName server1,server2 -Full ComputerName IPAddress BufferSize Result ResponseTime ------------ --------- ---------- ------ ------------ server1 192.168.1.31 32 Success 86 server2 192.168.1.41 32 Success 79 Description ----------- Performs asynchronous ping test against listed systems and lists full output. .EXAMPLE Test-ConnectionAsync -ComputerName server1,server2 -Full -BufferSize 1500 ComputerName IPAddress BufferSize Result ResponseTime ------------ --------- ---------- ------ ------------ server1 192.168.1.31 1500 Success 140 server2 192.168.1.41 1500 Success 137 Description ----------- Performs asynchronous ping test against listed systems and lists full output with a buffersize of 1500 bytes. #> #Requires -Version 3.0 [OutputType('Net.AsyncPingResult')] [CmdletBinding(ConfirmImpact = 'None')] Param ( [parameter(ValueFromPipeline, Position = 0)] [string[]] $ComputerName, [parameter()] [int] $Timeout = 2000, [parameter()] [Alias('Ttl')] [int] $TimeToLive = 128, [parameter()] [validaterange(32, 65500)] [int] $BufferSize = 32, [parameter()] [switch] $IncludeSource, [parameter()] [switch] $Full ) begin { Write-Verbose -Message "Starting [$($MyInvocation.Mycommand)]" if ($IncludeSource) { $Source = $env:COMPUTERNAME } $Buffer = New-Object -TypeName System.Collections.ArrayList 1..$BufferSize | ForEach-Object { $null = $Buffer.Add(([byte] [char] 'A')) } $PingOptions = New-Object -TypeName System.Net.NetworkInformation.PingOptions $PingOptions.Ttl = $TimeToLive If ($BufferSize -gt 1500) { $DontFragment = $false } else { $DontFragment = $true } Write-Verbose -Message "ComputerName [$($ComputerName -join ',')]" Write-Verbose -Message "BufferSize [$BufferSize]" Write-Verbose -Message "Timeout [$Timeout]" Write-Verbose -Message "TimeToLive [$TimeToLive]" Write-Verbose -Message "IncludeSource [$IncludeSource]" Write-Verbose -Message "Full [$Full]" Write-Verbose -Message "DontFragment [$DontFragment]" $PingOptions.DontFragment = $DontFragment $Computerlist = New-Object -TypeName System.Collections.ArrayList } process { foreach ($Computer in $ComputerName) { [void] $Computerlist.Add($Computer) } } end { $Task = foreach ($Computer in $ComputerList) { [pscustomobject] @{ ComputerName = $Computer Task = (New-Object -TypeName System.Net.NetworkInformation.Ping).SendPingAsync($Computer, $Timeout, $Buffer, $PingOptions) } } try { [void] [Threading.Tasks.Task]::WaitAll($Task.Task) } catch { Write-Error -Message "Error checking [$Computer]" } $Task | ForEach-Object { if ($_.Task.IsFaulted) { $Result = $_.Task.Exception.InnerException.InnerException.Message $IPAddress = $Null $ResponseTime = $Null } else { $Result = $_.Task.Result.Status $IPAddress = $_.task.Result.Address.ToString() $ResponseTime = $_.task.Result.RoundtripTime } $Layout = [ordered] @{ ComputerName = $_.ComputerName IPAddress = if ($IPAddress) { [version] $IPAddress } else { $Null } Result = $Result BufferSize = $BufferSize ResponseTime = $ResponseTime DontFragment = $DontFragment Timeout = $Timeout TimeToLive = $TimeToLive } if ($IncludeSource) { $Layout.Insert(0,'Source',$Source) } $Object = New-Object -TypeName psobject -Property $Layout $Object.pstypenames.insert(0, 'Net.AsyncPingResult') if ($Full) { $Object } else { if ($IncludeSource) { $Object | Select-Object -Property Source, ComputerName, IPAddress, Result } else { $Object | Select-Object -Property ComputerName, IPAddress, Result } } } Write-Verbose -Message "Ending [$($MyInvocation.Mycommand)]" } } |