You can easily Start and Stop Virtual Machines (VMs) through the Azure Portal. Previously, I’ve written about the importance of Stopping unused VMs to save money and place them in a “Stopped (Deallocated)” state. While it’s easy and simple to do through the Azure Portal, it’s also time consuming if you have multiple VMs; especially if you have a dozen or more VMs. The following Azure CLI 2.0 tip will show you how you can easily use the Azure CLI to Start and Stop multiple VMs with a single command!

Before we get into how to Start, Stop and Deallocate Virtual Machines (VMs) in batches, we must first cover the basics of Starting, Stopping and Deallocating VMs one at a time. After those commands are defined and demonstrated, then you’ll have the foundation necessary to extend on that to do the batching. Please be patient as you read through as you’ll need to step through this to fully understand the end result. And, you’ll be glad you did once you get there as this will really enable you to be immensely more productive in your management of Azure Virtual Machines when it comes to Starting, Stopping, and Deallocating them.

Stop a VM with Azure CLI

Here’s the simple command you can use to Stop a VM using the Azure CLI 2.0:

# command format
az vm stop --name {vm name}
    --resource-group {resource group name}
# usage example
az vm stop --name MyVM
    --resource-group MyVMGroup

Here’s a description of the parameters to pass into he “az vm stop” command:

-n / –name
The name of the Azure Virtual Machine.

-g / –resource-group
The name of the Azure Resource Group that contains the Virtual Machine.

Remember that Stopping a VM will still incur the Virtual Machine instance size cost. In the stopped state you will still be holding on to the underlying resource reservation (CPU, Memory, etc) within the Azure data center. In order to stop paying for the VM Instance you need to Deallocate the VM instead. You can see a command for this below.

Start a VM with Azure CLI

Here’s the simple command you can use to Start a VM using the Azure CLI 2.0:

# command format
az vm start --name {vm name}
    --resource-group {resource group name}

# usage example
az vm start --name MyVM
    --resource-group MyVMGroup

Here’s a description of the parameters to pass into he “az vm start” command:

-n / –name
The name of the Azure Virtual Machine.

-g / –resource-group
The name of the Azure Resource Group that contains the Virtual Machine.

Deallocate a VM with Azure CLI

Here’s the simple command you can use to Deallocate a VM using the Azure CLI 2.0:

# command format
az vm deallocate --name {vm name}
    --resource-group {resource group name}

# usage example
az vm deallocate --name MyVM
    --resource-group MyVMGroup

Here’s a description of the parameters to pass into he “az vm deallocate” command:

-n / –name
The name of the Azure Virtual Machine.

-g / –resource-group
The name of the Azure Resource Group that contains the Virtual Machine.

Start, Stop, Deallocate Virtual Machines by ID

You could run a single command for each VM to Start, Stop, or Deallocate them one at a time. While this is much easier than using the Azure Portal UI to do the same task, it’s still fairly cumbersome when you have many VMs you need to manage all at the same time. Luckily, the Start, Stop, and Deallocate VM commands support a parameter named “–ids” that allows you to pass in the IDs of multiple Azure VMs to apply that command to all at once.

# command format
az vm start --ids {virtual machine ids}

az vm stop --ids {virtual machine ids}

az deallocate --ids {virtual machine ids}

# usage example
az start --ids "/subscriptions/a35d316a-2a2a-48e2-8834-55481f7bbb48/resourceGroups/WIN16VM/providers/Microsoft.Compute/virtualMachines/Win16VM"

az stop --ids "/subscriptions/a35d316a-2a2a-48e2-8834-55481f7bbb48/resourceGroups/WIN16VM/providers/Microsoft.Compute/virtualMachines/Win16VM"

az deallocate --ids "/subscriptions/a35d316a-2a2a-48e2-8834-55481f7bbb48/resourceGroups/WIN16VM/providers/Microsoft.Compute/virtualMachines/Win16VM"

While you can explicitly pass in the IDs of the VMs you want to run the command against, it’s a still a bit cumbersome to do. The Azure CLI 2.0 makes it extremely easy to pass in the IDs for multiple Virtual Machines by specifying another Azure CLI command to run to generate the value passed in.

Get List of Virtual Machine IDs

First, in order to pass in the IDs, you need to gather the IDs of the VM’s you are looking to run the command against. To do this you can use the “az vm list” command in combination with a few different parameters.

# usage example
az vm list --query "[].id"
    -o tsv

The above command will output the IDs of ALL Virtual Machine you have access to on your Azure Subscription. Here’s a brief description of the parameters used and what action they are performing on this specific query:

–query “[].id”
This “–query” parameter is being used in this case to select only the “id” for all the VMs. So rather than return the full information or JSON for the VMs it’s going to only return their IDs.

-o tsv
This “-o” parameter is being used to modify the Output of the command. By passing the value of “tsv” to the Output parameter it’s instructed to return the results of the command in a Tab Delimited format. In this case since we’re only selecting the IDs of the VMs then its going to return a standard list of those IDs.

There are few times where you’ll want to be running a command against ALL the VMs in your Azure Subscription. In the majority of use cases you’ll need to filter this list down some to select the IDs of just the Virtual Machines you want to run the command against. To do this you can use the “–resource-group” parameter to select the VMs from a particular Resource Group.


# command format
az vm list --query "[].id"
    -o tsv
    --resource-group {resource group name}

# usage example
az vm list --query "[].id"
    -o tsv
    --resource-group MyVMGroup

You can also use the Linux “grep” command to perform filtering on the ID list that the “az vm list” command returns:

# usage example
az vm list --query "[].id"
    -o tsv | grep "Test"

The above example shows passing the result of the “az vm list” command to “grep” which is then filtering that result and returning just the items that contain the string passed in. In this example, it’s filtering out all but the VM IDs that contain the string “Test”.

Start, Stop, Deallocate Multiple VMs at Once

Now we can put the above commands together to be able to easily Start, Stop, and Deallocate multiple Virtual Machines all at once with a single Azure CLI 2.0 command:

# example usage
az vm start --ids $(
    az vm list --query "[].id"
        -o tsv | grep "Test"
)

az vm stop --ids $(
    az vm list --query "[].id"
        -o tsv | grep "Test"
)

az vm deallocate --ids $(
    az vm list --query "[].id"
        -o tsv | grep "Test"
)

Using these techniques you will be able to much more easily Start, Stop, and Deallocate multiple Azure Virtual Machines using a single, or at least fewer, Azure CLI 2.0 commands. This should help you be a fair amount more productive when it comes to managing these actions against your Azure Virtual Machines.

Happy scripting!

Posted by Chris Pietschmann

Chris is a Microsoft MVP and has nearly 20 years of experience building enterprise systems both in the cloud and on-premises. He is also a Microsoft Certified (MCSD) Azure Solutions Architect. He has a passion for technology and sharing what he learns with others to help enable them to learn faster and be more productive.

2 Comments

  1. […] Azure CLI 2.0: Quickly Start / Stop ALL VMs (Chris Pietschmann) […]

    Reply

  2. […] Azure CLI 2.0: Quickly Start / Stop ALL VMs (Chris Pietschmann) […]

    Reply

Leave a Reply