#requires -Version 2.0 Function Ping-Subnet { #.Synopsis # Ping a subnet returning all alive hosts. #.Example # Ping-Subnet -IP 192.168.1.0 -Netmask /24 #.Example # Ping-Subnet -IP 192.168.1.128 -Netmask 255.255.255.128 Param ( [string] $IP , [string] $netmask ) Begin { $IPs = New-Object System.Collections.ArrayList $Jobs = New-Object System.Collections.ArrayList $max = 50 Function Get-NetworkAddress { #.Synopsis # Get the network address of a given lan segment #.Example # Get-NetworkAddress -IP 192.168.1.36 -mask 255.255.255.0 Param ( [string] $IP , [string] $Mask , [switch] $Binary ) Begin { $NetAdd = $null } Process { $BinaryIP = ConvertTo-BinaryIP $IP $BinaryMask = ConvertTo-BinaryIP $Mask 0..34 | %{ $IPBit = $BinaryIP .Substring( $_ ,1) $MaskBit = $BinaryMask .Substring( $_ ,1) IF ( $IPBit -eq '1' -and $MaskBit -eq '1' ) { $NetAdd = $NetAdd + "1" } elseif ( $IPBit -eq "." ) { $NetAdd = $NetAdd + '.' } else { $NetAdd = $NetAdd + "0" } } if ( $Binary ) { return $NetAdd } else { return ConvertFrom-BinaryIP $NetAdd } } } Function ConvertTo-BinaryIP { #.Synopsis # Convert an IP address to binary #.Example # ConvertTo-BinaryIP -IP 192.168.1.1 Param ( [string] $IP ) Process { $out = @() Foreach ( $octet in $IP .split( '.' )) { $strout = $null 0..7|% { IF (( $octet - [math] ::pow(2,(7- $_ ))) -ge 0) { $octet = $octet - [math] ::pow(2,(7- $_ )) [string] $strout = $strout + "1" } else { [string] $strout = $strout + "0" } } $out += $strout } return [string] ::join( '.' , $out ) } } Function ConvertFrom-BinaryIP { #.Synopsis # Convert from Binary to an IP address #.Example # Convertfrom-BinaryIP -IP 11000000.10101000.00000001.00000001 Param ( [string] $IP ) Process { $out = @() Foreach ( $octet in $IP .split( '.' )) { $strout = 0 0..7|% { $bit = $octet .Substring(( $_ ),1) IF ( $bit -eq 1) { $strout = $strout + [math] ::pow(2,(7- $_ )) } } $out += $strout } return [string] ::join( '.' , $out ) } } Function ConvertTo-MaskLength { #.Synopsis # Convert from a netmask to the masklength #.Example # ConvertTo-MaskLength -Mask 255.255.255.0 Param ( [string] $mask ) Process { $out = 0 Foreach ( $octet in $Mask .split( '.' )) { $strout = 0 0..7|% { IF (( $octet - [math] ::pow(2,(7- $_ ))) -ge 0) { $octet = $octet - [math] ::pow(2,(7- $_ )) $out ++ } } } return $out } } Function ConvertFrom-MaskLength { #.Synopsis # Convert from masklength to a netmask #.Example # ConvertFrom-MaskLength -Mask /24 #.Example # ConvertFrom-MaskLength -Mask 24 Param ( [int] $mask ) Process { $out = @() [int] $wholeOctet = ( $mask - ( $mask % 8))/8 if ( $wholeOctet -gt 0) { 1..$( $wholeOctet ) |%{ $out += "255" } } $subnet = ( $mask - ( $wholeOctet * 8)) if ( $subnet -gt 0) { $octet = 0 0..( $subnet - 1) | %{ $octet = $octet + [math] ::pow(2,(7- $_ )) } $out += $octet } for ( $i = $out .count; $i -lt 4; $I ++) { $out += 0 } return [string] ::join( '.' , $out ) } } Function Get-IPRange { #.Synopsis # Given an Ip and subnet, return every IP in that lan segment #.Example # Get-IPRange -IP 192.168.1.36 -Mask 255.255.255.0 #.Example # Get-IPRange -IP 192.168.5.55 -Mask /23 Param ( [string] $IP , [string] $netmask ) Process { iF ( $netMask .length -le 3) { $masklength = $netmask .replace( '/' , '' ) $Subnet = ConvertFrom-MaskLength $masklength } else { $Subnet = $netmask $masklength = ConvertTo-MaskLength -Mask $netmask } $network = Get-NetworkAddress -IP $IP -Mask $Subnet [int] $FirstOctet , [int] $SecondOctet , [int] $ThirdOctet , [int] $FourthOctet = $network .split( '.' ) $TotalIPs = ( [math] ::pow(2,(32- $masklength )) -2) $blocks = ( $TotalIPs - ( $TotalIPs % 256))/256 if ( $Blocks -gt 0) { 1.. $blocks | %{ 0..255 |%{ if ( $FourthOctet -eq 255) { If ( $ThirdOctet -eq 255) { If ( $SecondOctet -eq 255) { $FirstOctet ++ $secondOctet = 0 } else { $SecondOctet ++ $ThirdOctet = 0 } } else { $FourthOctet = 0 $ThirdOctet ++ } } else { $FourthOctet ++ } Write-Output ( "{0}.{1}.{2}.{3}" -f ` $FirstOctet , $SecondOctet , $ThirdOctet , $FourthOctet ) } } } $sBlock = $TotalIPs - ( $blocks * 256) if ( $sBlock -gt 0) { 1.. $SBlock | %{ if ( $FourthOctet -eq 255) { If ( $ThirdOctet -eq 255) { If ( $SecondOctet -eq 255) { $FirstOctet ++ $secondOctet = 0 } else { $SecondOctet ++ $ThirdOctet = 0 } } else { $FourthOctet = 0 $ThirdOctet ++ } } else { $FourthOctet ++ } Write-Output ( "{0}.{1}.{2}.{3}" -f ` $FirstOctet , $SecondOctet , $ThirdOctet , $FourthOctet ) } } } } } Process { #get every ip in scope Get-IPRange $IP $netmask | %{ [void] $IPs .Add( $_ ) } #loop untill we've pinged them all While ( $IPs .count -gt 0 -or $jobs .count -gt 0) { #if we have open spots kick off some more IF ( $jobs .count -le $max ) { # determin how many to kick off $addjobs = ( $max - $jobs .count) Foreach ( $IP in ( $IPS | Select -first $addjobs )) { #save the job id, and move on [VOID] $Jobs .Add((gwmi -q "SELECT Address,StatusCode FROM Win32_Pingstatus WHERE Address = `'$IP`'" -asjob ).Id) #remove the IP from our pool $IPs .Remove( $IP ) } } #we'll use this array to track what's comeback $Clean = @() Foreach ( $J in $jobs ) { # If this job is done get the results if (( Get-Job -id $j ).JobStateInfo.state -eq 'Completed') { # if the ping was sucessfull return the IP Address write-output ( Receive-Job -id $j ) | ?{ $_ .StatusCode -eq 0}| select -expand Address # dispose of the job remove-job -id $j $clean += $j } } Foreach ( $c in $Clean ) { #remove the jobs that we just processed $jobs .remove( $c ) } } } } Ping-Subnet 192.168.70.20 /24 |
Reference: http://poshcode.org/976