export vm_ids=$(az vm list --show-details --resource-group myResourceGroup --query "[?powerState=='VM running'].id" --output tsv)
az vm stop --ids $vm_ids
For more information about these and other formats, see Output formats for Azure CLI commands.
Pass values to another command
If the value is used more than once, assign it to a variable. Variables allow you to use values more than once or to create more general scripts. This example assigns an ID found by the az vm list command to a variable.
# assign the list of running VMs to a variable
running_vm_ids=$(az vm list --resource-group MyResourceGroup --show-details \
--query "[?powerState=='VM running'].id" --output tsv)
# verify the value of the variable
echo $running_vm_ids
If the value is used only once, consider piping. (Piping passes the output of one command as input to a second command.)
az vm list --query "[?powerState=='VM running'].name" --output tsv | grep my_vm
For multi-value lists, consider the following options:
If you need more controls on the result, use a "for" loop:
#!/usr/bin/env bash
for vmList in $(az vm list --resource-group MyResourceGroup --show-details --query "[?powerState=='VM running'].id" --output tsv); do
echo stopping $vmList
az vm stop --ids $vmList
if [ $? -ne 0 ]; then
echo "Failed to stop $vmList"
exit 1
echo $vmList stopped
Alternatively, use xargs
and consider using the -P
flag to run the operations in parallel for improved performance:
az vm list --resource-group MyResourceGroup --show-details \
--query "[?powerState=='VM stopped'].id" \
--output tsv | xargs -I {} -P 10 az vm start --ids "{}"
Finally, Azure CLI has built-in support to process commands with multiple --ids
in parallel to achieve the same effect of xargs. @-
is used to get values from the pipe:
az vm list --resource-group MyResourceGroup --show-details \
--query "[?powerState=='VM stopped'].id" \
--output tsv | az vm start --ids @-
For more information on using Bash constructs with the Azure CLI including loops, case statements, if..then..else, and error handling, see Learn to use Bash with the Azure CLI.
Use quotation marks in parameters
When you work with Azure CLI commands, be aware of how your shell uses quotation marks and escapes characters. If you support scripts used in different shells, understand how they differ.
Bash. Quoting
PowerShell. About Quoting Rules
Windows Command Prompt. How-to: Escape Characters, Delimiters and Quotes at the Windows command line
Due to a known issue in PowerShell, some extra escaping rules apply. For more information, see Quoting issues with PowerShell.
To avoid unanticipated results, here are a few suggestions:
If you provide a parameter that contains whitespace, wrap it in quotation marks.
In Bash or PowerShell, both single and double quotes are interpreted correctly. In Windows Command Prompt, only double quotes are interpreted correctly -- single quotes are treated as part of the value.
If your command is only going to run on Bash (or Zsh), use single quotes to preserve the content inside the JSON string. Single quotes are necessary when supplying inline JSON values. For example, this JSON is correct in Bash: '{"key": "value"}'
.
If your command runs at a Windows Command Prompt, you must use double quotes. If the value contains double quotes, you must escape it. The equivalent of the above JSON string is "{\"key\": \"value\"}"
In PowerShell, if your value is an empty string, use '""'
.
In Bash or PowerShell, if your value is an empty quotes string ''
, use "''"
.
Use Azure CLI's @<file>
convention to load from a file and bypass the shell's interpretation mechanisms.
az ad app create --display-name myName --native-app --required-resource-accesses @manifest.json
Bash evaluates double quotes in exported variables. If this behavior isn't what you want, escape the variable: "\$variable"
.
Some Azure CLI commands take a list of space separated values.
If the key name or value contains spaces, wrap the whole pair: "my key=my value"
. For example:
az web app config app settings set --resource-group myResourceGroup --name myWebAppName --settings "client id=id1" "my name=john"
When a CLI parameter states that it accepts a space-separated list, one of two formats is expected:
Unquoted, space-separated list
--parameterName firstValue secondValue
Quoted space-separated list
--parameterName "firstValue" "secondValue"
This example is a string with a space in it. It isn't a space-separated list:
--parameterName "firstValue secondValue"
There are special characters of PowerShell, such as at @
. To run Azure CLI in PowerShell, add `
before the special character to escape it. You can also enclose the value in single or double quotes "
/"
.
# The following three examples will work in PowerShell
--parameterName `@parameters.json
--parameterName '@parameters.json'
--parameterName "@parameters.json"
# This example will not work in PowerShell
--parameterName @parameters.json
When you use the --query
parameter with a command, some characters of JMESPath need to be escaped in the shell.
PowerShell
These three commands are correct and equivalent in Bash:
az version --query '"azure-cli"'
az version --query \"azure-cli\"
az version --query "\"azure-cli\""
Here are two examples of incorrect commands in Bash:
# Wrong, as the dash needs to be quoted in a JMESPath query
az version --query azure-cli
az version: error: argument --query: invalid jmespath_type value: 'azure-cli'
# Wrong, as the dash needs to be quoted in a JMESPath query, but quotes are interpreted by Bash
az version --query "azure-cli"
az version: error: argument --query: invalid jmespath_type value: 'azure-cli'
For more example comparisons between Bash, PowerShell and Cmd, see Query Azure CLI command output
These five commands work correctly in PowerShell:
az version --query '\"azure-cli\"'
az version --query "\`"azure-cli\`""
az version --query "\""azure-cli\"""
az --% version --query "\"azure-cli\""
az --% version --query \"azure-cli\"
For more example comparisons between Bash, PowerShell and Cmd, see Query Azure CLI command output
These two commands work correctly in Windows Command Prompt:
az version --query "\"azure-cli\""
az version --query \"azure-cli\"
For more example comparisons between Bash, PowerShell and Cmd, see Query Azure CLI command output
The best way to troubleshoot a quoting issue is to run the command with the --debug
flag. This flag reveals the actual arguments received by the Azure CLI in Python's syntax.
# Correct
$ az '{"key":"value"}' --debug
Command arguments: ['{"key":"value"}', '--debug']
# Correct
$ az "{\"key\":\"value\"}" --debug
Command arguments: ['{"key":"value"}', '--debug']
# Wrong, as quotes and spaces are interpreted by Bash
$ az {"key": "value"} --debug
Command arguments: ['{key:', 'value}', '--debug']
# Wrong, as quotes are interpreted by Bash
$ az {"key":"value"} --debug
Command arguments: ['{key:value}', '--debug']
Use hyphen characters in parameters
If a parameter's value begins with a hyphen, Azure CLI tries to parse it as a parameter name. To parse it as value, use =
to concatenate the parameter name and value: --password="-VerySecret"
.
Asynchronous operations
Operations in Azure can take a noticeable amount of time. For instance, configuring a virtual machine at a data center isn't instantaneous. Azure CLI waits until the command has finished to accept other commands. Many commands therefore offer a --no-wait
parameter as shown here:
az group delete --name MyResourceGroup --no-wait
When you delete a resource group, all the resources that belong to it are also removed. Removing these resources can take a long time. When you run the command with the --no-wait
parameter, the console accepts new commands without interrupting the removal.
Many commands offer a wait option, pausing the console until some condition is met. The following example uses the az vm wait command to support creating independent resources in parallel:
az vm create --resource-group VMResources --name virtual-machine-01 --image centos --no-wait
az vm create --resource-group VMResources --name virtual-machine-02 --image centos --no-wait
subscription=$(az account show --query "id" -o tsv)
vm1_id="/subscriptions/$subscription/resourceGroups/VMResources/providers/Microsoft.Compute/virtualMachines/virtual-machine-01"
vm2_id="/subscriptions/$subscription/resourceGroups/VMResources/providers/Microsoft.Compute/virtualMachines/virtual-machine-02"
az vm wait --created --ids $vm1_id $vm2_id
After both IDs are created, you can use the console again.
Work behind a proxy
If you're using Azure CLI over a proxy server that uses self-signed certificates, the Python requests library used by the Azure CLI may cause the following error: SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",)
. To address this error, set the environment variable REQUESTS_CA_BUNDLE
to the path of CA bundle certificate file in PEM format.
Default certificate authority bundle
Windows 32-bit
C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\Lib\site-packages\certifi\cacert.pem
Windows 64-bit
C:\Program Files\Microsoft SDKs\Azure\CLI2\Lib\site-packages\certifi\cacert.pem
Ubuntu/Debian Linux
/opt/az/lib/python<version>/site-packages/certifi/cacert.pem
CentOS/RHEL/SUSE Linux
/usr/lib64/az/lib/python<version>/site-packages/certifi/cacert.pem
macOS
/usr/local/Cellar/azure-cli/<cliversion>/libexec/lib/python<version>/site-packages/certifi/cacert.pem
Append the proxy server's certificate to the CA bundle certificate file, or copy the contents to another certificate file. Then set REQUESTS_CA_BUNDLE
to the new file location. Here's an example:
<Original cacert.pem>
-----BEGIN CERTIFICATE-----
<Your proxy's certificate here>
-----END CERTIFICATE-----
Some proxies require authentication. The format of the HTTP_PROXY
or HTTPS_PROXY
environment variables should include the authentication, such as HTTPS_PROXY="https://username:password@proxy-server:port"
. For details, see How to configure proxies for the Azure libraries.
Concurrent execution
If you run Azure CLI commands concurrently on the same machine, write conflicts can happen if multiple Azure CLI commands write to the same MSAL token cache.
To avoid potential failures, you may isolate the Azure CLI configuration folder for each script by setting environment variable AZURE_CONFIG_DIR
for each script to a separate directory. Azure CLI commands in that script save the configuration and token cache to the configured location instead of the default ~/.azure
folder.
PowerShell
Generic update parameters
Azure CLI command groups often feature an update command. For instance, Azure Virtual Machines includes the az vm update command. Most update commands offer the three generic parameters: --add
, --set
, and --remove
.
The --set
and --add
parameters take a list of space-separated key-value pairs: key1=value1 key2=value2
. To see what properties you can update, use a show command, such as az vm show.
az vm show --resource-group VMResources --name virtual-machine-01
To simplify the command, consider using a JSON string. For example, to attach a new data disk to a virtual machine, use the following value:
az vm update --resource-group VMResources --name virtual-machine-01 \
--add storageProfile.dataDisks "{\"createOption\": \"Attach\", \"managedDisk\":
{\"id\":
\"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/yg/providers/Microsoft.Compute/disks/yg-disk\"},
\"lun\": 1}"
Generic resource commands (az resource)
A service you want to work with may not have Azure CLI support. You can use the az resource commands to work with these resources.
If you only need create or update commands, use the az deployment group create. For working examples, see Azure Quickstart Templates.
REST API commands (az rest)
If generic update parameters and az resource don't meet your needs, you can use the az rest command to call the REST API. The command automatically authenticates using the logged-in credential and sets header Content-Type: application/json
. For more information, see Azure REST API reference.
This example works with the Microsoft Graph API. To update redirect URIs for an Application, call the Update application REST API, as in this code:
# Get the application
az rest --method GET \
--uri 'https://graph.microsoft.com/v1.0/applications/b4e4d2ab-e2cb-45d5-a31a-98eb3f364001'
# Update `redirectUris` for `web` property
az rest --method PATCH \
--uri 'https://graph.microsoft.com/v1.0/applications/b4e4d2ab-e2cb-45d5-a31a-98eb3f364001' \
--body '{"web":{"redirectUris":["https://myapp.com"]}}'
When using --uri-parameters
for requests in the form of OData, make sure to escape $
in different environments: in Bash
, escape $
as \$
and in PowerShell
, escape $
as `$
Script examples
Here are examples for using variables and looping through a list when working with Azure Virtual Machines. For in-depth examples on using Bash constructs with the Azure CLI including loops, case statements, if..then..else, and error handling, see Learn to use Bash with the Azure CLI.
Use these scripts to save IDs to variables:
PowerShell
SETLOCAL
FOR /F "tokens=* USEBACKQ" %%F IN (
`az vm list --resource-group VMResources --show-details --query "[?powerState=='VM running'].id" --output tsv`
) DO (
SET "vm_ids=%%F %vm_ids%" :: construct the id list
az vm stop --ids %vm_ids% :: CLI stops all VMs in parallel
$vm_ids=(az vm list --resource-group VMResources --show-details --query "[?powerState=='VM running'].id" --output tsv)
az vm stop --ids $vm_ids # CLI stops all VMs in parallel
SETLOCAL
FOR /F "tokens=* USEBACKQ" %%F IN (
`az vm list --resource-group VMResources --show-details --query "[?powerState=='VM running'].id" --output tsv`
) DO (
ECHO Stopping %%F
az vm stop --ids %%F
$vm_ids=(az vm list --resource-group VMResources --show-details --query "[?powerState=='VM running'].id" --output tsv)
foreach ($vm_id in $vm_ids) {
Write-Output "Stopping $vm_id"
az vm stop --ids $vm_id
See also
Configure the Azure CLI
Learn to use Bash with Azure CLI
Query Azure CLI command output
Use variables in Azure CLI commands
Find Azure CLI samples and published articles
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see: https://aka.ms/ContentUserFeedback.
Submit and view feedback for
This product