Расширение Custom Script в ОС Windows

Расширение пользовательских сценариев скачивает и выполняет сценарии на виртуальных машинах Azure. Используйте это расширение для настройки после развертывания, установки программного обеспечения или любой другой задачи настройки или управления. Сценарии можно скачать из службы хранилища Azure или GitHub или передать на портал Azure во время выполнения расширения.

Расширение пользовательских сценариев интегрируется с шаблонами Azure Resource Manager. Его также можно запустить с помощью Azure CLI, Azure PowerShell, портал Azure или REST API Azure Виртуальные машины.

В этой статье описывается, как использовать расширение пользовательского скрипта с помощью модуля Azure PowerShell и шаблонов Azure Resource Manager. В ней статье также показаны шаги по устранению неполадок в системах Windows.

Предварительные требования

Примечание.

Не используйте расширение пользовательского скрипта для запуска Update-AzVM с той же виртуальной машиной, что и его параметр. Расширение будет ждать себя.

Поддерживаемые операционные системы Windows

ОС Windows x64
Windows 10 Поддерживается
Windows 11 Поддерживается
Windows Server 2008 с пакетом обновления 2 (SP2) Поддерживается
Windows Server 2008 R2 Поддерживается
Windows Server 2012 Поддерживается
Windows Server 2012 R2 Поддерживается
Windows Server 2016 Поддерживается
Windows Server 2016 Core Поддерживается
Windows Server 2019 Поддерживается
Windows Server 2019 Core Поддерживается
Windows Server 2022 Поддерживается
Windows Server 2022 Core Поддерживается

Расположение скрипта

Вы можете настроить расширение, чтобы получить доступ к Хранилищу BLOB-объектов Azure с помощью учетных данных службы Хранилища BLOB-объектов Azure. Скрипт может находиться в любом расположении при условии, что виртуальная машина может осуществлять маршрутизацию в конечную точку, например, GitHub или внутренний файловый сервер.

Подключение к Интернету

Чтобы загрузить скрипт из внешнего источника, например из GitHub или службы хранилища Azure, нужно открыть другой брандмауэр или порты группы безопасности сети (NSG). К примеру, если ваш скрипт находится в службе хранилища Azure, можете предоставить к нему доступ с помощью служебных тегов для хранилища Azure NSG.

Расширение пользовательского скрипта не имеет способа обойти проверку сертификата. При скачивании из защищенного расположения, например самозаверяющего сертификата, могут возникнуть ошибки, такие как удаленный сертификат, недопустимый в соответствии с процедурой проверки. Убедитесь, что сертификат правильно установлен в хранилище доверенных корневых центров сертификации на виртуальной машине.

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

