I have seen most of the Powershell IP scanner, ping sweeping scripts but none of them uses the PingASync method.


The "problem" with synchronous scripts is that they have to wait until a node replies or times out before continuing to the next address.

Using this approach may take some time to sweep through a large network.

In an asynchronous approach the script send an ICMP request to all addresses and an event is raised when an address replies. 

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.

The script just loads the function into the current scope so to use it open Powershell or Powershell-ISE, run the script once and type Ping-IPRange on the command line.


Ping-IPRange -StartAddress <string> -EndAddress <string> -Interval <Int32> -RawOutput<switch> 


Version 6.0 : Major overhaul of the event handling part, done a lot of testing and debugging and yes, it got faster again.

 Version 5.1 : Better error handling and a proper comment-based help.

Version 5.0 :  A lot of little improvements, There is no more need to store variables in the global scope so it's cleaner.

It got faster too, found a way to generate the IP's just a bit faster and

there is the -RawOutput switch that changes the output to the raw System.Net.Networkinformation.PingReply output.

If you update your script, don't worry about the normal output, the names and types are still the same.

  PS, the funcion runs a lot faster on Powershell 3 and above


 An example on how you may use the funtion
PS C:\Scripts\> .\Ping-IPRange.ps1 #Run Once 
Ping-IPRange -StartAddress -EndAddress -Interval 10 | Format-Table  -AutoSize 
IPAddress     Bytes Ttl ResponseTime 
---------     ----- --- ------------     32 128            0     32  64          498     32  64         1118    32  64            0 
  An example on how you may use the funtion


$MySubnet = Ping-IPRange -StartAddress -EndAddress -Interval 20 
$MySubnet | ft Ipaddress,@{LABEL="FQDN"; EXPRESSION={[System.Net.Dns]::GetHostByAddress($_.IPaddress).Hostname}}

And Yes, it got fast again!


Measure-Command { Ping-IPRange -Interval 0 } 
Days              : 0 
Hours             : 0 
Minutes           : 0 
Seconds           : 3 
Milliseconds      : 484 
Ticks             : 34847832 
TotalDays         : 4,03331388888889E-05 
TotalHours        : 0,000967995333333333 
TotalMinutes      : 0,05807972 
TotalSeconds      : 3,4847832 
TotalMilliseconds : 3484,7832