Azure Automation – How to quickly work with many subscriptions

Lately, I have been writing various scripts to automate Azure tasks for our Zerto Training team. One of the unique things about deploying training labs at scale is that we use MANY Azure subscriptions in order to properly isolate and scale labs. So when a change needs to be made, we need to make the change to 100+ subscriptions.

In this post I’ll show you how to quickly automate tasks that need applied to many subscriptions.

Understanding a Context

When writing PowerShell Scripts with the “Az” or “AzureRM” PowerShell modules, a context is how you Azure knows which subscription the commands should affect.

Think: “If you run this command out of context it might not work.” Simply put, a context is a subscription.

Get and Set your Context

Scripting across multiple subscriptions is basically just a script that can switch its context when needed. In this example I will build a simple script to show all of the resource groups from all subscriptions in a single table.

First, let’s see what context we are in. Get-AzContext or Get-AzureRmContext will show your current context.

Get-AzContext Showing my current context

All of the commands I will run here are the new “Az” PowerShell module. if you have the AzureRM module, most commands are the same (just switch Az out for AzureRm), but some are different.

So if “Get-AzContext” will show our current context… “Set-AzContext” will change our current context! Very Simple isn’t it?

But! You need to pass which subscription you want to switch into to the Set-AzContext cmdlet. An easy way to do that is to pipe the output of Get-AzSubscription over to Set-AzContext.

Switching my Context to the “Sub115” subscription.

This allows we to pass the user friendly name of my subscription to Get-AzSubscription using the “SubscriptionName” parameter.

Now if I run a command it is applied to my subscription named “Sub115”.

Getting all resource groups in Sub115

As I said before, the example script will return all resource groups from all subscriptions into a table. The command in the screenshot above shows how to put the resource groups into a variable called $RGs and then later print that variable with table formatting.

I could manually change the context to each subscription and run the $RGs = Get-AzResourceGroups in each one… but that would take a while. We can use a foreach loop to automate this.

Looping through all your subscriptions

To use a for each loop we need a list of our subscriptions. Then we can put the commands we want to run in each subscription into the foreach loop. For this example it is pretty straightforward.

$RGs = @()
$Subscriptions = Get-AzSubscription
foreach ($sub in $Subscriptions) {
    Get-AzSubscription -SubscriptionName $sub.Name | Set-AzContext
    $RGs += Get-AzResourceGroup
$RGs | Ft

This code can take a little while to run if you have a lot of subscriptions. But eventually, you will get a nice formatted table with all your resource groups.

Tip: Make sure if you store data from a loop in a variable to be used outside of the foreach loop, that you declare those variables before the loop.

The completed script

Note that I “Ctrl-C” the script before it went through all 100+ subscriptions I have. But that was just so I got all output on one screen.

Use cases

Obviously, this example use case is only marginally helpful. Better use cases which I’ve used this basic “multi-subscription” layout for have been:

  • Creating Storage Accounts
  • Copying VHDs to above storage accounts
  • Giving user accounts specific roles and rights in each subscription
  • Deleting resources

Got any other use cases? Let us know in the comments below!


Share This Post

4 Responses to "Azure Automation – How to quickly work with many subscriptions"

  1. Clederson Eckstein · Edit

    Hello Justin, great post! Can you give an example how can I run through all the subscriptions and stop the VMs for example?

  2. An important tip!
    Be careful mixing Azure Shell and Powershell – eg. “az login” and “Connect-AzAccount”
    If you use “az login” it will not reflect on commands like Get-AzContext.
    So if you have powershell scripts that depend on Get-AzContext they’ll fail.

  3. How about using select-azsubscription and passing the context using -defaultprofile to Get-AzResourceGroup command? Isn’t that faster than Set-AzContext?

Post Comment