Home > Enterprise >  How to convert IP range to single CIDR notation using Powershell?
How to convert IP range to single CIDR notation using Powershell?

Time:02-01

I am trying to convert IP Address range into single CIDR notation, but unable to find any method using Powershell which converts it into CIDR notation.

startIP = '4.249.240.6'
endIP = '4.249.255.255'

Output: '4.249.241.0/24'

CodePudding user response:

You can use this function. Not exactly what you are expecting because it has few other subnet information.

#------------------------------------------------------------------------------
# Subroutine ip_range_to_prefix
# Purpose           : Return all prefixes between two IPs
function Get-IpSubnetsBetween {

    param(
        [ipaddress]$StartIp,

        [ipaddress]$EndIp
    )


    if ($StartIp.AddressFamily -ne [System.Net.Sockets.AddressFamily]::InterNetwork -or
          $EndIp.AddressFamily -ne [System.Net.Sockets.AddressFamily]::InterNetwork) {

        Write-Error -Message 'Function only works for IPv4 addresses'
    }


    # Get the IPs in 32-bit unsigned integers (big-endian)
    # The .Address property is little-endian, or host-endian, so avoid that.

    [uint32[]]$octets = $StartIp.GetAddressBytes()
    [uint32]$startIpAddress = ($octets[0] -shl 24)   ($octets[1] -shl 16)   ($octets[2] -shl 8)   $octets[3]

    [uint32[]]$octets = $EndIp.GetAddressBytes()
    [uint32]$EndIpAddress   = ($octets[0] -shl 24)   ($octets[1] -shl 16)   ($octets[2] -shl 8)   $octets[3]
    Remove-Variable -Name octets -ErrorAction SilentlyContinue


    while ($startIpAddress -le $endIPAddress -and $startIpAddress -ne [uint32]::MaxValue) {


        # Bitwise shift-right in a loop,
        # to find how many trailing 0 bits there are
        $numTrailingZeros = 0
        while ([uint32]($startIpAddress -shr $numTrailingZeros) % 2 -eq 0) {
            $numTrailingZeros  
        }
    
        # switch all those bits to 1, 
        # see if that takes us past the end IP address. 
        # Try one fewer in a loop until it doesn't pass the end.
        do {
            [uint32]$current = $startIpAddress -bor ([math]::Pow(2, $numTrailingZeros)-1)
            $numTrailingZeros--
        } while ($current -gt $endIpAddress)
    

        # Now compare this new address with the original,
        # and handwave idk what this is for
        $prefixLen = 0
        while (([uint32]($current -band [math]::Pow(2, $prefixLen))) -ne ([uint32]($startIpAddress -band [math]::Pow(2, $prefixLen)))) {
            $prefixLen  
        }
        $prefixLen = 32 - $prefixLen

    
        # add this subnet to the output
        [byte[]]$bytes = @(
            (($startIpAddress -band [uint32]4278190080) -shr 24),
            (($startIpAddress -band [uint32]16711680) -shr 16),
            (($startIpAddress -band [uint32]65280) -shr 8),
             ($startIpAddress -band [uint32]255)
        )

        [ipaddress]::new($bytes).IpAddressToString   "/$prefixLen"
    
        # Add 1 to current IP
        [uint32]$startIpAddress = [uint32]($current   1)

    }
}

Usage:

Get-IpSubnetsBetween -StartIp '4.249.240.6' -EndIp '4.249.255.255'

Output

Output

Reference Link: r/Powershell - Reddit

  • Related