Those of us that have tried to manipulate IPv4 information in Powershell know that out of the box, it isn’t the easiest thing to do. Problem is that in calculating IPv4 information such as broadcast address, network address, and host range properly, you have to manipulate it in it’s 32-bit form, and not its integer format.
After having to do this the hard way a few times, I decided to write a script that I could use for a wide array of scenarios to get this information, and now I’m passing the time savings onto you!
You can use either CIDR notation (e.g. 192.168.1.1/24) or IP address and subnet mask to get an object that contains info on the network.
1 2 3 4 5 6 7 8 9 10 |
PS C:\> Get-IPv4NetworkInfo -CIDRAddress 192.168.1.12/24 IPAddress : 192.168.1.12 SubnetMask : 255.255.255.0 NetworkAddress : 192.168.1.0 BroadcastAddress : 192.168.1.255 WildcardMask : 0.0.0.255 NumberOfHostIPs : 254 IPRange : {} |
If I want the output object to also contain an array of IPs within that network, I can use the -IncludeIPRange switch parameter:
1 2 3 4 5 6 7 8 9 |
PS C:\> Get-IPv4NetworkInfo -CIDRAddress 192.168.1.12/24 -IncludeIPRange IPAddress : 192.168.1.12 SubnetMask : 255.255.255.0 NetworkAddress : 192.168.1.0 BroadcastAddress : 192.168.1.255 WildcardMask : 0.0.0.255 NumberOfHostIPs : 254 IPRange : {192.168.1.1, 192.168.1.2, 192.168.1.3, 192.168.1.4...} |
The Script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
<# .SYNOPSIS Gets extended information about an IPv4 network. .DESCRIPTION Gets Network Address, Broadcast Address, Wildcard Mask. and usable host range for a network given the IP address and Subnet Mask. .PARAMETER IPAddress IP Address of any ip within the network Note: Exclusive from @CIDRAddress .PARAMETER SubnetMask Subnet Mask of the network. Note: Exclusive from @CIDRAddress .PARAMETER CIDRAddress CIDR Notation of IP/Subnet Mask (x.x.x.x/y) Note: Exclusive from @IPAddress and @SubnetMask .PARAMETER IncludeIPRange Switch parameter that defines whether or not the script will return an array of usable host IP addresses within the defined network. Note: This parameter can cause delays in script completion for larger subnets. .EXAMPLE Get-IPv4NetworkInfo -IPAddress 192.168.1.23 -SubnetMask 255.255.255.0 Get network information with IP Address and Subnet Mask .EXAMPLE Get-IPv4NetworkInfo -CIDRAddress 192.168.1.23/24 Get network information with CIDR Notation .NOTES File Name : Get-IPv4NetworkInfo.ps1 Author : Ryan Drane Date : 5/10/16 Requires : PowerShell v3 .LINK www.ryandrane.com #> Function Get-IPv4NetworkInfo { Param ( [Parameter(ParameterSetName="IPandMask",Mandatory=$true)] [ValidateScript({$_ -match [ipaddress]$_})] [System.String]$IPAddress, [Parameter(ParameterSetName="IPandMask",Mandatory=$true)] [ValidateScript({$_ -match [ipaddress]$_})] [System.String]$SubnetMask, [Parameter(ParameterSetName="CIDR",Mandatory=$true)] [ValidateScript({$_ -match '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/([0-9]|[0-2][0-9]|3[0-2])$'})] [System.String]$CIDRAddress, [Switch]$IncludeIPRange ) # If @CIDRAddress is set if($CIDRAddress) { # Separate our IP address, from subnet bit count $IPAddress, [int32]$MaskBits = $CIDRAddress.Split('/') # Create array to hold our output mask $CIDRMask = @() # For loop to run through each octet, for($j = 0; $j -lt 4; $j++) { # If there are 8 or more bits left if($MaskBits -gt 7) { # Add 255 to mask array, and subtract 8 bits $CIDRMask += [byte]255 $MaskBits -= 8 } else { # bits are less than 8, calculate octet bits and # zero out our $MaskBits variable. $CIDRMask += [byte]255 -shl (8 - $MaskBits) $MaskBits = 0 } } # Assign our newly created mask to the SubnetMask variable $SubnetMask = $CIDRMask -join '.' } # Get Arrays of [Byte] objects, one for each octet in our IP and Mask $IPAddressBytes = ([ipaddress]::Parse($IPAddress)).GetAddressBytes() $SubnetMaskBytes = ([ipaddress]::Parse($SubnetMask)).GetAddressBytes() # Declare empty arrays to hold output $NetworkAddressBytes = @() $BroadcastAddressBytes = @() $WildcardMaskBytes = @() # Determine Broadcast / Network Addresses, as well as Wildcard Mask for($i = 0; $i -lt 4; $i++) { # Compare each Octet in the host IP to the Mask using bitwise # to obtain our Network Address $NetworkAddressBytes += $IPAddressBytes[$i] -band $SubnetMaskBytes[$i] # Compare each Octet in the subnet mask to 255 to get our wildcard mask $WildcardMaskBytes += $SubnetMaskBytes[$i] -bxor 255 # Compare each octet in network address to wildcard mask to get broadcast. $BroadcastAddressBytes += $NetworkAddressBytes[$i] -bxor $WildcardMaskBytes[$i] } # Create variables to hold our NetworkAddress, WildcardMask, BroadcastAddress $NetworkAddress = $NetworkAddressBytes -join '.' $BroadcastAddress = $BroadcastAddressBytes -join '.' $WildcardMask = $WildcardMaskBytes -join '.' # Now that we have our Network, Widcard, and broadcast information, # We need to reverse the byte order in our Network and Broadcast addresses [array]::Reverse($NetworkAddressBytes) [array]::Reverse($BroadcastAddressBytes) # We also need to reverse the array of our IP address in order to get its # integer representation [array]::Reverse($IPAddressBytes) # Next we convert them both to 32-bit integers $NetworkAddressInt = [System.BitConverter]::ToUInt32($NetworkAddressBytes,0) $BroadcastAddressInt = [System.BitConverter]::ToUInt32($BroadcastAddressBytes,0) $IPAddressInt = [System.BitConverter]::ToUInt32($IPAddressBytes,0) #Calculate the number of hosts in our subnet, subtracting one to account for network address. $NumberOfHosts = ($BroadcastAddressInt - $NetworkAddressInt) - 1 # Declare an empty array to hold our range of usable IPs. $IPRange = @() # If -IncludeIPRange specified, calculate it if ($IncludeIPRange) { # Now run through our IP range and figure out the IP address for each. For ($j = 1; $j -le $NumberOfHosts; $j++) { # Increment Network Address by our counter variable, then convert back # lto an IP address and extract as string, add to IPRange output array. $IPRange +=[ipaddress]([convert]::ToDouble($NetworkAddressInt + $j)) | Select-Object -ExpandProperty IPAddressToString } } # Create our output object $obj = New-Object -TypeName psobject # Add our properties to it Add-Member -InputObject $obj -MemberType NoteProperty -Name "IPAddress" -Value $IPAddress Add-Member -InputObject $obj -MemberType NoteProperty -Name "SubnetMask" -Value $SubnetMask Add-Member -InputObject $obj -MemberType NoteProperty -Name "NetworkAddress" -Value $NetworkAddress Add-Member -InputObject $obj -MemberType NoteProperty -Name "BroadcastAddress" -Value $BroadcastAddress Add-Member -InputObject $obj -MemberType NoteProperty -Name "WildcardMask" -Value $WildcardMask Add-Member -InputObject $obj -MemberType NoteProperty -Name "NumberOfHostIPs" -Value $NumberOfHosts Add-Member -InputObject $obj -MemberType NoteProperty -Name "IPRange" -Value $IPRange # Return the object return $obj } |
Hope this helps, and happy scripting!