PowerShell : Find-AvailableIP

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:

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

 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

<#
.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.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.