Manage virtual networks with PowerShell

Introduction

I got used to the Azure CLI quite quickly. The interface and sub-commands feel intuitiv, commands like create, list, show etc. can be used consistently. The Azure CLI makes it easy to explore the commands and paramters needed to configure resources I am unfamiliar with.

In contrast I am surprised how difficult it is to figure out how to do certain things using Azure PowerShell. Managing virtual networks with PowerShell is not complicated perse, however update-operations, like adding a new subnet to an existing vnet, doesn't come naturally (at least to me). It took me some time to figure things out, so I thought it might be worth sharing!

So let's go!

Relevant cmdlets

This are the cmdlets we are going to use

Get-Command -Noun AzVirtualNetwork

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Cmdlet          Get-AzVirtualNetwork                               2.5.0      az.network
Cmdlet          New-AzVirtualNetwork                               2.5.0      az.network
Cmdlet          Remove-AzVirtualNetwork                            2.5.0      az.network
Cmdlet          Set-AzVirtualNetwork                               2.5.0      az.network

And for the subnet configuration

Get-Command -Noun AzVirtualNetworkSubnetConfig

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Cmdlet          Add-AzVirtualNetworkSubnetConfig                   2.5.0      az.network
Cmdlet          Get-AzVirtualNetworkSubnetConfig                   2.5.0      az.network
Cmdlet          New-AzVirtualNetworkSubnetConfig                   2.5.0      az.network
Cmdlet          Remove-AzVirtualNetworkSubnetConfig                2.5.0      az.network
Cmdlet          Set-AzVirtualNetworkSubnetConfig                   2.5.0      az.network

Creating a new VNet

A VNet can't be created without a subnet. So we first instanciate a new PSSubnet object by using

$snet = New-AzVirtualNetworkSubnetConfig -Name snet-1 `
                                         -AddressPrefix 10.3.1.0/24  

This object does only exist in memory for now. We will use it to create the final vnet-resource.

New-AzVirtualNetwork -Name vnet-3 `
                     -ResourceGroupName rg-training `
                     -location switzerlandnorth `
                     -AddressPrefix 10.3.0.0/16 `
                     -Subnet $snet

The comannd will return with a ProvisioningState of Succeed if everything went fine. Please note that you can pass multiple PSSubnet instances to the -Subnet parameter to create many subnets at vnet-creation time.

$snet1 = New-AzVirtualNetworkSubnetConfig -Name snet-1 `
                                          -AddressPrefix 10.3.1.0/24                                        
$snet2 = New-AzVirtualNetworkSubnetConfig -Name snet-2 `
                                          -AddressPrefix 10.3.2.0/24                                                                                  
New-AzVirtualNetwork -Name vnet-3 `
                     -ResourceGroupName rg-training `
                     -location switzerlandnorth `
                     -AddressPrefix 10.3.0.0/16 `
                     -Subnet $snet1,$snet2       

List operations on VNets

Now let's double check if the vnet really got created as expected

Get-AzVirtualNetwork -Name vnet-3 `
                     -ResourceGroupName rg-training | Select-Object ProvisioningState

ProvisioningState
-----------------
Succeeded  

Okay great, there it is. Now let's see what subnets are part of our vnet.

Get-AzVirtualNetwork -Name vnet-3 `
                     -ResourceGroupName rg-training | Select-Object Subnets

Subnets
-------
{snet-1}  

Our subnet is there as expected. But uh, what again was the address space of the subnet?

$vnet = Get-AzVirtualNetwork -Name vnet-3
Get-AzVirtualNetworkSubnetConfig -Name snet-1 `
                                 -VirtualNetwork $vnet | Select-Object AddressPrefix

AddressPrefix
-------------
{10.3.1.0/24}

Add a subnet to an existing VNet

So far so good. But oh, we forgot to add an additional subnet. Let's catch up on that. That part is a bit tricky and unintuitiv (at least to me).

# Get vnet
$vnet = Get-AzVirtualNetwork -Name vnet-3 

# Get existing subnet
$snet1 = Get-AzVirtualNetworkSubnetConfig -Name snet-1 -VirtualNetwork $vnet 

# Create new subnet
$snet2 = New-AzVirtualNetworkSubnetConfig -Name snet-2 -AddressPrefix 10.3.2.0/24

# Overwrite resource 
New-AzVirtualNetwork -Name vnet-3 `
                     -ResourceGroup rg-training `
                     -Location switzerlandnorth `
                     -AddressPrefix 10.3.0.0/16 `
                     -Subnet $snet1,$snet2 | Set-AzVirtualNetwork 

It's kinda inconvenient that we first have to retrieve the existing subnets and then add them again later (together with an additional one). In case I find a simpler solution I will update this post.

Remove a subnet

Now let's clean up the mass we created...

$vnet = Get-AzVirtualNetwork -Name vnet-3 

Remove-AzVirtualNetworkSubnetConfig -Name snet-2 -VirtualNetwork $vnet

And it's gone...

Remove the entire VNet

Thats as easy as this

Remove-AzVirtualNetwork -Name vnet-3 -ResourceGroupName rg-training

Conclusion

It requires some practice to get used to Azure PowerShell and finding the right combination of cmdlets and parameters. To me it feels like Azure PowerShell is more targed towards automation and only automation. Where as Azure CLI can be more seen as a cli-remote-administration tool.

Happy hacking! 👾