Created
November 22, 2023 08:13
-
-
Save aschmidt75/36dc929e9b5752c63c820b16804ee03f to your computer and use it in GitHub Desktop.
Powershell ipcalc cidrsubnet helper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Function Convert-IpAddressStringToBinString { | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory)] | |
[string]$IpAddress | |
) | |
$IpAddressFullBin = "" | |
foreach ($octet in $IPAddress.Split(".")) { | |
# make sure this is a valid byte octet | |
$v = [convert]::ToInt32($octet) | |
if ( ($v -lt 0) -or ($v -gt 255)) { | |
throw "Invalid ip address octet" | |
} | |
$s = [convert]::ToString($octet, 2) | |
$IpAddressFullBin += $s.PadLeft(8, "0") | |
} | |
$IpAddressFullBin | |
} | |
Function Convert-IpAddressBinStringToString { | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory)] | |
[string]$IpAddressBinString | |
) | |
@( 0, 8, 16, 24 ) | ForEach-Object { | |
$o = $IpAddressBinString.substring($_, 8) | |
"{0}" -f [convert]::ToInt32($o,2) | |
} | Join-String -Separator "." | |
} | |
Function Test-CidrValid { | |
<# | |
.SYNOPSIS | |
Checks if a given CIDR string is valid | |
#> | |
return $false | |
} | |
Function Measure-Cidr { | |
[CmdletBinding()] | |
param ( | |
[Parameter(Mandatory=$true)] | |
[string]$Prefix, | |
[Parameter(Mandatory=$true)] | |
[byte]$NewBits | |
) | |
$m = $Prefix -match "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{1,2}$" | |
if (-not $m) { | |
throw "Prefix not a valid CIDR" | |
} | |
$s = $Prefix.split("/") | |
$IpCidr = $s[0] | |
$NetmaskBits = [convert]::ToUint16($s[1]) | |
if ($NetmaskBits -gt 32) { | |
throw "Prefix not a valid CIDR, invalid netmask" | |
} | |
if ($NewBits -gt 32) { | |
throw "NewBits must be <= 32" | |
} | |
if ($NewBits -lt $NetMaskBits) { | |
throw "NewBits must be larger that netmask of prefix" | |
} | |
$d = [math]::pow(2, $NewBits - $NetmaskBits) | |
$res = New-Object PSCustomObject @{ | |
Prefix = $Prefix | |
IP = $IpCidr | |
NetmaskBits = $NetmaskBits | |
NumberOfNetworks = $d | |
} | |
$res | |
} | |
Function Get-CidrSubnets { | |
<# | |
.SYNPOSIS | |
.EXAMPLE | |
#> | |
[CmdletBinding()] | |
param ( | |
[Parameter(Mandatory=$true)] | |
[string]$Prefix, | |
[Parameter(Mandatory=$true)] | |
[byte]$NewBits | |
) | |
$m = Measure-Cidr -Prefix $Prefix -NewBits $NewBits | |
for ($i = 0; $i -lt $m.NumberOfNetworks; $i++) { | |
Split-CidrSubnet -Prefix $Prefix -NewBits $NewBits -NetNum $i | |
} | |
} | |
Function Split-CidrSubnet { | |
<# | |
.EXAMPLE | |
> Update-CidrSubnet -Prefix "192.168.10.0/24" -NewBits 26 -NetNum 3 | |
192.168.10.192 | |
#> | |
[CmdletBinding()] | |
param ( | |
[Parameter(Mandatory=$true)] | |
[string]$Prefix, | |
[Parameter(Mandatory=$true)] | |
[byte]$NewBits, | |
[Parameter(Mandatory=$true)] | |
[byte]$NetNum | |
) | |
$m = Measure-Cidr -Prefix $Prefix -NewBits $NewBits | |
$f = Convert-IpAddressStringToBinString $m.IP | |
# given the $NewBits parameter, determine the size of the new bits | |
# begin patched in. bin-format the $NetNum to the length of bits to replace | |
$d = $NewBits - $m.NetmaskBits | |
Write-Verbose ("d: {0}" -f $d) | |
$maxNets = $m.NumberOfNetworks | |
Write-Verbose ("NetNum: {0}, maxNets: {1}" -f $NetNum, $MaxNets) | |
if ($NetNum -ge $maxNets) { | |
throw ("NetNum must be <={0}" -f $maxNets) | |
} | |
$patch = ("{0}" -f [convert]::ToString($NetNum,2)).PadLeft($d,"0") | |
if ($d -eq 0) { | |
# if the same subnet length is requested, the patch is empty | |
$patch = "" | |
} | |
Write-Verbose ("f: {0}" -f $f) | |
Write-Verbose ("patch: {0}" -f $patch) | |
# combine the old net-part, patch and rest into new bitmask | |
$fPatched = $f.substring(0,$m.NetMaskBits) + $patch + $f.substring($NewBits, 32-$NewBits) | |
Write-Verbose ("Patch: {0} l:{1}" -f $fPatched, $fPatched.Length) | |
if ($fPatched.Length -ne 32) { | |
throw "Internal error" | |
} | |
# convert bitmask back into octet IP string | |
$result = Convert-IpAddressBinStringToString $fPatched | |
Write-Verbose ("RES: {0}" -f $result) | |
$result | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment