Skip to content

Instantly share code, notes, and snippets.

@davidjenni
Created January 7, 2020 18:08
Show Gist options
  • Select an option

  • Save davidjenni/7eb707e60316cdd97549b37ca95fbe93 to your computer and use it in GitHub Desktop.

Select an option

Save davidjenni/7eb707e60316cdd97549b37ca95fbe93 to your computer and use it in GitHub Desktop.
CIDR to IP range conversion using PowerShell
# calculate IP address range from CIDR notation
# https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
function cidrToIpRange {
param (
[string] $cidrNotation
)
$addr, $maskLength = $cidrNotation -split '/'
[int]$maskLen = 0
if (-not [int32]::TryParse($maskLength, [ref] $maskLen)) {
throw "Cannot parse CIDR mask length string: '$maskLen'"
}
if (0 -gt $maskLen -or $maskLen -gt 32) {
throw "CIDR mask length must be between 0 and 32"
}
$ipAddr = [Net.IPAddress]::Parse($addr)
if ($ipAddr -eq $null) {
throw "Cannot parse IP address: $addr"
}
if ($ipAddr.AddressFamily -ne [Net.Sockets.AddressFamily]::InterNetwork) {
throw "Can only process CIDR for IPv4"
}
$shiftCnt = 32 - $maskLen
$mask = -bnot ((1 -shl $shiftCnt) - 1)
$ipNum = [Net.IPAddress]::NetworkToHostOrder([BitConverter]::ToInt32($ipAddr.GetAddressBytes(), 0))
$ipStart = ($ipNum -band $mask) + 1
$ipEnd = ($ipNum -bor (-bnot $mask)) - 1
# return as tuple of strings:
([BitConverter]::GetBytes([Net.IPAddress]::HostToNetworkOrder($ipStart)) | ForEach-Object { $_ } ) -join '.'
([BitConverter]::GetBytes([Net.IPAddress]::HostToNetworkOrder($ipEnd)) | ForEach-Object { $_ } ) -join '.'
}
$start, $end = cidrToIpRange "192.168.100.14/24"
Write-Host "Start: $start, end: $end"
$start, $end = cidrToIpRange "10.77.1.1/18"
Write-Host "Start: $start, end: $end"
@andreandradearke
Copy link
Copy Markdown

andreandradearke commented Apr 10, 2025

The script is really good but does not work well when the mask is 31 or 32.
For an input 13.105.220.108/31 it will produce a result like:

Start Host: 13.105.220.109
End Host: 13.105.220.108

To fix that just replace lines 28 and 29
$ipStart = ($ipNum -band $mask) + 1 $ipEnd = ($ipNum -bor (-bnot $mask)) - 1

By this
` $ipStart = $ipNum -band $mask
$ipEnd = $ipNum -bor (-bnot $mask)

    if ($maskLength -lt 31) {
        $ipStart += 1
        $ipEnd -= 1
    }`

I've tested this with more than 4000 cidr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment