Thursday, 20 August 2015

PowerShell Subnet Calculator

I'm often faced with situations when I need to scan entire subnets to find devices and either perform an inventory or run a remote PowerShell command on all the devices on a subnet. It's quite simple to generate the list of IPs for a /24 subnet but is a little trickier for the other subnets, e.g. a /12. Anyways, long story short. Here is a PowerShell function that will output an array of all the IPs on a particular subnet. 

You can run it as below:

Get-IPs -Subnets "10.0.2.0/24","10.0.4.0/24"

For example:



You can then pipe out the IPs so you can run a command on each:

Get-IPs -Subnets "10.0.2.0/24","10.0.4.0/24" | % {Do something on $_}


The function is below. Happy scripting.



function Get-IPs {

        Param(
        [Parameter(Mandatory = $true)]
        [array] $Subnets
        )

foreach ($subnet in $subnets)
    {
        
        #Split IP and subnet
        $IP = ($Subnet -split "\/")[0]
        $SubnetBits = ($Subnet -split "\/")[1]
        
        #Convert IP into binary
        #Split IP into different octects and for each one, figure out the binary with leading zeros and add to the total
        $Octets = $IP -split "\."
        $IPInBinary = @()
        foreach($Octet in $Octets)
            {
                #convert to binary
                $OctetInBinary = [convert]::ToString($Octet,2)
                
                #get length of binary string add leading zeros to make octet
                $OctetInBinary = ("0" * (8 - ($OctetInBinary).Length) + $OctetInBinary)

                $IPInBinary = $IPInBinary + $OctetInBinary
            }
        $IPInBinary = $IPInBinary -join ""

        #Get network ID by subtracting subnet mask
        $HostBits = 32-$SubnetBits
        $NetworkIDInBinary = $IPInBinary.Substring(0,$SubnetBits)
        $HostIDInBinary = $IPInBinary.Substring($SubnetBits,$HostBits)

        #Work out all the host IDs in that subnet by cycling through $i from 1 up to max $HostIDInBinary (i.e. 1s stringed up to $HostBits)
        #Work out max $HostIDInBinary
        $imax = [convert]::ToInt32(("1" * $HostBits),2) -1

        $IPs = @()

        #Next ID is first network ID converted to decimal plus $i then converted to binary
        For ($i = 1 ; $i -le $imax ; $i++)
            {
                #Convert to decimal and add $i
                $NextHostIDInDecimal = ([convert]::ToInt32($HostIDInBinary,2) + $i)
                #Convert back to binary
                $NextHostIDInBinary = [convert]::ToString($NextHostIDInDecimal,2)
                #Add leading zeros
                #Number of zeros to add 
                $NoOfZerosToAdd = $HostIDInBinary.Length - $NextHostIDInBinary.Length
                $NextHostIDInBinary = ("0" * $NoOfZerosToAdd) + $NextHostIDInBinary

                #Work out next IP
                #Add networkID to hostID
                $NextIPInBinary = $NetworkIDInBinary + $NextHostIDInBinary
                #Split into octets and separate by . then join
                $IP = @()
                For ($x = 1 ; $x -le 4 ; $x++)
                    {
                        #Work out start character position
                        $StartCharNumber = ($x-1)*8
                        #Get octet in binary
                        $IPOctetInBinary = $NextIPInBinary.Substring($StartCharNumber,8)
                        #Convert octet into decimal
                        $IPOctetInDecimal = [convert]::ToInt32($IPOctetInBinary,2)
                        #Add octet to IP 
                        $IP += $IPOctetInDecimal
                    }

                #Separate by .
                $IP = $IP -join "."
                $IPs += $IP

                
            }
        $IPs
    }
}

No comments:

Post a Comment