Working with virtual machines using the Azure command line client
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 )
}