Public/Get-Subnet.ps1
function Get-Subnet { <# .SYNOPSIS Returns subnet details for the local IP address, or a given network address and mask. .DESCRIPTION Use to get subnet details for a given network address and mask, including network address, broadcast address, network class, address range, host addresses and host address count. .PARAMETER IP A metric object (generated by one of the Get-*Metric cmdlets from this module) which can be provided as pipeline input. .PARAMETER MaskBits The name of the measure to be updated or created. .PARAMETER Force Use to force the return of all host IP addresses regardless of the subnet size (skipped by default for subnets larger than /16). .EXAMPLE Get-Subnet 10.1.2.3/24 Description ----------- Returns the subnet details for the specified network and mask, specified as a single string to the -IP parameter. .EXAMPLE Get-Subnet 192.168.0.1 -MaskBits 23 Description ----------- Returns the subnet details for the specified network and mask. .EXAMPLE Get-Subnet Description ----------- Returns the subnet details for the current local IP. .EXAMPLE '10.1.2.3/24','10.1.2.4/24' | Get-Subnet Description ----------- Returns the subnet details for two specified networks. #> Param ( [parameter(ValueFromPipeline)] [string] $IP, [ValidateRange(0, 32)] [int] $MaskBits, [switch] $Force ) Process { If ($PSBoundParameters.ContainsKey('MaskBits')) { $Mask = $MaskBits } If (-not $IP) { $LocalIP = (Get-NetIPAddress | Where-Object { $_.AddressFamily -eq 'IPv4' -and $_.PrefixOrigin -ne 'WellKnown' }) $IP = $LocalIP.IPAddress If ($Mask -notin 0..32) { $Mask = $LocalIP.PrefixLength } } If ($IP -match '/\d') { $IPandMask = $IP -Split '/' $IP = $IPandMask[0] $Mask = $IPandMask[1] } $IPAddr = [Net.IPAddress]::Parse($IP) $Class = Switch ($IP.Split('.')[0]) { { $_ -in 0..127 } { 'A' } { $_ -in 128..191 } { 'B' } { $_ -in 192..223 } { 'C' } { $_ -in 224..239 } { 'D' } { $_ -in 240..255 } { 'E' } } If ($Mask -notin 0..32) { $Mask = Switch ($Class) { 'A' { 8 } 'B' { 16 } 'C' { 24 } default { Throw "Subnet mask size was not specified and could not be inferred because the address is Class $Class." } } Write-Warning "Subnet mask size was not specified. Using default subnet size for a Class $Class network of /$Mask." } $MaskAddr = [IPAddress]::Parse((Convert-Int64toIP -int ([convert]::ToInt64(("1" * $Mask + "0" * (32 - $Mask)), 2)))) $NetworkAddr = [IPAddress]($MaskAddr.address -band $IPAddr.address) $BroadcastAddr = [IPAddress](([IPAddress]::parse("255.255.255.255").address -bxor $MaskAddr.address -bor $NetworkAddr.address)) $HostStartAddr = (Convert-IPtoInt64 -ip $NetworkAddr.ipaddresstostring) + 1 $HostEndAddr = (Convert-IPtoInt64 -ip $broadcastaddr.ipaddresstostring) - 1 $HostAddressCount = ($HostEndAddr - $HostStartAddr) + 1 If ($Mask -ge 16 -or $Force) { Write-Progress "Calcualting host addresses for $NetworkAddr/$Mask.." $HostAddresses = for ($i = $HostStartAddr; $i -le $HostEndAddr; $i++) { Convert-Int64toIP -int $i } } Else { Write-Warning "Host address calculation was not performed because it would take some time for a /$Mask subnet. `nUse -Force if you want it to occur." } [pscustomobject]@{ IPAddress = $IPAddr MaskBits = $Mask NetworkAddress = $NetworkAddr BroadcastAddress = $broadcastaddr SubnetMask = $MaskAddr NetworkClass = $Class Range = "$networkaddr ~ $broadcastaddr" HostAddresses = $HostAddresses HostAddressCount = $HostAddressCount } } } |