Советы

  • Выводятся только последние 4096 байт.
  • Надлежащее преобразование символов поможет правильно проанализировать строки. Например, при работе с путями к файлам всегда требуется две обратные косые черты. Пример: {"commandToExecute": "C:\\Windows\\System32\\systeminfo.exe >> D:\\test.txt"}
  • Наибольшая частота сбоев для этого расширения обусловлена синтаксическими ошибками в скрипте. Проверьте, что скрипт запускается без ошибок. Добавьте больше возможностей ведения журнала в скрипт, чтобы упростить поиск ошибок.
  • Пишите идемпотентные скрипты, чтобы их повторные запуски не вызывали изменения системы.
  • Выполняемые скрипты не должны запрашивать ввод данных пользователем.
  • Выполнение скриптов разрешено в течение 90 минут. Выполняющиеся дольше скрипты вызовут сбой подготовки расширения.
  • Не добавляйте перезагрузки в скрипт. Это действие вызывает проблемы с другими устанавливаемыми расширениями, и расширение не будет работать после перезагрузки.
  • Если у вас есть скрипт, который вызывает к перезагрузку перед установкой приложений и запуском скриптов, назначьте время перезагрузки с помощью запланированного задания Windows или таких инструментов, как расширения DSC, Chef или Puppet.
  • Не запускайте скрипт, который вызывает остановку или обновление агента виртуальных машин. Это может привести к тому, что расширение останется в состоянии перехода, из-за чего истечет время ожидания.
  • Расширение выполняет скрипт только один раз. Если вы хотите выполнять скрипт при каждой загрузке, используйте расширение, чтобы создать запланированную задачу Windows.
  • Чтобы запланировать время выполнения скрипта, создайте запланированную задачу Windows с помощью расширения.
  • Во время выполнения скрипта вы увидите на портале Azure или в Azure CLI только переходное состояние расширения. Если требуются более частые обновления состояния выполняющегося скрипта, создайте собственное решение.
  • Расширение пользовательских скриптов не предусматривает собственную поддержку прокси-серверов. Но вы можете использовать средство передачи файлов, которое поддерживает прокси-серверы в скрипте, такое как Invoke-WebRequest.
  • Следует учитывать настраиваемые расположения каталогов, которые могут использоваться вашими скриптами или командами. Для решения этой ситуации необходимо иметь в распоряжении логику.
  • Расширение пользовательских скриптов будет выполняться под учетной записью LocalSystem.
  • Если вы планируете использовать свойства storageAccountName и storageAccountKey, эти свойства должны находиться в protectedSettings.
  • К виртуальной машине можно применить только одну версию расширения. Чтобы запустить второй пользовательский скрипт, можно применить к имеющемуся расширению новую конфигурацию. Кроме того, можно удалить расширение пользовательских скриптов и повторно применить его с измененным скриптом.

Схема расширения

В конфигурации расширения пользовательских сценариев указываются такие параметры, как расположение сценария и команда для его выполнения. Эту конфигурацию можно хранить в файлах конфигурации, указать в командной строке или в шаблоне Azure Resource Manager.

Конфиденциальные данные можно хранить в защищенной конфигурации, которая шифруется и расшифровывается только на виртуальной машине. Защищенная конфигурация удобна, если команда выполнения содержит секреты, такие как пароль или ссылка на подписанный URL-адрес (SAS) файла. Приведем пример:

{
    "apiVersion": "2018-06-01",
    "type": "Microsoft.Compute/virtualMachines/extensions",
    "name": "virtualMachineName/config-app",
    "location": "[resourceGroup().location]",
    "dependsOn": [
        "[concat('Microsoft.Compute/virtualMachines/', variables('vmName'),copyindex())]",
        "[variables('musicstoresqlName')]"
    ],
    "tags": {
        "displayName": "config-app"
    },
    "properties": {
        "publisher": "Microsoft.Compute",
        "type": "CustomScriptExtension",
        "typeHandlerVersion": "1.10",
        "autoUpgradeMinorVersion": true,
        "settings": {
            "timestamp":123456789
        },
        "protectedSettings": {
            "commandToExecute": "myExecutionCommand",
            "storageAccountName": "myStorageAccountName",
            "storageAccountKey": "myStorageAccountKey",
            "managedIdentity" : {},
            "fileUris": [
                "script location"
            ]
        }
    }
}

Примечание.

Свойство managedIdentity не должно применяться вместе со свойствами storageAccountName или storageAccountKey.

Одновременно можно установить только одну версию расширения на виртуальной машине. Указание пользовательского скрипта дважды в одном шаблоне Azure Resource Manager для одной виртуальной машины завершается сбоем.

Эту схему можно использовать в ресурсе виртуальной машины или в качестве автономного ресурса. Если это расширение используется в качестве автономного ресурса в шаблоне Azure Resource Manager, имя ресурса должно быть в формате virtualMachineName/extensionName.

Значения свойств

Имя. Значение или пример Тип данных
версия_API 2015-06-15 Дата
издатель Microsoft.Compute строка
type CustomScriptExtension строка
typeHandlerVersion 1.10 INT
fileUris https://raw.githubusercontent.com/Microsoft/dotnet-core-sample-templates/master/dotnet-core-music-windows/scripts/configure-music-app.ps1 array
TIMESTAMP 123456789 32-разрядное целое число
commandToExecute powershell -ExecutionPolicy Unrestricted -File configure-music-app.ps1 строка
storageAccountName examplestorageacct строка
storageAccountKey TmJK/1N3AbAZ3q/+hOXoi/l73zOqsaxXDhqa9Y83/v5UpXQp2DQIBuv2Tifp60cE/OaHsJZmQZ7teQfczQj8hg== строка
managedIdentity { } или { "clientId": "31b403aa-c364-4240-a7ff-d85fb6cd7232" } или { "objectId": "12dd289c-0583-46e5-b9b4-115d5c19ef4b" } Объект JSON

