Blog Post

Core Infrastructure and Security Blog
3 MIN READ

Running PowerShell Against All Azure Subscriptions

PaulHarrison's avatar
PaulHarrison
Icon for Microsoft rankMicrosoft
May 13, 2021

 

Q: How do I run my PowerShell command against all my Azure subscriptions? 

A: Easy – Use the cmdlet I wrote when I ran into the same problem. 

  

When you go from one Azure subscription to two, three, or hundreds it is no longer trivial to run a single command against all your subscriptions in PowerShell.  I was working with one subscription that quickly expanded to three then soon more than a dozen. Opening new PowerShell hosts for each environment and switching between them was too much work. I needed an easy way to assess everything across all my subscriptions.  My solution was to write Invoke-AzureCommand.  Invoke-AzureCommand allows you to run a script block against every subscription easily.  To use it install AzureHelper, put your code in a script block, and run Invoke-AzureCommand to do the repetitive work of cycling the script block across all your subscriptions.  

 

Disclaimer: The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.  

  

1.  Install AzureHelper

To get started, install the AzureHelper module using the following command: 

 

 

Install-Module AzureHelper

 

 

If you prefer, you could also download it from GitHub here: www.GitHub.com/PaulHCode/AzureHelper 

 

2. Put your code in a script block

Put whatever commands you want to run against all of your subscriptions into a script block.  If you are new to script blocks check out more information on script blocks here. 

For example, I want to find all Azure Disks that are larger than 512 GB across my subscriptions.  To find these I put the following script block together. 

 

 

$DiskScriptBlock = {Get-AzDisk | Where{$_.DiskSizeGB -gt 512}} 

 

 

 

3. Run your script block against all subscriptions 

Running the script block against all subscriptions is as easy as the example below. 

 

 

Invoke-AzureCommand -AllSubscriptions -ScriptBlock $DiskScriptBlock | FT ResourceGroupName, Name, DiskSizeGB 

 

 

This example gives the output from every subscription, but if we have the same resource group name in multiple subscriptions then it isn’t clear which subscription contains the resource.  To fix that we use a named expression to include the name of the subscription as seen in the following example. 

  

Are you concerned about deallocated VMs sitting around that you don’t need anymore?  Use the following: 

 

 

$MyScriptBlock = {get-azvm -Status | Where{$_.PowerState -eq 'VM deallocated'} | Select Name, ResourceGroupName, @{N='Subscription';E={(Get-AzContext).Subscription.Name}}} 

Invoke-AzureCommand -ScriptBlock $MyScriptBlock -AllSubscriptions 

 

 

 

Okay, that sure makes a quick query easier but what if I want to do something a little more complex in my script block that needs arguments passed in?  I’m glad you asked.  Invoke-AzureCommand also supports passing an array of arguments into your scriptblock as seen in the example here. 

 

 

$ArgumentList = @() 
$ArgumentList+=512    # The first parameter is the minimum disk size 
$ArgumentList+="westus2"    # The second parameter is the Azure region to search 

$BetterDiskScriptBlock = { 
   param($disksize, $region) 
   Get-AzDisk | Where{$_.DiskSizeGB -gt $disksize} | Where{$_.Location -eq $region} 
}  

Invoke-AzureCommand -ScriptBlock $BetterDiskScriptBlock -AllSubscriptions -ArgumentList $ArgumentList 

 

 

 

You can make this example shorter by passing the arguments directly to Invoke-AzureCommand like this. 

 

 

Invoke-AzureCommand -ScriptBlock $BetterDiskScriptBlock -AllSubscriptions -ArgumentList 512,"westus2" 

 

 

 

Have fun scripting!

Updated May 14, 2021
Version 2.0