Find Stopped Azure VMs with PowerShell

Stopped, but not deallocated, Azure VMs still cost you money. This article looks at how we can find those servers using PowerShell.

When an Azure VM is shutdown using the operating system it enters a “stopped” state. In this state the server is not running but the compute resource is still being held by Azure so you continue to get charged for that compute. Virtual Machines should be deallocated by either stopping them in the Portal or using a PowerShell Stop-AzVM cmdlet.

PowerShell can be used to look up the power state of VMs in your Azure Subscription as follows:

1Get-AzVM | `
2  Select-Object Name, @{Name="Status";
3        Expression={(Get-AzVM -Name $_.Name -ResourceGroupName $_.ResourceGroupName -status).Statuses[1].displayStatus}}

The results might look like this:

1Name             Status
2----             ------
3myVm-01          VM running
4myVm-02          VM stopped
5myVm-03          VM deallocated

The VM stopped virtual machine myVM-02 is the one we’re interested in. You’re likely to have a longer list than 3 VMs so the Where-Object cmdlet can be used to filter to only those stopped (but not deallocated) virtual machines.

1Get-AzVM | `
2  Select-Object Name, @{Name="Status";
3        Expression={(Get-AzVM -Name $_.Name -ResourceGroupName $_.ResourceGroupName -status).Statuses[1].displayStatus}} | `
4  Where-Object {$_.Status -eq "VM stopped"}

The results now would look like this:

1Name             Status
2----             ------
3myVm-02          VM stopped

We can now take this one step further and stop those VMs properly, deallocating them.

1 Get-AzVM | `
2  Select-Object Name, ResourceGroupName, @{Name="Status";
3        Expression={(Get-AzVM -Name $_.Name -ResourceGroupName $_.ResourceGroupName -status).Statuses[1].displayStatus}} | `
4  Where-Object {$_.Status -eq "VM stopped"} | `
5  Stop-AzVM -Force