Azure Virtual Machines — CLI & PowerShell Cheat Sheet

IntermediateCheat Sheet15 min6 min read20 Jan 2025Azure

Must-know Azure CLI and PowerShell commands for creating, managing, scaling, and troubleshooting Azure Virtual Machines.

VM Lifecycle

Create a VM (Azure CLI)

# Basic Linux VM
az vm create \
  --resource-group myRG \
  --name myVM \
  --image Ubuntu2204 \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --location eastus

# Windows VM with password auth
az vm create \
  --resource-group myRG \
  --name myWinVM \
  --image Win2022Datacenter \
  --size Standard_D2s_v3 \
  --admin-username azureuser \
  --admin-password "P@ssword1234!" \
  --location eastus

# VM in existing VNet/subnet
az vm create \
  --resource-group myRG \
  --name myVM \
  --image Ubuntu2204 \
  --vnet-name myVNet \
  --subnet mySubnet \
  --public-ip-address "" \
  --nsg ""

Create a VM (PowerShell)

# Basic VM
New-AzVM `
  -ResourceGroupName "myRG" `
  -Name "myVM" `
  -Location "EastUS" `
  -Image "Ubuntu2204" `
  -Size "Standard_B2s" `
  -Credential (Get-Credential)

# Detailed VM config
$vmConfig = New-AzVMConfig -VMName "myVM" -VMSize "Standard_D2s_v3"
$vmConfig = Set-AzVMOperatingSystem -VM $vmConfig -Linux -ComputerName "myVM" -Credential (Get-Credential)
$vmConfig = Set-AzVMSourceImage -VM $vmConfig -PublisherName "Canonical" -Offer "0001-com-ubuntu-server-jammy" -Skus "22_04-lts" -Version "latest"
New-AzVM -ResourceGroupName "myRG" -Location "EastUS" -VM $vmConfig

Start / Stop / Deallocate

# Stop (keeps compute allocation — still billed)
az vm stop --resource-group myRG --name myVM

# Deallocate (releases compute — not billed for compute)
az vm deallocate --resource-group myRG --name myVM

# Start
az vm start --resource-group myRG --name myVM

# Restart
az vm restart --resource-group myRG --name myVM

# Delete
az vm delete --resource-group myRG --name myVM --yes

# Bulk deallocate all VMs in a resource group
az vm deallocate --ids $(az vm list -g myRG --query "[].id" -o tsv)
Stop-AzVM -ResourceGroupName "myRG" -Name "myVM"
Start-AzVM -ResourceGroupName "myRG" -Name "myVM"
Restart-AzVM -ResourceGroupName "myRG" -Name "myVM"
Remove-AzVM -ResourceGroupName "myRG" -Name "myVM"

Listing and Querying

# List all VMs in subscription
az vm list --output table

# List VMs in a resource group
az vm list --resource-group myRG --output table

# Show VM details
az vm show --resource-group myRG --name myVM

# Get VM status (running / deallocated)
az vm get-instance-view --resource-group myRG --name myVM \
  --query "instanceView.statuses[1].displayStatus" -o tsv

# List available VM sizes in a region
az vm list-sizes --location eastus --output table

# List all available images
az vm image list --publisher Canonical --output table --all
Get-AzVM
Get-AzVM -ResourceGroupName "myRG"
Get-AzVM -ResourceGroupName "myRG" -Name "myVM" -Status
Get-AzVMSize -Location "EastUS"

Resizing VMs

# Check available resize options for a VM
az vm list-vm-resize-options \
  --resource-group myRG \
  --name myVM \
  --output table

# Resize (VM will restart)
az vm resize \
  --resource-group myRG \
  --name myVM \
  --size Standard_D4s_v3
$vm = Get-AzVM -ResourceGroupName "myRG" -Name "myVM"
$vm.HardwareProfile.VmSize = "Standard_D4s_v3"
Update-AzVM -ResourceGroupName "myRG" -VM $vm

Managed Disks

# Add a data disk to a running VM
az vm disk attach \
  --resource-group myRG \
  --vm-name myVM \
  --name myDataDisk \
  --size-gb 128 \
  --sku Premium_LRS \
  --new

