共用方式為


在 PowerShell 指令碼語言中運行 Azure CLI 的注意事項

Azure CLI 是一個用來管理 Azure 資源的工具,透過在 Bash 和 PowerShell 腳本語言中運行的 Azure CLI 參考命令來實現。 然而,腳本語言之間在參數格式上有些微的語法差異,可能會導致意想不到的結果。 本文的目的是幫助您在使用 PowerShell 腳本語言時,解決 Azure CLI 語法錯誤。

本文比較在以下腳本語言中執行的 Azure CLI 命令語法差異。

  • 在使用Azure Cloud Shell的 Linux 作業系統中執行 Bash。
  • 在 Azure Cloud Shell 中使用 Linux 作業系統執行 PowerShell
  • Windows PowerShell 在 Windows 11 中執行,使用 PowerShell 5 終端。
  • 在 Windows 11 中使用 PowerShell 7 終端機運行 PowerShell。

如果你是 CLI 新手,可能會難以區分 工具腳本語言如何選擇合適的命令列工具 提供了一個良好的比較。

先決條件

這篇文章是為了讓你閱讀和學習。 但是,如果您想執行示例,請選擇Prepare your environments選項卡來安裝本文中使用的腳本語言。

這很重要

當您使用的 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/

在包含查詢字串的URL中傳遞參數

URL 中的問號表示 URL 的結尾和查詢字串的開頭。 以下是 在瞭解如何使用 Azure CLI 中開啟步驟 3 的範例:

/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 文章的範例:

請注意 $containerRegistryName?api-version 如何在 Bash 中無錯誤地串連在一起。

# Script for a Bash scripting language

# 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 解釋。 您可以使用 --debug 參數看到這個現象:

az "a&b" --debug

# output
'a' is misspelled or not recognized by the system.
'b' is not recognized as an internal or external command

然而,如果您使用相同的測試將標籤添加到資源群組中,標籤值中的符號“&”並不會導致錯誤。

az group create --location eastus2 --name "msdocs-rg-test"
az group update --name "msdocs-rg-test" --tags "company name=Contoso & Sons"

# output
{
  "id": "/subscriptions/3618afcd-ea52-4ceb-bb46-53bb962d4e0b/resourceGroups/msdocs-rg-test",
  "location": "eastus2",
  "managedBy": null,
  "name": "msdocs-rg-test",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": {
    "company name": "Contoso & Sons"
  },
  "type": "Microsoft.Resources/resourceGroups"
}

若您遇到參數值中的與號造成錯誤的情況,可以嘗試以下解決方案:

# When quoted by single quotes ('), double quotes (") are preserved by PowerShell and sent
# to Command Prompt, so that ampersand (&) is treated as a literal character
> az '"a&b"' --debug
Command arguments: ['a&b', '--debug']

