I use NMAP frequently and there are many times that I wish to have its functions on different environments. In this case I was interested in finding how many IP were available for capacity on a local network, knowing that all devices on my network have ICMP enabled.
Using NMAP
In this article I’ve used NMAP to get a list of all IP on my network:
1 |
nmap -sL 192.168.0.* |
My first idea was use Python and Python-nmap library, but I think that PowerShell using Test-Connection or ping was simple and good enough, especially if we run it on powershell core this will work on every os.
Using PowerShell
Using the ping command is a simple way to leverage ICMP protocol and check if a host is reachable. Test-Connection is essentially the same command, so we can specify some parameters to speed up the process (e.g. limit to just one attempt). Whenever we are starting an interactive script that can take some time to complete, I like to use Write-Progess to provide a meaningful information about the progress and the status at runtime.
I’ve added a Write-Verbose to add some more information about the number of the results that can sometime be required.
This is the output
1 2 3 4 5 6 7 8 |
C:\PS> "10.0.0.*", "10.0.1.*" |Find-AvailableIP -Verbose VERBOSE: There are 2 IPs Available on network 10.0.0.* 10.0.0.2 10.0.0.5 VERBOSE: There are 3 IPs Available on network 10.0.1.* 10.10.1.2 10.10.1.3 10.10.1.5 |
Remember to use the Dot-Sourcing before calling the Find-AvailableIP function.
Let’s view the code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
<# .SYNOPSIS Get available IPs on the network .DESCRIPTION Get a list of all IPs that don't respond to ICPM protocol. .PARAMETER Network Specify your network using a '*' symbol, for example 10.0.0.* .EXAMPLE C:\PS>Find-AvailableIP -Network"172.16.0.*" -verbose VERBOSE: There are 2 IPs Available on network 172.16.0.* 172.16.0.9 172.16.0.10 .EXAMPLE C:\PS> "172.16.0.*" |Find-AvailableIP 172.16.0.9 172.16.0.10 .EXAMPLE C:\PS> "10.0.0.*", "10.0.1.*" | Find-AvailableIP -Verbose VERBOSE: There are 2 IPs Available on network 10.0.0.* 10.0.0.2 10.0.0.5 VERBOSE: There are 3 IPs Available on network 10.0.1.* 10.10.1.2 10.10.1.3 10.10.1.5 .NOTES Author: Paolo Frigo, https://www.scriptinglibrary.com #> function Find-AvailableIP { [CmdletBinding(SupportsShouldProcess = $true)] [OutputType([string])] param( #check if the IP Address belong to a private class A,B or C [parameter(ValueFromPipeline, Mandatory = $true)] [ValidateScript( {$_ -match "^(10\.|172\.16\.|192\.168\.|)[0-9.]*(\*$)"})] [string] $Network ) Begin { } Process { $counter = 0 $Results = @() $IPs = 1 .. 254 foreach ($IP in $IPs) { $counter += 1 $IpAddress = $Network.Replace("*", $IP) Write-Progress -activity "Testing subnet $Network" -status "$IpAddress" -PercentComplete (($counter / ($IPs.Length)) * 100) if ( (Test-Connection -computername "$IpAddress" -quiet -count 1 ) -eq $False) { $Results += $IpAddress } } Write-Verbose "There are $($Results.Length) IPs Available on network $Network" Write-OutPut $Results } End { } } |
You can find this script, as usual, on my github repo.