This function will take an IP address and either a subnet mask, or a mask length, and return a custom object with information about that subnet. The information you get is basic stuff like network address, the first and the last usable addresses, the broadcast address etc. But it will also tell you the class of the address, as well as if it’s a private address or not. If run without any parameters it will try to get the needed information from the host you are running it on.
As always, if you discover any bugs, or have any ideas for future improvement, drop me a line in the comments section below!
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 Get-Ipv4SubnetInfo { | |
<# | |
.SYNOPSIS | |
Get subnet information. | |
.DESCRIPTION | |
This function will return basic subnet information if given an IP address as well as either | |
a subnet mask, or a mask length. | |
.EXAMPLE | |
Get-Ipv4SubnetInfo -IPAddress '10.10.10.1' -SubnetMask '255.255.0.0' | |
.EXAMPLE | |
Get-Ipv4SubnetInfo -IPAddress '192.168.0.4' -MaskLength 16 | |
.NOTES | |
Author: Øyvind Kallstad | |
Date: 28.04.2015 | |
Version: 1.0 | |
#> | |
[CmdletBinding(DefaultParameterSetName = 'SubnetMask')] | |
param ( | |
[Parameter()] | |
[IPAddress] $IPAddress = ([System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() | Where-Object {$_.OperationalStatus -eq 'Up' -and $_.NetworkInterfaceType -ne [System.Net.NetworkInformation.NetworkInterfaceType]::Loopback}).GetIPProperties().UnicastAddresses.Address.ToString(), | |
[Parameter(ParameterSetName = 'SubnetMask')] | |
[IPAddress] $SubnetMask = ([System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() | Where-Object {$_.OperationalStatus -eq 'Up' -and $_.NetworkInterfaceType -ne [System.Net.NetworkInformation.NetworkInterfaceType]::Loopback}).GetIPProperties().UnicastAddresses.IPv4Mask, | |
[Parameter(ParameterSetName = 'MaskLength')] | |
[ValidateRange(0,32)] | |
[int] $MaskLength | |
) | |
function ConvertTo-IPAddressUInt32 { | |
param ( | |
[Parameter()] | |
[ValidateNotNullOrEmpty()] | |
[string] $IPAddress | |
) | |
try { | |
$ip = [IPAddress]::Parse($IPAddress) | |
$ipBytes = $ip.GetAddressBytes() | |
[System.Array]::Reverse($ipBytes) | |
$output = [BitConverter]::ToUInt32($ipBytes,0) | |
} | |
catch { | |
Write-Warning $_.Exception.Message | |
} | |
Write-Output $output | |
} | |
function ConvertTo-IPAddress { | |
param ( | |
[Parameter()] | |
[ValidateRange([System.UInt32]::MinValue, [System.UInt32]::MaxValue)] | |
[uint32] $IPAddress | |
) | |
try { | |
$ipBytes = [BitConverter]::GetBytes($IPAddress) | |
[System.Array]::Reverse($ipBytes) | |
} | |
catch { | |
Write-Warning $_.Exception.Message | |
} | |
Write-Output ([IPAddress]$ipBytes) | |
} | |
function Get-IPv4AddressClass { | |
[CmdletBinding()] | |
param ( | |
[Parameter(Position = 0)] | |
[IPAddress] $IPAddress | |
) | |
$ipBinary = ($IPAddress.GetAddressBytes() | ForEach-Object {[Convert]::ToString($_,2).PadLeft(8, '0') }) -join '' | |
switch –Regex ($ipBinary) { | |
'^1111' {$class = 'E';break} | |
'^1110' {$class = 'D';break} | |
'^110' {$class = 'C';break} | |
'^10' {$class = 'B';break} | |
'^0' {$class = 'A';break} | |
} | |
Write-Output $class | |
} | |
function Test-Ipv4IsPrivate { | |
[CmdletBinding()] | |
param ( | |
[Parameter(Position = 0)] | |
[IPAddress] $IPAddress | |
) | |
$private = $false | |
$ipBinary = ($IPAddress.GetAddressBytes() | ForEach-Object {[Convert]::ToString($_,2).PadLeft(8, '0') }) -join '' | |
if (($ipBinary -match '^1100000010101000') -or ($ipBinary -match '^101011000001') -or ($ipBinary -match '^0000101')) { | |
$private = $true | |
} | |
Write-Output $private | |
} | |
if ($PSCmdlet.ParameterSetName -eq 'SubnetMask') { | |
# convert the subnetmask to uint32 | |
$smUint32 = ConvertTo-IPAddressUInt32 –IPAddress $SubnetMask | |
# calculate mask length (CIDR) by converting the subnetmask to binary and counting the 1s | |
$SubnetMask.GetAddressBytes() | ForEach-Object {$cidr += [Convert]::ToString($_,2)} | |
$MaskLength = $cidr.TrimEnd('0').Length | |
} | |
else { | |
# create the subnetmask from the mask length, and convert to uint32 | |
$smUint32 = [Convert]::ToUInt32($(('1' * $MaskLength).PadRight(32, '0')), 2) | |
$SubnetMask = ConvertTo-IPAddress –IPAddress $smUint32 | |
} | |
# convert the IP address | |
$ipUint32 = ConvertTo-IPAddressUInt32 –IPAddress $IPAddress | |
# calculate the network and broadcast addresses of the subnet | |
$networkAddress = $ipUint32 -band $smUint32 | |
$broadcastAddress = $ipUint32 -bor ((-bnot $smUint32) -band [UInt32]::MaxValue) | |
# calculate the first and the last address in the subnet | |
$firstIP = $networkAddress + 1 | |
$lastIP = $broadcastAddress – 1 | |
$usableAddresses = $lastIP – $networkAddress | |
Write-Output ([PSCustomObject] [Ordered] @{ | |
NetworkAddress = (ConvertTo-IPAddress –IPAddress $networkAddress) | |
SubnetMask = $SubnetMask | |
FirstAddress = (ConvertTo-IPAddress –IPAddress $firstIP) | |
LastAddress = (ConvertTo-IPAddress –IPAddress $lastIP) | |
BroadcastAddress = (ConvertTo-IPAddress –IPAddress $broadcastAddress) | |
UsableAddresses = $usableAddresses | |
MaskLength = $MaskLength | |
AddressClass = (Get-IPv4AddressClass –IPAddress $IPAddress) | |
IsPrivate = (Test-Ipv4IsPrivate –IPAddress $IPAddress) | |
}) | |
} |