Примечание.

В именах свойств учитывается регистр. Чтобы избежать проблем с развертыванием, используйте имена, как показано ниже.

Сведения о значениях свойств

Свойство Необязательное или обязательное Сведения
fileUris Необязательно URL-адреса для загрузки файлов. Если URL-адреса чувствительны, например, если они содержат ключи, это поле должно быть указано в protectedSettings.
commandToExecute Обязательное поле Точка входа для выполнения скрипта. Если команда содержит секретные данные, например пароли, или если универсальные коды ресурса (URI) для файлов являются конфиденциальным, используйте это свойство.
TIMESTAMP Необязательно Меняйте это значение, только чтобы вызвать перезапуск скрипта. Допускается любое целое значение, если оно отличается от предыдущего значения.
storageAccountName Необязательно Название учетной записи хранения. Если указаны учетные данные хранилища, все значения fileUris должны иметь формат URL-адресов для BLOB-объектов Azure.
storageAccountKey Необязательно Ключ доступа учетной записи хранения.
managedIdentity Необязательно Управляемое удостоверение для скачивания файлов. Допустимые значения — clientId (необязательно, строка), которая является идентификатором клиента управляемого удостоверения и objectId (необязательной, строкой), которая является идентификатором объекта управляемого удостоверения.

Общедоступные параметры отправляются в виде открытого текста на виртуальную машину, в которой выполняется скрипт. Защищенные параметры шифруются с помощью ключа, известного только в Azure и виртуальной машине. Параметры сохраняются на виртуальной машине по мере их отправки. Это значит, что если параметры были зашифрованы, они сохранятся в таком виде и на виртуальной машине. Сертификат, используемый для расшифровки зашифрованных значений, хранится на виртуальной машине. При необходимости сертификат также используется для расшифровки параметров во время выполнения.

Открытые параметры могут быть полезны для отладки, но мы рекомендуем использовать защищенные параметры.

Приведенные ниже значения можно задать в открытых или защищенных параметрах. Расширение отклоняет любую конфигурацию, в которой эти значения задаются как в общедоступных, так и защищенных параметрах.

  • commandToExecute
  • fileUris

Свойство: managedIdentity

Примечание.

Это свойство должно быть задано только в защищенных параметрах.

Расширение пользовательского скрипта версии 1.10 и более поздних версий поддерживает управляемые удостоверения для скачивания файлов из URL-адресов, предоставленных в параметре fileUris . Свойство позволяет расширению пользовательского скрипта получать доступ к служба хранилища Azure частным большим двоичным объектам или контейнерам без необходимости передавать секреты, такие как маркеры SAS или ключи учетной записи хранения.

Чтобы использовать эту функцию, добавьте назначаемое системой удостоверение или удостоверение, назначаемое пользователем, в виртуальную машину или масштабируемый набор виртуальных машин, где выполняется расширение пользовательского скрипта. Затем предоставьте управляемому удостоверению доступ к контейнеру служба хранилища Azure или большому двоичному объекту.

Чтобы использовать назначаемое системой удостоверение на целевой виртуальной машине или масштабируемом наборе виртуальных машин, задайте managedidentity пустой объект JSON.

{
  "fileUris": ["https://mystorage.blob.core.windows.net/privatecontainer/script1.ps1"],
  "commandToExecute": "powershell.exe script1.ps1",
  "managedIdentity" : {}
}

Чтобы использовать назначаемое пользователем удостоверение на целевой виртуальной машине или масштабируемом наборе виртуальных машин, настройте managedidentity идентификатор клиента или идентификатор объекта управляемого удостоверения.

