Поделиться через


Соображения по запуску Azure CLI в сценарном языке PowerShell

Средство командной строки Azure (Azure CLI) — это инструмент для управления ресурсами Azure с помощью ссылочных команд Azure CLI, которые могут выполняться как в среде Bash, так и в PowerShell. Однако существуют небольшие различия в синтаксисе форматирования параметров между языками сценариев, которые могут привести к непредвиденным результатам. Цель данной статьи - помочь вам устранить ошибки синтаксиса Azure CLI при работе с языком сценариев PowerShell.

Эта статья сравнивает различия в синтаксисе команд Azure CLI, выполняемых в следующих языках сценариев:

  • Bash, работающий в операционной системе Linux с использованием Azure Cloud Shell.
  • PowerShell, работающая в операционной системе Linux с использованием Azure Cloud Shell.
  • Windows PowerShell , запущенная в Windows 11 с помощью терминала PowerShell 5.
  • PowerShell, работающий в Windows 11 с использованием терминала PowerShell 7.

Если вы только начали работать с CLI, различать инструмент и язык сценариев может быть запутанно. Как выбрать подходящий инструмент командной строки предлагает хорошее сравнение.

Предпосылки

Эта статья предназначена для того, чтобы вы могли её прочитать и узнать что-то новое. Однако, если вы хотите запустить примеры, выберите вкладку Prepare your environments для установки языков сценариев, используемых в этой статье.

Это важно

Когда у вас есть скрипт Azure CLI, который выдает ошибку, учтите, как использованный вами язык сценариев анализирует синтаксис команд Azure CLI.

Передавайте пробелы в параметрах Azure CLI

В Azure CLI, когда вам нужно передать значение параметра, содержащего пробел, существуют различия в кавычках между операционными системами и языками сценариев. В этом примере используйте az storage account list и переименуйте выходные столбцы, используя слово, содержащее пробел.

В этом примере обратите внимание на оболочку одинарной кавычкой ('...') с встроенными двойными кавычками ("..."). Этот пример также работает в PowerShell на Linux.

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 >=...". Однако в Bash в среде Linux ваш вывод выглядит примерно так:

SA Name           Primary Endpoint
-----------       -----------------
msdocssa00000000  https://msdocssa000000000.blob.core.windows.net/

Передайте параметры в URL, содержащем строку запроса

Вопросительные знаки в URL-адресах указывают на конец URL-адреса и начало строки запроса. Вот пример, который открывает шаг 3 в Узнать, как использовать Azure CLI:

/cli/azure/account?view=azure-cli-2020-09-01-hybrid.

Результаты ?view=azure-cli-2020-09-01-hybrid приводят к желаемой версии справочного материала Azure CLI.

Когда вы выполняете команды Azure CLI в скриптовом языке PowerShell, PowerShell позволяет вопросительным знакам быть частью имени переменной. Это может вызвать путаницу в значениях параметров Azure CLI.

Вот пример из статьи Использование REST API Azure:

Заметьте, как $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']

Передайте параметры, содержащие символ at (@)

В PowerShell существуют специальные символы, такие как символ at (@), который является оператором распознавания в PowerShell. Добавьте обратный апостроф ` перед специальным символом, чтобы избежать его. Вы также можете заключить значение в одинарные (') или двойные (") кавычки.

Следующие три примера будут работать в PowerShell:

  • `parameterName '@parameters.json
  • parameterName '@parameters.json'
  • parameterName "@parameters.json"

Этот пример не будет работать в PowerShell:

  • имяПараметра @parameters.json

Вот еще один пример в команде az ad app create: Обратите внимание на двойные кавычки ("...") вокруг имени файла JSON, которые необходимы в языке скриптов PowerShell.

# 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 для загрузки из файла, чтобы избежать интерпретации оболочки. Для примеров синтаксиса JSON для Bash, PowerShell и Cmd.exe смотрите Различия в кавычках между языками сценариев - строки JSON.

Передайте параметры, содержащие пары ключ:значение

Некоторые значения параметров Azure CLI, такие как теги ресурсов Azure, требуют пары ключ:значение. Если ваш key или value содержит пробел или специальный символ, то синтаксис Bash и PowerShell не всегда совпадают.

Для примеров синтаксиса Bash, PowerShell и Cmd см. Создание тегов для практики различий в кавычках в учебнике Изучение использования Azure CLI. Этот шаг руководства приводит примеры для следующих сценариев пар ключ:значение:

  • пространства
  • пустые значения
  • специальные символы
  • переменные

Символ остановки парсинга

Символ прекращения анализа (--%), введенный в PowerShell 3.0, указывает PowerShell не интерпретировать ввод как команды или выражения PowerShell. При встрече со стоп-символом анализа PowerShell воспринимает оставшиеся символы в строке как литерал.

az --% vm create --name xxx

Обработка ошибок для Azure CLI в PowerShell

Вы можете запускать команды Azure CLI в PowerShell, как описано в Выберите правильный инструмент командной строки Azure. Если да, убедитесь, что вы понимаете обработку ошибок Azure CLI в PowerShell. В частности, 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. Условное выражение определяет, что $? ложно, и выводит ошибку.

Если вы хотите использовать ключевые слова try и catch, вы можете использовать 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 слово создает исключение для перехвата. Блок catch может быть использован для написания сообщения об ошибке или обработки ошибки.

Пример восстанавливает $ErrorActionPreference до значения по умолчанию.

Дополнительные сведения об обработке ошибок PowerShell см. в разделе "Все, что вы хотели знать об исключениях".

Включение автозавершения вкладок в PowerShell

Автодополнение, также известное как "дополнители Azure CLI", обеспечивает завершение ввода для предоставления подсказок, облегчения поиска и ускорения ввода информации. Имена команд, имена групп команд, параметры и определенные значения параметров можно автоматически вставить в командную строку, нажав клавишу TAB .

Функция автодополнения вкладок включена по умолчанию в Azure Cloud Shell и в большинстве дистрибутивов Linux. Начиная с Azure CLI версии 2.49 можно включить завершение вкладки для Azure CLI в PowerShell. Выполните следующие действия.

  1. Создайте или измените профиль, хранящийся в переменной $PROFILE. Самый простой способ — запустить notepad $PROFILE в PowerShell. Дополнительные сведения см. в разделах How to create your profile (Как создать свой профиль) и Profiles and execution policy (Профили и политика выполнения).

  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.

См. также