Private/ConvertTo-NSPConditionalAccessCidr.ps1
|
function ConvertTo-NSPConditionalAccessCidr { <# .SYNOPSIS Validates an IP range typed by an operator and returns it as CIDR, with its Graph range type and any concerns. .DESCRIPTION A bare address becomes a single-address range (/32 or /128). Throws on anything that is not an IPv4 or IPv6 address with an optional prefix length. Concerns are returned, not thrown: a private or reserved address (Entra only ever sees the public address a sign-in comes from), and a very broad range (IPv4 /16 or wider, IPv6 /32 or wider). #> [CmdletBinding()] param( [Parameter(Mandatory)][string]$Range ) $text = $Range.Trim() $address, $prefix = $text -split '/', 2 $ip = $null if (-not [System.Net.IPAddress]::TryParse($address, [ref]$ip)) { throw "'$Range' is not an IP address or CIDR range (for example 203.0.113.10 or 203.0.113.0/24)." } $v6 = $ip.AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetworkV6 $max = if ($v6) { 128 } else { 32 } $length = $max if ($null -ne $prefix -and $prefix -ne '') { if (-not [int]::TryParse($prefix, [ref]$length) -or $length -lt 1 -or $length -gt $max) { throw "'$Range' has an invalid prefix length; use 1 to $max." } } $concerns = [System.Collections.Generic.List[string]]::new() if (-not $v6) { $bytes = $ip.GetAddressBytes() $private = $bytes[0] -eq 10 -or $bytes[0] -eq 127 -or ($bytes[0] -eq 172 -and $bytes[1] -ge 16 -and $bytes[1] -le 31) -or ($bytes[0] -eq 192 -and $bytes[1] -eq 168) -or ($bytes[0] -eq 169 -and $bytes[1] -eq 254) -or ($bytes[0] -eq 100 -and $bytes[1] -ge 64 -and $bytes[1] -le 127) if ($private) { $concerns.Add("$text is a private or reserved address. Entra sees the office's public address, not this one.") } if ($length -le 16) { $concerns.Add("$text is very broad ($([math]::Pow(2, 32 - $length)) addresses). Trust only the office's own public addresses.") } } else { if ($text -match '^(?i)(fe80|fc|fd|::1)') { $concerns.Add("$text is a link-local or private IPv6 address. Entra sees the public address.") } if ($length -le 32) { $concerns.Add("$text is a very broad IPv6 range. Trust only the office's own prefix.") } } [pscustomobject]@{ Cidr = "$($ip.ToString())/$length" Type = if ($v6) { '#microsoft.graph.iPv6CidrRange' } else { '#microsoft.graph.iPv4CidrRange' } Concerns = @($concerns) } } |