Over the past 8 months I have gethered quite a few useful snippets for interacting with Azure VMs from the az command-line client. This is a summary of them.

Listing VMs

List all VMs and their OS:

az vm list --query "[].{Name:name,OS:storageProfile.osDisk.osType}" -o table

Same but limited to a specific resource group:

az vm list --resource-group MY-RG --query "[].{Name:name,OS:storageProfile.osDisk.osType}" -o table

List VMs with IP addresses and status, slower due to needing -d (short-form of --show-details):

az vm list -d --query "[].{Name:name,OS:storageProfile.osDisk.osType,Status:powerState,PrivateIPs:privateIps,PublicIPs:publicIps}" -o table

List VMs with their size:

az vm list --query "[].{Name:name,Size:hardwareProfile.vmSize}" -o table 

List each VM size with the number of that size (based on: https://samcogan.com/audit-your-azure-resources-with-resource-graph/):

az graph query -q "where type =~ 'Microsoft.Compute/virtualMachines' | project SKU = tostring(properties.hardwareProfile.vmSize) | summarize count() by SKU" --output table 

List just the Linux VMs:

az vm list -d --query "[?storageProfile.osDisk.osType=='Linux'].{Name:name,OS:storageProfile.osDisk.osType,Status:powerState,PrivateIPs:privateIps,PublicIPs:publicIps}" -o table 

Manipulating VMs

Start all non-started Windows VMs

az vm start --ids $( az vm list -d --query "[?storageProfile.osDisk.osType=='Windows' && powerState!='VM running'].id" -o tsv )

Start all non-started Linux VMs:

az vm start --ids $( az vm list -d --query "[?storageProfile.osDisk.osType=='Linux' && powerState!='VM running'].id" -o tsv )

Get a list of all non-started Linux VMs, start them, do some work then stop the ones that were off again (in PowerShell):

$off_linux_ids=(az vm list -d --query "[?storageProfile.osDisk.osType=='Linux' && powerState!='VM running'].id" -o tsv)
$all_linux_ids=(az vm list -d --query "[?storageProfile.osDisk.osType=='Linux'].id" -o tsv)
az vm start --ids $off_linux_ids

# Do work here, once VMs have started

az vm deallocate --ids $off_linux_ids

Updated azureuser password on running Windows machines:

$windows_ids=(az vm list -d --query "[?storageProfile.osDisk.osType=='Windows' && powerState=='VM running'].id" -o tsv) 

az vm user update -u azureuser -p 'newpassword' --ids $windows_ids

Or to run an arbitary (PowerShell) command:

az vm run-command invoke --command-id RunPowerShellScript --ids $windows_ids --scripts 'param([string]$target_host,[int]$target_port); Test-NetConnection -ComputerName $target_host -Port $target_port' --parameters 'target_host=10.91.44.68' 'target_port=1715'

Same for Linux:

$linux_ids=(az vm list -d --query "[?storageProfile.osDisk.osType=='Linux' && powerState=='VM running'].id" -o tsv) 

az vm user update -u azureuser -p 'newpassword' --ids $linux_ids

Or to run an arbitary (BASH) command:

az vm run-command invoke --command-id RunShellScript  --ids $linux_ids --scripts 'nc -z -v $1 $2' --parameters '10.91.44.68' 1715 

Listing users and roles

Find a user’s object id:

az ad user show --id "user@my.domain.tld" --query "objectId" --output tsv

Find group’s object ID:

az ad group show --group "Group-Name" --query "objectId" --output tsv 

List all roles:

az role definition list --query "[].{name:name, roleType:roleType, roleName:roleName}" --output tsv

List a specific role:

az role definition list --name "Owner" 

Manipulating users and roles

Assign a role to a user or group (principal can be at least a user objectId, a group objectId or a principal name of the form “user@my.domain.tld”):

az role assignment create --assignee "principal" --role "Virtual Machine User" --scope "$( az vm list --query "[?name=='VM-NAME'].id" -o tsv )"

az role assignment create does not allow us to assign the same role to a single principal into multiple scopes at once, so a loop is required to do this. For example, to assign the role Virtual Machine User to a group for the VMs with names WEAZHPC[18-25] this should work:

$group=az ad group show --group "My-Group" --query "objectId" --output tsv 

for($i=18; $i -lt 26; $i++) { 
    az role assignment create --assignee $group --role "Virtual Machine User" --scope $( az vm list --query "[?name=='WEAZHPC$i'].id" -o tsv )
}