{
  "fileUris": ["https://mystorage.blob.core.windows.net/privatecontainer/script1.ps1"],
  "commandToExecute": "powershell.exe script1.ps1",
  "managedIdentity" : { "clientId": "31b403aa-c364-4240-a7ff-d85fb6cd7232" }
}
{
  "fileUris": ["https://mystorage.blob.core.windows.net/privatecontainer/script1.ps1"],
  "commandToExecute": "powershell.exe script1.ps1",
  "managedIdentity" : { "objectId": "12dd289c-0583-46e5-b9b4-115d5c19ef4b" }
}

Примечание.

Свойство managedIdentity не должно применяться вместе со свойствами storageAccountName или storageAccountKey.

Развертывание шаблона

Вы можете развернуть расширения виртуальной машины Azure с помощью шаблонов Azure Resource Manager. Схема JSON, подробно описанная в предыдущем разделе, может использоваться в шаблоне Azure Resource Manager для запуска расширения пользовательского скрипта во время развертывания шаблона. Приведенные ниже примеры демонстрируют использование расширения пользовательских сценариев:

Развертывание с помощью PowerShell

Вы можете использовать команду Set-AzVMCustomScriptExtension, чтобы добавить расширение пользовательских сценариев в существующую виртуальную машину. Дополнительные сведения см. в статье о Set-AzVMCustomScriptExtension.

Set-AzVMCustomScriptExtension -ResourceGroupName <resourceGroupName> `
    -VMName <vmName> `
    -Location myLocation `
    -FileUri <fileUrl> `
    -Run 'myScript.ps1' `
    -Name DemoScriptExtension

Примеры

Использование нескольких скриптов

В этом примере для сборки сервера используются три скрипта. Свойство commandToExecute вызывает первый скрипт. Также есть параметры, с помощью которых вызываются другие. Например, можно использовать скрипт свинца, который управляет выполнением, с правильной обработкой ошибок, ведением журнала и управлением состоянием. Скрипты скачиваются на локальный компьютер для запуска.

Например, в 1_Add_Tools.ps1можно вызвать 2_Add_Features.ps1, добавив .\2_Add_Features.ps1 в скрипт. Повторите этот процесс для других скриптов, которые вы определили.$settings

$fileUri = @("https://xxxxxxx.blob.core.windows.net/buildServer1/1_Add_Tools.ps1",
"https://xxxxxxx.blob.core.windows.net/buildServer1/2_Add_Features.ps1",
"https://xxxxxxx.blob.core.windows.net/buildServer1/3_CompleteInstall.ps1")

$settings = @{"fileUris" = $fileUri};

$storageAcctName = "xxxxxxx"
$storageKey = "1234ABCD"
$protectedSettings = @{"storageAccountName" = $storageAcctName; "storageAccountKey" = $storageKey; "commandToExecute" = "powershell -ExecutionPolicy Unrestricted -File 1_Add_Tools.ps1"};

#run command
Set-AzVMExtension -ResourceGroupName <resourceGroupName> `
    -Location <locationName> `
    -VMName <vmName> `
    -Name "buildserver1" `
    -Publisher "Microsoft.Compute" `
    -ExtensionType "CustomScriptExtension" `
    -TypeHandlerVersion "1.10" `
    -Settings $settings `
    -ProtectedSettings $protectedSettings;

Запуск скриптов из локальной общей папки

В этом примере может потребоваться использовать локальный сервер SMB в качестве расположения скрипта. Тогда вам не нужно указывать другие параметры, кроме commandToExecute.

$protectedSettings = @{"commandToExecute" = "powershell -ExecutionPolicy Unrestricted -File \\filesvr\build\serverUpdate1.ps1"};

Set-AzVMExtension -ResourceGroupName <resourceGroupName> `
    -Location <locationName> `
    -VMName <vmName> `
    -Name "serverUpdate"
    -Publisher "Microsoft.Compute" `
    -ExtensionType "CustomScriptExtension" `
    -TypeHandlerVersion "1.10" `
    -ProtectedSettings $protectedSettings

Запуск пользовательского скрипта более одного раза с помощью интерфейса командной строки

Обработчик расширения пользовательского скрипта предотвращает повторное выполнение скрипта, если были переданы те же параметры. Такое поведение предотвращает случайный перезапуск, который может привести к непредвиденному поведению, если скрипт не является идемпотентным. Чтобы убедиться, что обработчик заблокировал повторное выполнение, посмотрите.C:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension\<HandlerVersion>\CustomScriptHandler.log* Выполните поиск предупреждения следующим образом:

Current sequence number, <SequenceNumber>, is not greater than the sequence number
of the most recently executed configuration. Exiting...

Чтобы выполнить расширение пользовательского скрипта более одного раза, должны соблюдаться следующие условия:

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

Кроме того, можно задать для свойства ForceUpdateTag значение true.

Использование Invoke-WebRequest

Если вы используете Invoke-WebRequest в скрипте, необходимо указать параметр -UseBasicParsing. Если параметр не указан, при проверка подробного состояния вы получите следующую ошибку:

The response content cannot be parsed because the Internet Explorer engine
is not available, or Internet Explorer's first-launch configuration
is not complete. Specify the UseBasicParsing parameter and try again.

Масштабируемые наборы виртуальных машин

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

Рекомендуется использовать PowerShell, Azure CLI или шаблон Azure Resource Manager при развертывании расширения пользовательского скрипта в масштабируемом наборе виртуальных машин. Таким образом, вы можете использовать управляемое удостоверение или иметь возможность непосредственного управления сроком действия маркера SAS для доступа к скрипту в вашей учетной записи хранения столько, сколько потребуется.

Устранение неполадок и поддержка

Данные о состоянии развертывания расширения можно получить на портале Azure, а также с помощью модуля Azure PowerShell. Чтобы просмотреть состояние развертывания расширений для виртуальной машины, выполните следующую команду:

Get-AzVMExtension -ResourceGroupName <resourceGroupName> `
    -VMName <vmName> -Name myExtensionName

