Powershell to Validate IP Configuration (Address, Gateway, Subnet Mask, DNS)

I'm working on a VM deployment script for one of my customers.  As you might expect, input validation is incredibly important, as we want to filter out a malformed configuration before starting the actual deployment.  To that end, I put together a bit of PowerShell that I'm pretty proud of; this script does a basic sanity check on a network configuration.

It does a fair amount of work.  Firstly, it checks to ensure that the IP Address, Gateway, Subnet Mask, and all DNS Servers are being supplied as valid IP addresses.  PowerShell makes this trivial to do, as you can cast a string as an [ipaddress] object and PowerShell will parse it for you.  If it's a string that can't be parsed (such as [ipaddress]"JasonIsAwesome!" which is a string that most people would agree is inherently incomprehensible*), it'll throw an Exception and thus end the execution of the script.  So, that most basic input validation is over in a blink... but wait, there's more!

Since we're doing input validation, we should verify that the IP Address can actually communicate with the provided Gateway.  To do that, we had to understand the subnet that the given IP and Gateway were using.  Fortunately, once again, this is a really easy thing to figure out in PowerShell.  You can use bitwise-and to basically just apply the subnet mask to a given IP Address, thus extracting the subnet without having to do any weird math if dealing with a non-standard subnet mask like 255.255.252.0.  So, we very easily get the subnets for both the supplied IP and Gateway, then just make sure that they're the same.  But wait, there's more!

What if we have an invalid Subnet Mask?  Not all x.x.x.x sequences that are valid IP Addresses are valid Subnet Masks, so the script does a bit of work to convert the subnet mask into its binary string, then it checks the length of that string (to ensure that it's 32 characters) and does some quick regex magic to ensure that it starts with a sequence of 1s that is followed by a sequence of 0s that ends the string (which means that it's a valid netmask).  Then, since we've already got the subnet mask stored in a binary representation, I figured that I'd go ahead and just extract the CIDR value for that netmask (which can be handy, as cmdlets like New-NetIPAddress take that CIDR value for the -PrefixLength parameter).

Finally, the script repeats the [ipaddress] casting trick in order to validate that the supplied addresses for the DNS Servers are all valid.  Assuming everything checks out, the script returns the subnet's CIDR notation, otherwise it returns a (hopefully) helpful error message about what didn't check out!

Well, if you want to check out the script, it's on my github!  Remember, this is posted for education purposes.  Make sure that you fully understand what any code does before you execute it, and there's no implied warranty or guaranty that anything will work.  Also, have fun!

*That is a bit of an inside joke that only two other people in the whole world are likely to get; sorry everyone else!

Comments

Popular posts from this blog

PowerShell Sorting by Multiple Columns

Clone a Standard vSwitch from one ESXi Host to Another

Deleting Orphaned (AKA Zombie) VMDK Files