Home / Azure

AzureRunbookIntermediate

Azure VM won't boot or accept RDP/SSH: a triage runbook

Work out whether a VM is down, firewalled or stuck at boot, using boot diagnostics, the serial console, run-command and the repair extension.

Deepak Bhardwaj4 min read

Applies toAzure CLI 2.60+, Windows and Linux VMs

Most "the VM is down" tickets turn out to be one of three things: the guest OS is stuck at boot, something on the network path blocks the port, or the guest is running but the remote access service isn't. Find out which one before you change anything.

1. Check what Azure thinks

RG=rg-prod-app; VM=vm-app-01
az vm get-instance-view -g $RG -n $VM \
  --query "{power:instanceView.statuses[1].displayStatus, agent:instanceView.vmAgent.statuses[0].displayStatus}" -o table
  • VM running, agent Ready: the guest is up. Go to step 3, the network path.
  • VM running, agent Not Ready: the guest is hung, still booting, or the agent has crashed. Go to step 2.
  • VM deallocated or stopped: check the Activity Log for who stopped it, or whether a Spot eviction happened.

Also check Resource Health in the portal. If it says Unavailable – platform initiated, the fault is on Azure's side and redeploying usually fixes it.

2. Look at the console

# Screenshot + serial log (needs boot diagnostics; managed storage is fine)
az vm boot-diagnostics enable -g $RG -n $VM
az vm boot-diagnostics get-boot-log -g $RG -n $VM | tail -50

# Interactive serial console (needs a local password user in the guest)
az serial-console connect -g $RG -n $VM

Common screens and what they mean:

Console shows Likely cause Next step
Windows "Getting ready" / "Applying updates" for hours Stuck update Wait 30 min, then use az vm repair
Emergency mode / fstab errors (Linux) Detached data disk still in /etc/fstab Add nofail to the mount, or comment it out
Blue screen, INACCESSIBLE_BOOT_DEVICE Driver or disk-controller change Repair VM, then restore the driver
Login prompt is visible The OS is fine It's a network or service problem: step 3

3. Test the network path

# Effective NSG rules on the NIC
NIC=$(az vm show -g $RG -n $VM --query "networkProfile.networkInterfaces[0].id" -o tsv)
az network nic list-effective-nsg --ids $NIC -o table

# Would traffic from my IP to 3389/22 be allowed?
az network watcher test-ip-flow -g $RG --vm $VM --direction Inbound \
  --protocol TCP --local 10.10.1.4:22 --remote 203.0.113.10:50000

If test-ip-flow reports Deny, it also names the rule that matched. Check route tables (UDRs that send traffic to a firewall) and Azure Firewall/NVA logs too.

Tip

Bastion avoids most of this. If Bastion can connect but your VPN path can't, the guest is healthy and the problem is in your network.

4. Fix the guest without logging in

# Run a script in the guest through the VM agent
az vm run-command invoke -g $RG -n $VM --command-id RunPowerShellScript \
  --scripts "Get-Service TermService | Restart-Service -Force; netsh advfirewall firewall set rule group='remote desktop' new enable=Yes"

# Linux: reset SSH config and a user's key
az vm user reset-ssh -g $RG -n $VM
az vm user update -g $RG -n $VM -u azureuser --ssh-key-value ~/.ssh/id_rsa.pub

5. Last resort: the repair VM

The vm-repair extension copies the OS disk and attaches it to a temporary rescue VM, where you can fix it offline:

az extension add -n vm-repair
az vm repair create -g $RG -n $VM --repair-username rescue --repair-password '<strong-password>' --verbose
# ...fix fstab / registry / drivers on the attached disk...
az vm repair restore -g $RG -n $VM --verbose   # swaps the fixed disk back in

Warning

az vm redeploy moves the VM to a new host and wipes the temporary disk (D: on Windows, /mnt on Linux). Don't keep anything there that you need.

Prevent it next time

  • Enable boot diagnostics in your VM baseline (Azure Policy can enforce it).
  • Keep one local break-glass account so the serial console always works.
  • Alert on the VM Availability metric and Resource Health, not only on ping.