Выходные данные расширения регистрируются в файле, расположенном в следующей папке на целевой виртуальной машине:

C:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension

Указанные файлы скачиваются в указанную ниже папку на целевой виртуальной машине:

C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.*\Downloads\<n>

В предыдущем пути <n> — это десятичное целое число, которое может меняться между выполнениями расширения. Значение 1.* соответствует фактическому текущему значению typeHandlerVersion расширения. Например, фактическим каталогом может быть C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.8\Downloads\2.

При выполнении commandToExecute команды расширение задает этот каталог, например, ...\Downloads\2в качестве текущего рабочего каталога. Этот процесс позволяет использовать относительные пути для поиска файлов, скачанных с помощью fileURIs свойства. Ниже приведены примеры скачанных файлов:

URI в fileUris Относительное расположение скачанных файлов Абсолютное расположение скачивания
https://someAcct.blob.core.windows.net/aContainer/scripts/myscript.ps1 ./scripts/myscript.ps1 C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.8\Downloads\2\scripts\myscript.ps1
https://someAcct.blob.core.windows.net/aContainer/topLevel.ps1 ./topLevel.ps1 C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.8\Downloads\2\topLevel.ps1

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

Так как со временем абсолютный путь для скачивания может измениться, в строке commandToExecute лучше указывать относительные пути к сценариям или файлам, когда это возможно. Например:

"commandToExecute": "powershell.exe . . . -File \"./scripts/myscript.ps1\""

Сведения о пути после первого сегмента URI хранятся для файлов, скачанных с помощью fileUris списка свойств. Как показано в таблице выше, скачанные файлы распределяются по подкаталогам в соответствии со структурой значений fileUris.

Поддержка

  • Если вам нужна помощь с любой частью этой статьи, обратитесь к экспертам Azure в службе поддержки сообщества Azure.

  • Чтобы отправить инцидент поддержка Azure, перейдите на сайт поддержка Azure и выберите "Получить поддержку".

  • Дополнительные сведения об использовании службы поддержки Azure см. в статье Часто задаваемые вопросы о поддержке Microsoft Azure.