Создание образа Виртуального рабочего стола Azure с помощью Конструктора образов виртуальных машин Azure и PowerShell

Область применения: ✔️ Виртуальные машины Windows

Из этой статьи вы узнаете, как создать образ Виртуального рабочего стола Azure со следующими настройками:

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

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

Эта статья предназначена для использования в качестве упражнения по копированию и вставке.

Примечание

Скрипты для установки приложений доступны на сайте GitHub. Они предназначены только для иллюстрации и тестирования. Не используйте их для выполнения задач в рабочей среде.

Советы по созданию образов Windows

  • Для Windows используйте размер виртуальной машины Standard_D2_v2 или больше. По умолчанию используется размер Standard_D1_v2, который не подходит для Windows.

  • В этой статье применяются скрипты настройщика PowerShell. Используйте следующие параметры, иначе сборка перестанет отвечать на запросы:

      "runElevated": true,
      "runAsSystem": true,
    

    Пример:

      {
          "type": "PowerShell",
          "name": "installFSLogix",
          "runElevated": true,
          "runAsSystem": true,
          "scriptUri": "https://raw.githubusercontent.com/azure/azvmimagebuilder/main/solutions/14_Building_Images_WVD/0_installConfFsLogix.ps1"
    
  • Закомментируйте код. Ведется подробный журнал сборки Конструктора образов виртуальных машин (файл customization.log). Если вы закомментируете скрипты с использованием write-host, они будут отправляться в журналы. Это упростит устранение неполадок.

     write-host 'AIB Customization: Starting OS Optimizations script'
    
  • Коды выхода. Конструктор образов виртуальных машин ожидает, что все скрипты будут возвращать код выхода 0. Если вы используете код выхода, отличный от нуля, Конструктор образов виртуальных машин завершит настройку и остановит сборку. При наличии сложных скриптов добавьте инструментирование и отправьте коды выхода, которые будут отображаться в файле customization.log.

     Write-Host "Exit code: " $LASTEXITCODE
    
  • Тест. Тестирование и повторное тестирование кода на автономной виртуальной машине. Убедитесь, что отсутствуют запросы пользователей, используются правильные привилегии и т. д.

  • Сеть. Командлет Set-NetAdapterAdvancedProperty задается в скрипте оптимизации, но приводит к сбою сборки Конструктора образов виртуальных машин. Так как этот командлет отключает соединение с сетью, он закомментирована. Мы изучаем эту проблему.

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

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

# Check to ensure that you're registered for the providers and RegistrationState is set to 'Registered'
Get-AzResourceProvider -ProviderNamespace Microsoft.VirtualMachineImages
Get-AzResourceProvider -ProviderNamespace Microsoft.Storage 
Get-AzResourceProvider -ProviderNamespace Microsoft.Compute
Get-AzResourceProvider -ProviderNamespace Microsoft.KeyVault
Get-AzResourceProvider -ProviderNamespace Microsoft.ContainerInstance

# If they don't show as 'Registered', run the following commented-out code

## Register-AzResourceProvider -ProviderNamespace Microsoft.VirtualMachineImages
## Register-AzResourceProvider -ProviderNamespace Microsoft.Storage
## Register-AzResourceProvider -ProviderNamespace Microsoft.Compute
## Register-AzResourceProvider -ProviderNamespace Microsoft.KeyVault
## Register-AzResourceProvider -ProviderNamespace Microsoft.ContainerInstance

Настройка среды и переменных

# Step 1: Import module
Import-Module Az.Accounts

# Step 2: get existing context
$currentAzContext = Get-AzContext

# Destination image resource group
$imageResourceGroup="avdImageDemoRg"

# Location (see possible locations in the main docs)
$location="westus2"

# Your subscription. This command gets your current subscription
$subscriptionID=$currentAzContext.Subscription.Id

# Image template name
$imageTemplateName="avd10ImageTemplate01"

# Distribution properties object name (runOutput). Gives you the properties of the managed image on completion
$runOutputName="sigOutput"

# Create resource group
New-AzResourceGroup -Name $imageResourceGroup -Location $location

Разрешения, удостоверение пользователя и роль

  1. Создайте удостоверение пользователя.

    # setup role def names, these need to be unique
    $timeInt=$(get-date -UFormat "%s")
    $imageRoleDefName="Azure Image Builder Image Def"+$timeInt
    $identityName="aibIdentity"+$timeInt
    
    ## Add Azure PowerShell modules to support AzUserAssignedIdentity and Azure VM Image Builder
    'Az.ImageBuilder', 'Az.ManagedServiceIdentity' | ForEach-Object {Install-Module -Name $_ -AllowPrerelease}
    
    # Create the identity
    New-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName -Location $location
    
    $identityNameResourceId=$(Get-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName).Id
    $identityNamePrincipalId=$(Get-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName).PrincipalId
    
    
  2. Назначьте разрешения удостоверению для распространения образов. Следующие команды позволяют скачать и обновить шаблон с помощью ранее заданных параметров.

    $aibRoleImageCreationUrl="https://raw.githubusercontent.com/azure/azvmimagebuilder/main/solutions/12_Creating_AIB_Security_Roles/aibRoleImageCreation.json"
    $aibRoleImageCreationPath = "aibRoleImageCreation.json"
    
    # Download the config
    Invoke-WebRequest -Uri $aibRoleImageCreationUrl -OutFile $aibRoleImageCreationPath -UseBasicParsing
    
    ((Get-Content -path $aibRoleImageCreationPath -Raw) -replace '<subscriptionID>',$subscriptionID) | Set-Content -Path $aibRoleImageCreationPath
    ((Get-Content -path $aibRoleImageCreationPath -Raw) -replace '<rgName>', $imageResourceGroup) | Set-Content -Path $aibRoleImageCreationPath
    ((Get-Content -path $aibRoleImageCreationPath -Raw) -replace 'Azure Image Builder Service Image Creation Role', $imageRoleDefName) | Set-Content -Path $aibRoleImageCreationPath
    
    # Create a role definition
    New-AzRoleDefinition -InputFile  ./aibRoleImageCreation.json
    
    # Grant the role definition to the VM Image Builder service principal
    New-AzRoleAssignment -ObjectId $identityNamePrincipalId -RoleDefinitionName $imageRoleDefName -Scope "/subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup"
    

Примечание

В случае отображения ошибки: "New-AzRoleDefinition. Предел определения роли превышен. Невозможно создать дополнительные определения.", см. статью Устранение неполадок с Azure RBAC (управление доступом на основе ролей).

Если у вас еще нет Коллекции вычислений Azure, ее необходимо создать.

$sigGalleryName= "myaibsig01"
$imageDefName ="win10avd"

# Create the gallery
New-AzGallery -GalleryName $sigGalleryName -ResourceGroupName $imageResourceGroup  -Location $location

# Create the gallery definition
New-AzGalleryImageDefinition -GalleryName $sigGalleryName -ResourceGroupName $imageResourceGroup -Location $location -Name $imageDefName -OsState generalized -OsType Windows -Publisher 'myCo' -Offer 'Windows' -Sku '10avd'

Настройка шаблона Конструктора образов виртуальных машин

Для этого примера мы подготовили шаблон, с помощью которого скачивается и обновляется шаблон Конструктора образов виртуальных машин с заданными ранее параметрами. Шаблон позволяет установить FSLogix, оптимизации операционной системы и Microsoft Teams, а затем запустить клиентский компонент Центра обновления Windows.

При открытии шаблона в исходном свойстве отображается используемый образ. В этом примере используется образ Windows 10 для нескольких сеансов.

Образы Windows 10

Учитывайте, что есть два основных типа образов: для нескольких сеансов и для одного сеанса.

Образы с несколькими сеансами предназначены для использования в пуле. Вот пример сведений об образе в Azure:

"publisher": "MicrosoftWindowsDesktop",
"offer": "Windows-10",
"sku": "20h2-avd",
"version": "latest"

Образы с одним сеансом предназначены для индивидуального использования. Вот пример сведений об образе в Azure:

"publisher": "MicrosoftWindowsDesktop",
"offer": "Windows-10",
"sku": "19h2-ent",
"version": "latest"

Кроме того, вы можете изменить набор доступных образов Windows 10:

Get-AzVMImageSku -Location westus2 -PublisherName MicrosoftWindowsDesktop -Offer windows-10

Скачивание и настройка шаблона

Теперь скачайте шаблон и настройте его для собственного использования.

$templateUrl="https://raw.githubusercontent.com/azure/azvmimagebuilder/main/solutions/14_Building_Images_WVD/armTemplateWVD.json"
$templateFilePath = "armTemplateWVD.json"

Invoke-WebRequest -Uri $templateUrl -OutFile $templateFilePath -UseBasicParsing

((Get-Content -path $templateFilePath -Raw) -replace '<subscriptionID>',$subscriptionID) | Set-Content -Path $templateFilePath
((Get-Content -path $templateFilePath -Raw) -replace '<rgName>',$imageResourceGroup) | Set-Content -Path $templateFilePath
((Get-Content -path $templateFilePath -Raw) -replace '<region>',$location) | Set-Content -Path $templateFilePath
((Get-Content -path $templateFilePath -Raw) -replace '<runOutputName>',$runOutputName) | Set-Content -Path $templateFilePath

((Get-Content -path $templateFilePath -Raw) -replace '<imageDefName>',$imageDefName) | Set-Content -Path $templateFilePath
((Get-Content -path $templateFilePath -Raw) -replace '<sharedImageGalName>',$sigGalleryName) | Set-Content -Path $templateFilePath
((Get-Content -path $templateFilePath -Raw) -replace '<region1>',$location) | Set-Content -Path $templateFilePath
((Get-Content -path $templateFilePath -Raw) -replace '<imgBuilderId>',$identityNameResourceId) | Set-Content -Path $templateFilePath

Вы можете без труда просматривать шаблон. Весь код доступен для просмотра.

Отправка шаблона

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

New-AzResourceGroupDeployment -ResourceGroupName $imageResourceGroup -TemplateFile $templateFilePath -TemplateParameterObject @{"api-Version" = "2020-02-14"; "imageTemplateName" = $imageTemplateName; "svclocation" = $location}

# Optional - if you have any errors running the preceding command, run:
$getStatus=$(Get-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name $imageTemplateName)
$getStatus.ProvisioningErrorCode 
$getStatus.ProvisioningErrorMessage

Создание образа

Start-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name $imageTemplateName -NoWait

Примечание

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

$getStatus=$(Get-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name $imageTemplateName)

# Shows all the properties
$getStatus | Format-List -Property *

# Shows the status of the build
$getStatus.LastRunStatusRunState 
$getStatus.LastRunStatusMessage
$getStatus.LastRunStatusRunSubState

Создание виртуальной машины

Теперь, когда образ создан, можно создать на его основе виртуальную машину. Используйте примеры из раздела New-AzVM (Az PowerShell module.Compute).

Очистка ресурсов

Если вам больше не нужны ресурсы, созданные во время этого процесса, их можно удалить следующим образом:

Важно!

Сначала удалите шаблон группы ресурсов. Если удалить только группу ресурсов, промежуточная группа ресурсов (IT_), используемая Конструктором образов виртуальных машин, не будет удалена.

  1. Удалите шаблон Конструктора образов виртуальных машин.

    Remove-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name vd10ImageTemplate
    
  2. Удалите назначение роли.

    Remove-AzRoleAssignment -ObjectId $identityNamePrincipalId -RoleDefinitionName $imageRoleDefName -Scope "/subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup"
    
    ## Remove the definitions
    Remove-AzRoleDefinition -Name "$identityNamePrincipalId" -Force -Scope "/subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup"
    
    ## Delete the identity
    Remove-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName -Force
    
  3. Удалите ее.

    Remove-AzResourceGroup $imageResourceGroup -Force
    

Дальнейшие действия

Чтобы опробовать другие примеры Конструктора образов виртуальных машин, перейдите на сайт GitHub.