IP Subnet Calculator using Powershell
Often during automation we run into scenarios where we have a large IP range and we would want to automate the subnetting of this large IP range into smaller subnets and then filter the ranges that are already in use. In most cases I have seen calculations being done manually and hard coding these ranges into the code or storing the ranges in some database. The downside of this approach is that the subnetting either with hard coded values or values stored in a database can be out of sync due to manual deployments done outside of the automation.
Let us see how we can automate subnetting and avoid hard coding values in code. We would need the following steps
- Calculate subnets with desired CIDR ranges for a larger IP address range
- Scan the environment for used IP ranges. example, Scan through subscriptions for Virtual Networks and Address ranges used by them
- Filter the used IP ranges from the list of calculated IP subnets in step 1.
Let us see if there is an easy way we can calculate subnet range using Powershell. Recently I wrote an “Azure function” to which if an IP Address, its CIDR range is passed along with the subnet range you want to divide the large range into, it would give you a list of subnets. Let us say the IP address is “192.168.0.0” and the CIDR is “18” the number of IP addresses in this range are 16,384. If you want to divide this range into a CIDR range “19” there would be two ranges that can be carved out of “192.68.0.0/18” which would be “192.168.0.0/19” and “192.168.32.0/19”. Instead of calculating these manually using a subnet calculators available online or doing the complex mathematics manually, you can make a web request to my online subnet calculator. Sample code could be
(Invoke-webrequest "https://ipsubnet.lessergeek.com/api/calculate?IpAddress=192.168.0.0&CIDR=18&NEWCIDR=19").Content | ConvertFrom-Json | ft
The output you would receive is
Similarly if the larger range “192.168.0.0/18” needs to be broken down into CIDR 24, the sample code would be
(Invoke-webrequest "https://ipsubnet.lessergeek.com/api/calculate?IpAddress=192.168.0.0&CIDR=18&NEWCIDR=24").Content | ConvertFrom-Json | ft
The output would be
This makes it easy for you to sub divide a large IP range into smaller subnets.
Now let us go through the second step. You have used some IP addresses already, example you have deployed virtual networks in Azure and you want to find out the next available non-overlapping IP range that can be used. The following code can be used to fetch IP address range used by virtual networks. The following Code can fetch IP addresses used by all virtual networks in the current context.
$addressesUsed = (Get-azVirtualNetwork ).AddressSpace.AddressPrefixes
You can also browse through multiple subscriptions of tenants and build a list of IP addresses in use by first getting all the subscriptions and tenants you have access to, then switching context to each subscription one at a time and getting the IP address ranges used by each virtual network. Sample code shown below
$Subscriptions = Get-azSubscription
$addressesUsed = @()
foreach($subscription in $Subscriptions){
Set-azContext $Subscription.id
$addressesUsed += (Get-azVirtualNetwork ).AddressSpace.AddressPrefixes
}
You can also build an array of used IP addresses manually. Let us say the used address ranges are as shown below
$addressesUsed = ("192.168.0.0","192.168.3.0", "192.168.2.0")
Using the web request let us fetch and populate the range array
$range = ((Invoke-webrequest "https://ipsubnet.lessergeek.com/api/calculate?IpAddress=192.168.0.0&CIDR=18&NEWCIDR=24").Content | ConvertFrom-Json )
To get the first unused IP range filtered you can simply run the following command
$range.Ipaddress | Where-Object {$_ -notin $addressesUsed} | select -first 1
The output you should get is
192.168.1.0
This can be used to create a new network with IP range “192.168.1.0/24”. Once the range is in use running the above code again should give you the next available IP as
192.168.4.0
By now we have figured how we can create an end-to-end automation in 3 easy steps
- Sub divide a large range into smaller subnets using web request
- Dynamically populate an array of IP addresses in use.
- Filter the used IP address from the range and get the first available IP range that is free.
Note: The Azure Function should remain available to enable your automation. However if you need to get the IP subnetting code you can send me an email and I would be happy to share the code which is written in Powershell code.