29. January 2010
Andy Schneider
This is actually a fairly simple task that many people have done in many different languages. However, I thought it would be useful to share for the sake of showing how .NET can do a lot of tedious work for us.
IP Addresses are made up of 32 bits. Subnet masks are 32 bits as well. The subnet mask is what is used to determine where the Network ID ends and the host ID begins. Masks must have contiguous 1’s. If there is a 1 in the mask, then the corresponding bit in the IP Address is part of the Network ID. If there is 0 in the mask, the corresponding bit in the IP Address is part of the host ID.
So obviously there is going to be a lot of binary math, which any good network engineer can do. However, if you can get it for free, even better!
There is a type in .NET called System.Net.IPAddress that has several useful properties. The one I will focus on is Address.

Using the Address property and some bitwise operators in PowerShell, we can come up with a function pretty quickly. The –and and –or operators are pretty commonplace in the world of PowerShell but there is occasionally a need to do a compare of two numbers at the bit level. This is done with the –band and –bor operators. I may be off but if memory serves, using –bor and –band you can build any other bit function like xor. I won’t event think about K-maps.
So with all that, here is some code:
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020
| Function Test-SameSubnet { param ( [parameter(Mandatory=$true)] [Net.IPAddress] $ip1, [parameter(Mandatory=$true)] [Net.IPAddress] $ip2, [parameter()] [alias("SubnetMask")] [Net.IPAddress] $mask ="255.255.255.0" ) if (($ip1.address -band $mask.address) -eq ($ip2.address -band $mask.address)) {$true} else {$false} } |
The Address property is the binary number that represents the IP Address. Doing a bitwise AND with a mask will tell us if they are in the same subnet. I have a default value of 255.255.255.0 for the mask, or /24 if you prefer CIDR notation, but you can specify it as a parameter if you like.
