你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

成功使用 Azure CLI 的提示

Azure CLI 是一种命令行工具,可用于配置和管理来自许多 shell 环境的 Azure 资源。 选择首选 shell 环境安装 Azure CLI 后,请使用本文来发现有关如何避免常见陷阱并成功使用 Azure CLI 的有用提示。

若要详细了解特定的 Azure CLI 命令,请参阅 Azure CLI 参考列表

输出格式设置

三种常见的输出格式用于 Azure CLI 命令:

  1. json 格式将信息显示为 JSON 字符串。

    • JSON 可提供最全面的信息。
    • 此格式是默认格式,但可以使用 --output 参数来指定其他选项。
    • 使用 az config(例如 az config set core.output=table)将全局默认格式更改为个人首选项之一。
    • JSON 格式会保留双引号,因此一般不适合用于编写脚本。
  2. table 格式将输出显示为可读表。 你可以指定在表中显示的值,并使用查询来自定义输出,如下所示:

    # command
    az vm show --resource-group myResourceGroup --name myVMname --query "{name: name, os:storageProfile.imageReference.offer}" --output table
    
    # output
    Name    Os
    ------  ------------
    myVMname   UbuntuServer
    
  3. tsv 格式返回制表符分隔和换行符分隔的值,而不带附加格式设置、键或其他符号。

    • TSV 格式适用于简洁的输出和编写脚本。
    • TSV 会去除 JSON 格式保留的双引号。
    • 要为 TSV 指定所需的格式,请使用 --query 参数。
    export vm_ids=$(az vm list --show-details --resource-group myResourceGroup --query "[?powerState=='VM running'].id" --output tsv)
    az vm stop --ids $vm_ids
    

有关这些格式和其他格式的详细信息,请参阅 Azure CLI 命令的输出格式

将值传递给其他命令

如果某个值被多次使用,请将它分配给一个变量。 通过变量,你可以多次使用值或创建更多通用脚本。 此示例将 az vm list 命令找到的一个 ID 分配给一个变量。

# 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

