Blog Post

Core Infrastructure and Security Blog
4 MIN READ

Azure PowerShell Tips and Tricks

PaulHarrison's avatar
PaulHarrison
Icon for Microsoft rankMicrosoft
Mar 11, 2024

 

I’ve spent most of my days lately writing PowerShell and using REST APIs as part of my work in Azure.  When I’m screen sharing with colleagues, I frequently learn different and better ways to do my work. This post is to share with you several tips and tricks I’ve shared with my colleagues, and I hope helps you shave minutes or hours off of your work.

 

Use ConvertTo-JSON to more easily read output.

When I’m working with a new object in Azure I often don’t know where the information I care about is actually found in output. PowerShell makes it easy to navigate through objects, however it isn’t easy to get an overview of all properties available if they’re nested 5 levels deep. I like to use ConvertTo-JSON to help me get a general understanding for a new object and which properties are available and how to find them.

For example, if I wasn’t familiar with storage accounts, I might create a test one to look at, or look at others in an existing environment like this:

$SAs = Get-AzStorageAccount

$SAs[0]

That gives me some basic output, but not the details as seen below.

It is common to use Format-List to provide more verbose output as seen here.

Unfortunately, it is common in many resources I’ve worked with in Azure for the information I care about to be buried several layers deep, like in a child property of Sku.

Fortunately, an easy way to get a quick view of an object is to use ConvertTo-JSON. This converts the whole object into JSON for easy viewing, especially if you have a good viewer like VSCode. For example, I would run the following, then paste the results into VSCode for easy viewing.

$SAs[0] | ConvertTo-Json | Set-Clipboard

With the object in VSCode it is much easier for me to then run a search for the property I’m interested in. For example, If I wanted to find where it was telling me that it was using LRS, I could just search for “LRS” and immediately see that I could later reference that in code as $SAs[0].Sku.Name.

 

Use Group-Object to summarize information.

  1. I often analyze Azure tenants with many resources. A short query in PowerShell can make certain analysis take only seconds. Someone wanted a list of every resource type deployed to the environment.

 

Get-AzResource | group type | select count, name

 

I was then told he actually wanted a list of every resource type deployed, but broken down by subscription.

 

get-azresource | group subscriptionid, type | select count,name

 

Group-Object certainly makes life easier.

 

Use named expressions to quickly get useful information that wasn’t returned exactly as you want.

We wanted to validate our storage accounts were all properly configured with the SKU we expected. We couldn’t just group on the Sku Name though because it wasn’t a top-level property returned. I am frequently given the information I want, just not exactly how I want it.

 

Get-AzStorageAccount | select @{N='SkuName';e={$_.Sku.Name}} | group skuname | select count,name

 

Count Name

----- ----

    1 Standard_GRS

    8 Standard_LRS

 

Oh no, we found a few using LRS, which ones are they:

(Get-AzStorageAccount | select id,@{N='SkuName';e={$_.Sku.Name}} | group skuname | where{$_.name -eq 'Standard_LRS'}).group.id

 

Named expressions are perfect for making the data just the way I like it.

 

Using a hash table makes lookups faster and easier.

  1. I’ll frequently get back resource data that includes a resource ID, but humans that I send information to like to see the subscription name, not an ID. If I’m looking up thousands of resources then I don’t want to do thousands of queries to lookup a subscription either, that just takes too long. Hash tables are my friend to solve this problem.

I first put every subscription ID and name into a hashtable, then I can do a lookup anytime I like to get pretty output.

$subs = Get-AzSubscription | %{@{$_.id = $_.Name}}

$allVMs = Get-AzVM

$allVMs | select location, @{n='sub';e={$_.id.split('/')[2]}} | select location, @{n='subName';E={$subs."$($_.sub)"}} | group location, subname | select count,name

 

Count  Name

78         eastus, Subscription0

2            eastus, Subscription1

3            eastus, Subscription2

2            eastus, Subscription3

94         southeastasia, Subscription4

50         westeurope, Subscription5

1            westus, Subscription6

100       westus2, Subscription7

 

Use Get-AzProviderOperation to determine which permissions are available for a particular provider.

  1. Setting the permissions to the minimum required, and not more for your Entra ID identities is very important. I generally know what permissions I want to assign to an identity, but don’t always know what it is called which is where Get-AzProviderOperation comes in.

When I wanted to grant access to a key vault, I queried to find exactly which permission I should use. I wanted to make sure that the ID could read metadata, but not the actual secrets.

Get-AzProviderOperation "Microsoft.KeyVault/vaults/secrets/*" | ft

After looking at this output I was quickly able to determine that I needed to request “Microsoft.KeyVault/vaults/secrets/readMetadata/action” for my identity.

 

I hope you were able to find a useful tidbit to help you in your work.

 

Have fun scripting!

 

References:

Updated Feb 25, 2024
Version 1.0
No CommentsBe the first to comment