# Escape double quotes (") with backticks (`) as required by PowerShell
> az "`"a&b`"" --debug
Command arguments: ['a&b', '--debug']

# Escape double quotes (") by repeating them
> az """a&b""" --debug
Command arguments: ['a&b', '--debug']

# With a whitespace in the argument, double quotes (") are preserved by PowerShell and
# sent to Command Prompt
> az "a&b " --debug
Command arguments: ['a&b ', '--debug']

# Use --% to stop PowerShell from parsing the argument
> az --% "a&b" --debug
Command arguments: ['a&b', '--debug']

傳遞包含@()符號的參數

PowerShell 中有一些特殊字元,例如 @ (@) 符號,這是 PowerShell 中的 展開運算子。 在特殊字符之前添加一個反引號 ` 來轉義它。 你也可以將數值用單引號(')或雙引號(")括起來。

以下三個範例可以在 PowerShell 中運作:

  • 參數名稱為 "@parameters.json"
  • 參數名稱 '@parameters.json'
  • parameterName “@parameters.json”

此範例在 PowerShell 中將無法運行:

  • 參數名稱 @parameters.json

此處是 az ad app create 指令中的另一個範例:請注意,在 PowerShell 腳本語言中需要使用雙引號 ("...") 圍住 JSON 文件名稱。

# Script for a PowerShell scripting language

az ad app create --display-name myTestAppName `
    --is-fallback-public-client `
    --required-resource-accesses "@manifest.json"

傳遞包含 JSON 的參數

對於像 JSON 字串這樣的複雜參數,最佳做法是使用 Azure CLI 的 @<file> 慣例從檔案中載入,以避免被 shell 解釋。 若要查看適用於 Bash、PowerShell 和 Cmd.exe 的 JSON 語法範例,請參閱 腳本語言之間的引用差異 - JSON 字串

傳遞包含鍵值對的參數

某些 Azure CLI 參數值,例如 Azure 資源標籤,要求使用鍵值對。 如果你的 keyvalue 包含空格或特殊字符,Bash 和 PowerShell 的語法不一定總是相同。

想要獲得 Bash、PowerShell 和 Cmd 的語法範例,請參閱 Azure CLI 使用教學中的建立標籤以練習引用差異。 本教程步驟提供以下鍵值對情境的範例:

  • 空間
  • 空值
  • 特殊字符
  • 變數

停止解析符號

在 PowerShell 3.0 中引入的停止解析符號 (--%) 指示 PowerShell 不要將輸入解釋為 PowerShell 命令或表達式。 當遇到停止解析符號時,PowerShell 將行內剩餘的字符視為字面值。

az --% vm create --name xxx

Azure CLI 在 PowerShell 中的錯誤處理

您可以在 PowerShell 中執行 Azure CLI 命令,如 選擇正確的 Azure 命令列工具 中所述。 如果這樣做,請確保您了解在 PowerShell 中的 Azure CLI 錯誤處理方式。 特別是,Azure CLI 並不會產生例外讓 PowerShell 來捕捉。

可以選擇使用$?自動變數。 此變數包含最近一次命令的狀態。 如果上一個命令失敗,$? 就會具有 $False 的值。 如需詳細資訊,請參閱 about_Automatic_Variables

下列範例示範這個自動變數如何運作以處理錯誤:

# Script for a PowerShell scripting language

az group create --name MyResourceGroup
if ($? -eq $false) {
    Write-Error "Error creating resource group."
}

az 指令失敗,因為缺少必要的 --location 參數。 條件語句發現$?為假,並寫入錯誤。

如果您想要使用 trycatch 關鍵詞,可以使用 throw 來建立一個 try 區塊的例外狀況以進行攔截:

# Script for a PowerShell scripting language

$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 關鍵字會創建一個例外來捕捉。 此區塊可以用來撰寫錯誤訊息或處理錯誤。

這個範例將 $ErrorActionPreference 恢復到其預設值。

如需有關 PowerShell 錯誤處理的更多資訊,請參閱您想知道的所有有關例外的資訊

在 PowerShell 中啟用 Tab 鍵自動完成功能

Tab 鍵完成功能,也稱為「Azure CLI 自動完成功能」,可以在輸入時提供提示、啟用探索並加速輸入過程。 按下 Tab 鍵,即可自動將命令名稱、命令組名、參數和特定參數值插入命令行

預設狀態下,Azure Cloud Shell 和大多數 Linux 發行版都啟用標籤完成功能。 從 Azure CLI 2.49 版開始,您可以在 PowerShell 中啟用 Azure CLI 的自動完成功能。 請遵循下列步驟:

  1. 建立或編輯儲存在變數 $PROFILE中的配置檔。 最簡單的方式是在PowerShell中執行 notepad $PROFILE 。 如需詳細資訊,請參閱如何建立設定檔設定檔與執行原則

  2. 將下列程式代碼新增至 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
    }
    
  3. 若要在功能表中顯示所有可用的選項,請將 新增 Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete 至您的PowerShell配置檔。

另請參閱