你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn 。
在 PowerShell 环境中运行 Azure CLI 的注意事项
本文内容
Azure CLI 是一种通过 Azure CLI 参考命令管理 Azure 资源的工具,可在 Bash 和 PowerShell 环境中运行。 但是,在可能导致意外结果的环境之间的参数格式设置方面存在轻微的语法差异。 本文旨在帮助你解决在 PowerShell 环境中工作时出现的 Azure CLI 语法错误。
本文比较了以下环境中执行的 Azure CLI 命令的语法差异:
如果你不熟悉 CLI,则工具和环境 之间的 区分可能会令人困惑。 如何选择正确的命令行工具 可提供很好的比较。
先决条件
本文旨在供你阅读和学习。 但是,如果要运行示例,请选择 Prepare your environments
用于安装本文中使用的环境的选项卡。
若要执行本文中给出的测试用例,请安装或打开以下环境:
Linux 环境
在所选的 Internet 应用程序中或Windows 终端 中,使用提供的链接打开两个选项卡。
使用 Bash 运行的 Azure Cloud Shell 实例 。
如果 Azure Cloud Shell 在 PowerShell 环境中打开,请在 Cloud Shell 菜单栏中选择 切换到 Bash 选项。
使用 PowerShell 运行的 Azure Cloud Shell 的第二个实例 。 如果 Azure Cloud Shell 在 Bash 环境中打开,请在 Cloud Shell 菜单栏中选择 “切换到 PowerShell ”选项。
Microsoft Windows 环境
在 Windows 环境中本地安装 Azure CLI 。
预安装在大多数 Windows 操作系统中的 Windows PowerShell 5.1 的本地安装。
在 Windows 环境中本地安装 PowerShell 7 。
本文在 Windows 11 企业版 版本 23H2 中进行了测试。
测试以查看正在使用的 Azure CLI 和 PowerShell 版本。
az version
$PSVersionTable
下面是 Azure Cloud Shell 的输出,它是 Azure CLI 和 PowerShell 的最新版本:
{
"azure-cli": "2.57.0",
"azure-cli-core": "2.57.0",
"azure-cli-telemetry": "1.1.0",
"extensions": {
"ai-examples": "0.2.5",
"ml": "2.22.0",
"ssh": "2.0.2"
}
}
Name Value
---- -----
PSVersion 7.4.1
PSEdition Core
GitCommitId 7.4.1
OS CBL-Mariner/Linux
Platform Unix
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
下面是 Windows PowerShell 5 终端的输出,它是 计算机上安装 的 Azure CLI 和 PowerShell 版本。 在此输出示例中,本地计算机上安装 Azure CLI 版本 2.57.0 和 Windows PowerShell 5.1.22621。
{
"azure-cli": "2.57.0",
"azure-cli-core": "2.57.0",
"azure-cli-telemetry": "1.1.0",
"extensions": {
"ai-examples": "0.2.5",
"ml": "2.22.0",
"ssh": "2.0.2"
}
}
Name Value
---- -----
PSVersion 5.1.22621.2506
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.22621.2506
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
如果在 PowerShell 7 终端中运行 $PSVersionTable
,则 PowerShell 版本或更高版本 PSVersion 7
取决于本地计算机上安装的内容。
如果需要 Azure 存储帐户来运行这些测试脚本,请立即创建一个。
# Bash syntax example
# Variable block
let "randomIdentifier=$RANDOM*$RANDOM"
location=eastus
resourceGroup="msdocs-test-rg-$randomIdentifier"
storageAccount="msdocssa$randomIdentifier"
# Create a resource group.
az group create --name $resourceGroup --location $location
# Create a storage account.
echo "Creating storage account $storageAccount in resource group $resourceGroup"
az storage account create --name $storageAccount \
--resource-group $resourceGroup \
--location $location \
--sku Standard_RAGRS \
--kind StorageV2 \
--output json
# PowerShell syntax example
# Variable block
$randomIdentifier = $(Get-Random)
$location="eastus"
$resourceGroup="msdocs-test-rg-$randomIdentifier"
$storageAccount="msdocssa$randomIdentifier"
# Create a resource group.
az group create --name $resourceGroup --location $location
# Create a storage account.
echo "Creating storage account $storageAccount in resource group $resourceGroup"
az storage account create --name $storageAccount `
--resource-group $resourceGroup `
--location $location `
--sku Standard_RAGRS `
--kind StorageV2 `
--output json
创建新的存储帐户时,Azure CLI 将返回超过 100 行的 JSON 输出。 以下 JSON 字典包含为简洁起见省略的字段。
{
"accessTier": "Hot",
"allowBlobPublicAccess": false,
"creationTime": "yyyy-mm-ddT19:14:26.962501+00:00",
"enableHttpsTrafficOnly": true,
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/ msdocs-test-rg-00000000/providers/Microsoft.Storage/storageAccounts/msdocssa00000000",
"keyCreationTime": {
"key1": "yyyy-mm-ddT19:14:27.103127+00:00",
"key2": "yyyy-mm-ddT19:14:27.103127+00:00"
},
"kind": "StorageV2",
"location": "eastus",
"name": "msdocssa00000000",
"primaryEndpoints": {
"blob": "https://msdocssa00000000.blob.core.windows.net/"
},
"primaryLocation": "eastus",
"provisioningState": "Succeeded",
"resourceGroup": "msdocs-test-rg-00000000",
"sku": {
"name": "Standard_RAGRS",
"tier": "Standard"
},
"statusOfPrimary": "available",
"statusOfSecondary": "available",
"tags": {},
"type": "Microsoft.Storage/storageAccounts"
}
重要
如果 Azure CLI 脚本生成错误, 请考虑你正在使用的环境如何分析 Azure CLI 命令语法。
在 Azure CLI 参数中传递空格
在 Azure CLI 中,需要传递包含空间的参数值时,操作系统和环境之间存在差异。 在此示例中,使用 az storage account list 并重命名包含空格的单词的输出列。
在此示例中,请注意带有嵌入双引号()的单引号 ('...'
) 包装器。"..."
此示例也适用于 Linux 中的 PowerShell。
az storage account list --query '[].{"SA Name":name, "Primary endpoint":primaryEndpoints.blob}' --output table
如果要添加筛选器,语法将更改。 请注意此示例如何将参数值包装 --query
在双引号 ("..."
) 中,并使用反斜杠 (\
) 转义字符。 此脚本不会在 PowerShell 中运行。
az storage account list --query "[?creationTime >='2024-02-01'].{\"SA Name\":name,\"Primary endpoint\":primaryEndpoints.blob}" --output table
如果刚刚尝试在 PowerShell 环境中运行筛选器语法,则会收到错误消息 argument --query: invalid jmespath_type value: "[?creationTime >=..."
。 但是,在 Linux 环境中的 Bash 中,输出如下所示:
SA Name Primary Endpoint
----------- -----------------
msdocssa00000000 https://msdocssa000000000.blob.core.windows.net/
在此示例中,请注意带有嵌入双引号和反引号转义`
字符的双引号 ("..."
) 包装器。
az storage account list --query "[].{`"SA Name`":name, `"Primary endpoint`":primaryEndpoints.blob}" --output table
如果在 Windows PowerShell 或 Windows 计算机上安装的 PowerShell 7 中运行此语法,则会收到错误 argument --query: invalid jmespath_type value: '[].{SA'
。 请注意错误消息在两者之间SA
Name
和之间的空间上是如何中断的。 在 Linux 环境中的 Bash 中,错误消息为 argument --query: invalid jmespath_type value: '[].{:name,'
。
现在添加筛选器。 与 Bash 脚本不同,添加日期筛选器不需要重新处理整个 --query
字符串。
az storage account list --query "[?creationTime >='2024-02-01'].{`"SA Name`":name, `"Primary endpoint`":primaryEndpoints.blob}" --output table
在此示例中,请注意带有嵌入双引号('...'
)和转义字符反斜杠()的单引号(""...""
\
) 包装器。
az storage account list --query '[].{\"SA Name\":name,\"Primary endpoint\":primaryEndpoints.blob}' --output table
请注意单引号 ('...'
) 包装器,其中包含嵌入的双引号对 (""...""
)。 此脚本还会在 Windows PowerShell 5 中成功运行。
az storage account list --query '[].{""SA Name"":name,""Primary endpoint"":primaryEndpoints.blob}' --output table
creationTime
应用筛选器并注意单引号 ('...'
) 包装器保持不变,但嵌入的单引号对 (''...''
) 用于环绕日期值。 此脚本还会在 Windows PowerShell 5 中成功运行。
az storage account list --query '[?creationTime >=''2024-02-01''].{""SA Name"":name,""Primary endpoint"":primaryEndpoints.blob}' --output table
在此示例中,请注意带有嵌入双引号对的单引号 ('...'
) 包装器(""...""
)。 此脚本还会在 Windows 环境中的 PowerShell 7 中成功运行。
az storage account list --query '[].{""SA Name"":name,""Primary endpoint"":primaryEndpoints.blob}' --output table
creationTime
应用筛选器并注意单引号 ('...'
) 包装器保持不变,但嵌入的单引号对 (''...''
) 用于环绕日期值。 此脚本还会在 Windows 环境中的 PowerShell 7 中成功运行。
az storage account list --query '[?creationTime >=''2024-02-01''].{""SA Name"":name,""Primary endpoint"":primaryEndpoints.blob}' --output table
是否从此选项卡上的脚本收到 argument --query: invalid jmespath_type value:...
错误? 在 Linux 环境中在 Bash 或 PowerShell 7 中执行这些 Windows 脚本时,将返回此错误。
在包含查询字符串的 URL 中传递参数
URL 中的问号指示 URL 的末尾和查询字符串的开头。 以下示例在 Learn 中 打开步骤 3 以使用 Azure CLI :
https://learn.microsoft.com/en-us/cli/azure/account?view=azure-cli-2020-09-01-hybrid
。
所需的 ?view=azure-cli-2020-09-01-hybrid
Azure CLI 引用内容版本的结果。
在 PowerShell 环境中执行 Azure CLI 命令时,PowerShell 允许问号成为变量名称的一部分。 这可能会在 Azure CLI 参数值中创建混淆。
下面是“使用 Azure REST API”一文中的 一个示例:
请注意 Bash 中如何 $containerRegistryName?api-version
连接在一起而不出错。
# Script for a Bash environment
# Variable block
let "randomIdentifier=$RANDOM*$RANDOM"
subscriptionId="00000000-0000-0000-0000-000000000000"
resourceGroup="msdocs-app-rg$randomIdentifier"
containerRegistryName="msdocscr$randomIdentifier"
# prior to this GET example, the resource group and container registry were created in the article.
az rest --method get --url https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.ContainerRegistry/registries/$containerRegistryName?api-version=2023-01-01-preview
请注意 PowerShell ${containerRegistryName}?api-version
中所需的括号{}
。 如果没有括号,PowerShell 会将问号(?
)解释为参数名称 $containerRegistryName
的一部分。
在 Linux 或 Windows 中运行的 PowerShell 5 和 PowerShell 7 中,此行为相同。
# Script for a PowerShell environment
# Variable block
$randomIdentifier = (New-Guid).ToString().Substring(0,8)
$subscriptionId="00000000-0000-0000-0000-000000000000"
$resourceGroup="msdocs-app-rg$randomIdentifier"
$containerRegistryName="msdocscr$randomIdentifier"
# prior to this GET example, the resource group and container registry were created in the article.
az rest --method get --url https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.ContainerRegistry/registries/${containerRegistryName}?api-version=2023-01-01-preview
传递包含 PowerShell 特殊字符的参数
PowerShell 有特殊字符,例如 At (@
) 符号。 若要在 PowerShell 中运行 Azure CLI,请在特殊字符之前添加反引号 `
以对其进行转义。 还可以将值括在单引号'
或双"
引号中。
以下三个示例将在 PowerShell 中工作:
parameterName '@parameters.json
parameterName “@parameters.json”
parameterName “@parameters.json”
此示例在 PowerShell 中不起作用:
parameterName @parameters.json
传递包含 JSON 的参数
对于 JSON 字符串等复杂参数,最佳做法是使用 Azure CLI 的 @<file>
约定从文件加载,以绕过 shell 的解释。 请注意, At (@
) 符号是 PowerShell 中的一个 分块运算符 ,因此应引用它。
az ad app create 中有 一个很好的示例,其中包含 JSON 文件内容和命令示例。 下面是一个代码片段:
# Script for a Bash environment
az ad app create --display-name myTestAppName \
--is-fallback-public-client \
--required-resource-accesses @manifest.json
在此示例中,请注意 PowerShell 环境中所需的 JSON 文件名的双引号("..."
)。
# Script for a PowerShell environment
az ad app create --display-name myTestAppName `
--is-fallback-public-client `
--required-resource-accesses "@manifest.json"
传递包含 key:value 对的参数
某些 Azure CLI 参数值(如 Azure 资源标记)需要键:值对。 key
如果你或value
包含空格或特殊字符,Bash 和 PowerShell 语法并不总是相同的。
请参阅“创建标记”来练习在 Learn 中使用 Azure CLI 教程中的差异。 本教程步骤为以下键值对方案提供了 Bash、PowerShell 和 Cmd 的示例:
有关 PowerShell 中 Azure CLI 的错误的处理
可以在 PowerShell 中运行 Azure CLI 命令,如选择正确的 Azure 命令行工具 中所述。
如果要这么做,请确保了解如何在 PowerShell 中处理 Azure CLI 错误。 具体而言,Azure CLI 不会创建供 PowerShell 捕获的异常。
一种替代方法是使用 $?
自动变量。 此变量包含最新命令的状态。 如果前面的命令失败,$?
的值为 $False
。 有关详细信息,请参阅 about_Automatic_Variables 。
下面的示例演示此自动变量如何在错误处理中发挥作用:
# Script for a PowerShell environment
az group create --name MyResourceGroup
if ($? -eq $false) {
Write-Error "Error creating resource group."
}
az
命令失败,因为它缺少必需的 --location
参数。 条件语句发现 $?
为 false 并写入错误。
如果要使用 try
和 catch
关键字,可以使用 throw
来创建供 try
块捕获的异常:
# Script for a PowerShell environment
$ErrorActionPreference = "Stop"
try {
az group create --name MyResourceGroup
if ($? -eq $false) {
throw 'Group create failed.'
}
}
catch {
Write-Error "Error creating the resource group."
}
$ErrorActionPreference = "Continue"
默认情况下,PowerShell 仅捕获终止错误。 此示例将 $ErrorActionPreference
全局变量设置为 Stop
,以便 PowerShell 可以处理错误。
条件语句测试 $?
变量以确定上一个命令是否失败。 如果失败,throw
关键字会创建一个供捕获的异常。 catch
块可用于编写错误消息或处理错误。
该示例将 $ErrorActionPreference
恢复为其默认值。
有关 PowerShell 错误处理的详细信息,请参阅关于异常的各项须知内容 。
在 PowerShell 中启用 Tab 自动补全
Tab 自动补全,也称为“Azure CLI 补全器”,提供输入自动补全功能,以提供提示、启用发现和加快条目输入速度。 可以通过按 Tab 键将命令名称、命令组名称、参数和某些参数值自动插入到命令行中。
Tab 自动补全在 Azure Cloud Shell 和大多数 Linux 发行版中默认启用。 从 Azure CLI 版本 2.49 开始,可以在 PowerShell 中为 Azure CLI 启用 Tab 自动补全。 执行以下步骤:
创建或编辑存储在变量 $PROFILE
中的配置文件。 最简单的方法是在 PowerShell 中运行 notepad $PROFILE
。 有关详细信息,请参阅如何创建配置文件 和配置文件和执行策略 。
将以下代码添加到 PowerShell 配置文件:
Register-ArgumentCompleter -Native -CommandName az -ScriptBlock {
param($commandName, $wordToComplete, $cursorPosition)
$completion_file = New-TemporaryFile
$env:ARGCOMPLETE_USE_TEMPFILES = 1
$env:_ARGCOMPLETE_STDOUT_FILENAME = $completion_file
$env:COMP_LINE = $wordToComplete
$env:COMP_POINT = $cursorPosition
$env:_ARGCOMPLETE = 1
$env:_ARGCOMPLETE_SUPPRESS_SPACE = 0
$env:_ARGCOMPLETE_IFS = "`n"
$env:_ARGCOMPLETE_SHELL = 'powershell'
az 2>&1 | Out-Null
Get-Content $completion_file | Sort-Object | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, "ParameterValue", $_)
}
Remove-Item $completion_file, Env:\_ARGCOMPLETE_STDOUT_FILENAME, Env:\ARGCOMPLETE_USE_TEMPFILES, Env:\COMP_LINE, Env:\COMP_POINT, Env:\_ARGCOMPLETE, Env:\_ARGCOMPLETE_SUPPRESS_SPACE, Env:\_ARGCOMPLETE_IFS, Env:\_ARGCOMPLETE_SHELL
}
若要显示菜单中的所有可用选项,请将 Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
添加到 PowerShell 配置文件。
另请参阅