List all VNet and Subnets across multiple subscriptions

It has happened to everyone, the network sprawl. You might have on-premises networks and virtual networks, maybe even in multiple clouds, and at one point you simply have lost count of your ranges and what they are used for. Usually, these ranges come from someone that is responsible for IP-ranges (preferably an IPAM solution) but what if you have a lot of teams creating VNet in a bunch of subscriptions? Well, it can get out of hand quickly.

The script

If you are interested in learning how this script works, we’ll continue the blog post after the code. For those who just want to run the script, here you go:

Get-AzSubscription | Foreach-Object {
    $sub = Set-AzContext -SubscriptionId $_.SubscriptionId
    $vnets = Get-AzVirtualNetwork

    foreach ($vnet in $vnets) {
        [PSCustomObject]@{
            Subscription = $sub.Subscription.Name
            Name = $vnet.Name
            Vnet = $vnet.AddressSpace.AddressPrefixes -join ', '
            Subnets = $vnet.Subnets.AddressPrefix -join ', '
        }
    }
} | Export-Csv -Delimiter ";" -Path "AzureVnet.csv"

This will export the results to CSV, but if you don’t want that you can remove the last pipe and the cmdlet Export-Csv.

Note that you need to have the Az-module installed. You also have to be connected to Azure with an account that can at least read all the subscriptions and network resources.

How the script works

We start off by getting all the subscriptions available and running them one by one through a for each loop. So for every subscription, we set the active context to that subscription and populate the variable $vnets with all Virtual Networks in that subscription.

We run through another for each loop, where we create one new PSCustomObject per VNet in our $vnets variable. This is how we will represent our information, and the first couple of values makes sense. We set Subscription to the name of our current subscription, and the name of the Vnet as the Name field.

For our VNet address space and subnets, we could just point to the value from $vnet and be done with it. This works perfectly if you just want the results in the terminal. What I want, is to export this as a CSV so I can share this with whoever needs the list. If you try to export this value and it’s more than one, you will not get an IP range but the text System.Collections.Generic.List.

To get around this refer to the value we want, and use the join operator to join all the values together, separated by a comma. I also added a space after the comma to make it more readable. The VNet address space and the subnet can be multiple values, so I had to use the join operator for both of them.

Roberth Strand's Picture

About Roberth Strand

Cloud consultant working primarily with Microsoft Azure, automation and infrastructure.

Tromsø, Norway https://robstr.dev

Comments