# List disks attached to a VM
az disk list --resource-group myRG --output table

# Detach a disk
az vm disk detach \
  --resource-group myRG \
  --vm-name myVM \
  --name myDataDisk

# Update disk size (VM must be deallocated)
az disk update \
  --resource-group myRG \
  --name myDataDisk \
  --size-gb 256

# Convert unmanaged → managed disk
az vm convert \
  --resource-group myRG \
  --name myVM

Create a Snapshot

# Get the OS disk ID
DISK_ID=$(az vm show -g myRG -n myVM --query "storageProfile.osDisk.managedDisk.id" -o tsv)

# Create snapshot
az snapshot create \
  --resource-group myRG \
  --name mySnapshot \
  --source "$DISK_ID"

# Create disk from snapshot
az disk create \
  --resource-group myRG \
  --name myRestoredDisk \
  --source mySnapshot \
  --size-gb 128

VM Extensions

# View installed extensions
az vm extension list --resource-group myRG --vm-name myVM --output table

# Install Custom Script Extension (Linux)
az vm extension set \
  --resource-group myRG \
  --vm-name myVM \
  --name customScript \
  --publisher Microsoft.Azure.Extensions \
  --settings '{"fileUris":["https://raw.githubusercontent.com/myrepo/script.sh"],"commandToExecute":"./script.sh"}'

# Install Azure Monitor Agent
az vm extension set \
  --resource-group myRG \
  --vm-name myVM \
  --name AzureMonitorLinuxAgent \
  --publisher Microsoft.Azure.Monitor

# Remove extension
az vm extension delete \
  --resource-group myRG \
  --vm-name myVM \
  --name customScript

Availability Sets

# Create availability set
az vm availability-set create \
  --resource-group myRG \
  --name myAvailSet \
  --platform-fault-domain-count 2 \
  --platform-update-domain-count 5

# Create VM in availability set
az vm create \
  --resource-group myRG \
  --name myVM \
  --image Ubuntu2204 \
  --availability-set myAvailSet \
  --generate-ssh-keys

Virtual Machine Scale Sets (VMSS)

# Create a scale set
az vmss create \
  --resource-group myRG \
  --name myScaleSet \
  --image Ubuntu2204 \
  --upgrade-policy-mode automatic \
  --admin-username azureuser \
  --generate-ssh-keys \
  --instance-count 2

# Scale out manually
az vmss scale \
  --resource-group myRG \
  --name myScaleSet \
  --new-capacity 5

# Add autoscale rule (scale out when CPU > 75%)
az monitor autoscale create \
  --resource-group myRG \
  --resource myScaleSet \
  --resource-type Microsoft.Compute/virtualMachineScaleSets \
  --name autoscale-rules \
  --min-count 2 --max-count 10 --count 2

az monitor autoscale rule create \
  --resource-group myRG \
  --autoscale-name autoscale-rules \
  --condition "Percentage CPU > 75 avg 5m" \
  --scale out 2

az monitor autoscale rule create \
  --resource-group myRG \
  --autoscale-name autoscale-rules \
  --condition "Percentage CPU < 30 avg 5m" \
  --scale in 1

# List VMSS instances
az vmss list-instances \
  --resource-group myRG \
  --name myScaleSet \
  --output table

Networking for VMs

# Open a port (creates NSG rule)
az vm open-port \
  --resource-group myRG \
  --name myVM \
  --port 80 \
  --priority 1010

# List public IPs
az network public-ip list --resource-group myRG --output table

# Get the public IP of a VM
az vm list-ip-addresses \
  --resource-group myRG \
  --name myVM \
  --output table

Key Facts for AZ-104

ConceptDetail
Stopped (OS-level)Pay compute + disk. IP retained
DeallocatedNo compute charge. Dynamic IP released
Fault domainsSeparate physical hardware (power/network)
Update domainsSequential reboot groups during maintenance
Premium SSDRequired for production; Standard_D*s sizes
Ephemeral OS diskStored on VM cache; faster, no extra cost
Spot VMsInterruptible; up to 90% cost saving
Proximity placement groupCo-locate VMs for low latency

More in Microsoft Azure