在 PowerShell 環境中執行 Azure CLI 的考慮
本文內容
Azure CLI 是一種工具,可透過在 Bash 和 PowerShell 環境中執行的 Azure CLI 參考命令來管理 Azure 資源。 不過,在可能導致非預期結果的環境中,參數格式設定有輕微的語法差異。 本文的目的是要協助您解決在PowerShell環境中運作時的 Azure CLI 語法錯誤。
本文會比較在下列環境中執行的 Azure CLI 命令語法差異:
如果您不熟悉 CLI,則工具和環境 之間的 區分可能會造成混淆。 如何選擇正確的命令行工具 可提供良好的比較。
必要條件
本文旨在讓您閱讀和學習。 不過,如果您想要執行範例,請選取索引 Prepare your environments
標籤以安裝本文中使用的環境。
若要執行本文所提供的測試案例,請安裝或開啟下列環境:
Linux 環境
在您選擇的因特網應用程式中,或在 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'
。 請注意,錯誤訊息在 與Name
之間的SA
空間上如何中斷。 在 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 的結尾和查詢字串的開頭。 以下是在瞭解如何使用 Azure CLI 中 開啟步驟 3 的範例:
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>
慣例從檔案載入,以略過殼層解譯。 請注意, 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"
傳遞包含索引鍵:值組的參數
某些 Azure CLI 參數值,例如 Azure 資源標籤,需要機碼:值組。 key
如果您的 或 value
包含空格或特殊字元,Bash 和 PowerShell 語法不一定相同。
請參閱建立標籤以練習學習使用 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 鍵,即可自動將命令名稱、命令組名、參數和特定參數值插入命令行 。
預設會在 Azure Cloud Shell 和大部分 Linux 發行版中啟用 Tab 鍵自動完成。 從 Azure CLI 2.49 版開始,您可以在 PowerShell 中啟用 Azure CLI 的索引標籤完成。 執行下列步驟:
建立或編輯儲存在變數 $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配置檔。
另請參閱