如果某个值只使用一次,请考虑使用管道。 (管道将一个命令的输出作为输入传递给第二个命令。

az vm list --query "[?powerState=='VM running'].name" --output tsv | grep my_vm

对于多值列表,请考虑以下选项:

  1. 如需加强对结果的控制,请使用“for”循环:

    #!/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
        fi
        echo $vmList stopped
    done
    
  2. 或者,使用 xargs,并考虑使用 -P 标志来并行运行操作以提高性能:

    az vm list --resource-group MyResourceGroup --show-details \
      --query "[?powerState=='VM stopped'].id" \
      --output tsv | xargs -I {} -P 10 az vm start --ids "{}"
    
  3. 最后,Azure CLI 具有内置支持,可并行处理具有多个 --ids 的命令,以实现 xargs 的相同效果。 @- 用于从管道获取值:

    az vm list --resource-group MyResourceGroup --show-details \
      --query "[?powerState=='VM stopped'].id" \
      --output tsv | az vm start --ids @-
    

有关将 Bash 构造与 Azure CLI 配合使用的详细信息,包括循环、case 语句、if..then..else 以及错误处理,请参阅了解如何将 Bash 与 Azure CLI 配合使用

在参数中使用引号

使用 Azure CLI 命令时,请注意 shell 如何使用引号和对字符进行转义。 如果支持在不同 shell 中使用的脚本,请了解它们的不同之处。

备注

由于 PowerShell 的已知问题,因此需要应用一些额外的转义规则。 有关详细信息,请参阅 PowerShell 引号问题

为了避免出现意外结果,此处提供了一些建议:

  • 如果提供的参数包含空格,请用引号将其引起来。

  • 在 Bash 或 PowerShell 中,单引号和双引号均会被正确解释。 在 Windows 命令提示符中,只会正确解释双引号,而单引号会被视为值的一部分。

  • 如果命令仅在 Bash(或 Zsh)上运行,请使用单引号保留 JSON 字符串中的内容。 提供内联 JSON 值时,需要使用单引号。 例如,在 Bash 中,此 JSON 是正确的:'{"key": "value"}'

  • 如果命令在 Windows 命令提示符上运行,则必须使用双引号。 如果值包含双引号,则必须对其进行转义。 上述 JSON 字符串的等效项为 "{\"key\": \"value\"}"

  • 在 PowerShell 中,如果值为空字符串,请使用 '""'

  • 在 Bash 或 PowerShell 中,如果值为空引号字符串 '',请使用 "''"

  • 使用 Azure CLI 的 @<file> 约定从文件加载,并绕过 shell 的解释机制。

    az ad app create --display-name myName --native-app --required-resource-accesses @manifest.json
    
  • Bash 评估导出变量中的双引号。 如果此行为不是所希望的,请对变量 "\$variable" 进行转义。

  • 某些 Azure CLI 命令采用以空格分隔的值列表。

    • 如果密钥名称或值包含空格,则将整对引起来:"my key=my value"。 例如:

      az web app config app settings set --resource-group myResourceGroup --name myWebAppName --settings "client id=id1" "my name=john"
      
    • 当 CLI 参数指出它接受空格分隔的列表时,应采用以下两种格式之一:

      1. 未加引号的空格分隔列表 --parameterName firstValue secondValue
      2. 加引号的空格分隔列表 --parameterName "firstValue" "secondValue"

      此示例是一个带有空格的字符串。 它不是空格分隔的列表:--parameterName "firstValue secondValue"

  • PowerShell 有特殊字符,例如 at @。 若要在 PowerShell 中运行 Azure CLI,请在特殊字符之前添加 ` 以对其进行转义。 你也可以将值括在单引号或双引号 "/" 中。

    # 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
    
  • --query 参数与命令一起使用时,需要在 shell 中对 JMESPath 的某些字符进行转义。

    在 Bash 中,这三个命令是正确且等效的:

    az version --query '"azure-cli"'
    az version --query \"azure-cli\"
    az version --query "\"azure-cli\""
    

    下面是 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'
    

    有关 Bash、PowerShell 和 Cmd 之间的更多示例比较,请参阅查询 Azure CLI 命令输出


  • 解决引号问题的最佳方法是运行带有 --debug 标志的命令。 此标志显示了 Azure CLI 在 Python 语法中接收到的实际参数。

    # 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']
    

在参数中使用连字符

如果参数的值以连字符开头,则 Azure CLI 会尝试将其分析为参数名。 若要将其分析为值,请使用 = 连接参数名称和值:--password="-VerySecret"

异步操作

Azure 中的操作可能需要花费很长时间。 例如,在数据中心配置虚拟机不是即时的。 Azure CLI 会一直等待直到命令完成,然后才会接受其他命令。 因此,许多命令提供 --no-wait 参数,如下所示:

az group delete --name MyResourceGroup --no-wait

删除资源组时,属于该资源组的所有资源也会被删除。 删除这些资源可能需要较长时间。 使用 --no-wait 参数运行命令时,控制台会在不中断删除操作的情况下接受新命令。

许多命令都提供等待选项,可在满足某些条件之前暂停控制台。 下面的示例使用 az vm wait 命令支持并行创建独立资源:

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

创建这两个 ID 后,你可以再次使用控制台。

在代理后面工作

如果对使用自签名证书的代理服务器使用 Azure CLI,则 Azure CLI 使用的 Python 请求库可能会导致以下错误:SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",)。 若要解决此错误,请将环境变量 REQUESTS_CA_BUNDLE 设置为采用 PEM 格式的 CA 捆绑证书文件的路径。

OS 默认证书颁发机构捆绑
Windows 32 位 C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\Lib\site-packages\certifi\cacert.pem
Windows 64 位 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

将代理服务器的证书追加到 CA 捆绑证书文件,或将内容复制到另一个证书文件。 然后将 REQUESTS_CA_BUNDLE 设置为新文件位置。 下面是一个示例:

<Original cacert.pem>

-----BEGIN CERTIFICATE-----
<Your proxy's certificate here>
-----END CERTIFICATE-----

某些代理需要身份验证。 HTTP_PROXYHTTPS_PROXY 格式的环境变量应包括身份验证,如 HTTPS_PROXY="https://username:password@proxy-server:port"。 有关详细信息,请参阅如何为 Azure 库配置代理

并发执行

如果在同一台计算机上并发运行 Azure CLI 命令,则如果多个 Azure CLI 命令写入同一 MSAL 令牌缓存,则会发生写入冲突。

为了避免潜在的失败,可以通过将每个脚本的环境变量 AZURE_CONFIG_DIR 设置为单独的目录来隔离每个脚本的 Azure CLI 配置文件夹。 该脚本中的 Azure CLI 命令会将配置和令牌缓存保存到配置的位置,而不是默认 ~/.azure 文件夹。

export AZURE_CONFIG_DIR=/my/config/dir

泛型更新参数

Azure CLI 命令组通常使用 update 命令。 例如,Azure 虚拟机包括 az vm update 命令。 大多数 update 命令提供了三个泛型参数:--add--set--remove

--set--add 参数采用以空格分隔的键值对列表:key1=value1 key2=value2。 若要查看可更新的属性,请使用 show 命令,如 az vm show

az vm show --resource-group VMResources --name virtual-machine-01

若要简化此命令,请考虑使用 JSON 字符串。 例如,若要将新的数据磁盘附加到虚拟机,请使用以下值:

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}"

通用资源命令 (az resource)

你要使用的服务可能不支持 Azure CLI。 可以通过 az resource 命令来使用这些资源。

如果只需要 create 或 update 命令,请使用 az deployment group create。 有关有效示例,请参阅 Azure 快速入门模板

REST API 命令 (az rest)

如果泛型更新参数和 az resource 无法满足需求,则可以使用 az rest 命令来调用 REST API。 此命令使用登录凭据自动进行身份验证,并设置标头 Content-Type: application/json。 有关详细信息,请参阅 Azure REST API 参考

此示例使用 Microsoft Graph API。 若要更新应用程序的重定向 URI,请调用更新应用程序 REST API,如以下代码中所示:

# 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"]}}'

--uri-parameters 用于 OData 格式的请求时,请确保在不同的环境中对 $ 进行转义:在 Bash 中,将 $ 转义为 \$,在 PowerShell 中,将 $ 转义为 `$

脚本示例

下面是使用 Azure 虚拟机时使用变量并循环访问列表的示例。 有关将 Bash 构造与 Azure CLI 配合使用的深度示例,包括循环、case 语句、if..then..else 以及错误处理,请参阅了解如何将 Bash 与 Azure CLI 配合使用

使用这些脚本将 ID 保存到变量:

ECHO OFF
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

使用这些脚本循环访问列表:

ECHO OFF
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
)

另请参阅