Erstellen eines Azure Virtual Desktop-Images mit VM Image Builder und PowerShell

Gilt für: ✔️ Windows-VMs

Dieser Artikel zeigt Ihnen, wie Sie ein Azure Virtual Desktop-Image mit diesen Anpassungen erstellen können:

In diesem Artikel wird erläutert, wie Sie die Anpassungen mithilfe des Azure VM Image Builder automatisieren. Anschließend können Sie das Image an eine Azure Compute Gallery (früher Shared Image Gallery) verteilen, wo Sie es in anderen Regionen replizieren, die Skalierung steuern und das Image innerhalb und über Ihre Organisation hinaus freigeben können.

Um die Bereitstellung einer VM Image Builder-Konfiguration zu vereinfachen, wird in diesem Beispiel eine Azure Resource Manager-Vorlage mit der darin geschachtelten VM Image Builder-Vorlage verwendet. Dieser Ansatz bietet Ihnen einige weitere Vorteile, z. B. die Eingabe von Variablen und Parametern. Sie können Parameter auch über die Befehlszeile übergeben.

Dieser Artikel ist als Kopier- und Einfügeübung gedacht.

Hinweis

Sie finden die Skripts zum Installieren der Apps unter GitHub. Sie dienen nur zu Veranschaulichungs- und Testzwecken. Verwenden Sie sie nicht für Produktionsworkloads.

Tipps zum Erstellen von Windows-Images

  • Größe des virtuellen Computers: Verwenden sie für Windows Standard_D2_v2 oder größer. Die Standardgröße ist Standard_D1_v2, die nicht für Windows geeignet ist.

  • In diesem Artikel werden die PowerShell-Anpassungsskripts verwendet. Verwenden Sie die folgenden Einstellungen, oder der Build wird nicht mehr reagieren:

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

    Beispiel:

      {
          "type": "PowerShell",
          "name": "installFSLogix",
          "runElevated": true,
          "runAsSystem": true,
          "scriptUri": "https://raw.githubusercontent.com/azure/azvmimagebuilder/main/solutions/14_Building_Images_WVD/0_installConfFsLogix.ps1"
    
  • Kommentieren Sie Ihren Code: Das Buildprotokoll des VM Image Builder, customization.log, ist ausführlich. Wenn Sie Ihre Skripts mithilfe von „write-host“ kommentieren, werden sie an die Protokolle gesendet, was die Problembehandlung erleichtern sollte.

     write-host 'AIB Customization: Starting OS Optimizations script'
    
  • Exitcodes: VM Image Builder erwartet, dass alle Skripts einen 0-Exitcode zurückgeben. Wenn Sie einenExit-Code verwenden, der nicht NULL ist, lässt der VM Image Builder die Anpassung fehlschlagen und beendet den Build. Wenn Sie komplexe Skripts verwenden, Instrumentierung hinzufügen und Exitcodes ausgeben, wird dies in der Datei customization.log angezeigt.

     Write-Host "Exit code: " $LASTEXITCODE
    
  • Test: Testen Sie Ihren Code auf einem eigenständigen virtuellen Computer und wiederholen Sie diese Tests. Vergewissern Sie sich, dass keine Benutzereingabeaufforderungen angezeigt werden, dass Sie die richtigen Berechtigungen verwenden und so weiter.

  • Netzwerk: Set-NetAdapterAdvancedProperty ist im Optimierungsskript festgelegt, lässt jedoch den VM Image Builder-Build fehlschlagen. Da es das Netzwerk trennt, wird es auskommentiert. Wir untersuchen dieses Problem.

Voraussetzungen

Stellen Sie zunächst sicher, dass Sie die aktuellen Azure PowerShell-Cmdlets installiert haben. Weitere Informationen finden Sie in der Übersicht über 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

Einrichten der Umgebung und Variablen

# 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

Berechtigungen, Benutzeridentität und Rolle

  1. Erstellen Sie eine Benutzeridentität.

    # 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. Weisen Sie der Identität Berechtigungen zum Verteilen von Images zu. Die folgenden Befehle laden die Vorlage mit den zuvor angegebenen Parametern herunter und aktualisieren sie.

    $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"
    

Hinweis

Wenn Sie die Fehlermeldung „New-AzRoleDefinition: Rollendefinitionsgrenze überschritten. Es können keine weiteren Rollendefinitionen erstellt werden“ erhalten, siehe Fehlerbehebung für Azure RBAC (rollenbasierte Zugriffssteuerung).

Wenn Sie noch nicht über eine Azure Compute Gallery-Instanz verfügen, müssen Sie eine solche erstellen.

$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'

Konfigurieren der VM Image Builder-Vorlage

In diesem Beispiel haben wir eine Vorlage vorbereitet, die die VM Image Builder-Vorlage mit den zuvor angegebenen Parametern herunterlädt und aktualisiert. Die Vorlage installiert FSLogix, Betriebssystemoptimierungen und Microsoft Teams und führt zum Schluss ein Windows Update aus.

Wenn Sie die Vorlage öffnen, können Sie in der Quelleigenschaft sehen, welches Image verwendet wird. In diesem Beispiel wird ein Windows 10 Multisession-Image verwendet.

Windows 10-Images

Sie sollten sich zwei wichtige Arten von Bildern bewusst sein: Multisession und Einzelsession.

Multisession-Image sind zur Verwendung in einem Pool vorgesehen. Hier ein Beispiel für die Imagedetails in Azure:

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

Einzelsession-Image sind zur individuellen Verwendung vorgesehen. Hier ein Beispiel für die Imagedetails in Azure:

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

Sie können auch ändern, welche Windows 10-Images verfügbar sind:

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

Herunterladen und Konfigurieren der Vorlage

Nun müssen Sie die Vorlage herunterladen und für Ihre spezifische Verwendung konfigurieren.

$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

Sie können sich dazu gerne die Vorlage ansehen. Der gesamte Code kann angezeigt werden.

Übermitteln der Vorlage

Ihre Vorlage muss an den Dienst übermittelt werden. Dadurch werden alle abhängigen Artefakte, z. B. Skripts, heruntergeladen und überprüft, Berechtigungen überprüft und in der Ressourcengruppe „Staging“ gespeichert, die das Präfix IT_ hat.

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

Erstellen des Image

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

Hinweis

Der Befehl wartet nicht auf den VM Image Builder-Dienst, um den Imagebuild abzuschließen, sodass Sie den Status wie hier gezeigt abfragen können.

$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

Erstellen einer VM

Nachdem das Image erstellt wurde, können Sie einen virtuellen Computer (VM) daraus erstellen. Verwenden Sie die Beispiele aus New-AzVM (Az PowerShell module.Compute).

Bereinigen von Ressourcen

Wenn Sie die Ressourcen, die während dieses Prozesses erstellt wurden, nicht mehr benötigen, können Sie sie wie folgt löschen:

Wichtig

Löschen Sie zuerst die Ressourcengruppenvorlage. Wenn Sie nur die Ressourcengruppe löschen, wird die Ressourcengruppe „Staging“ (IT_), die von VM Image Builder verwendet wird, nicht bereinigt.

  1. Entfernen Sie die VM Image Builder-Vorlage.

    Remove-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name vd10ImageTemplate
    
  2. Löschen Sie die Rollenzuweisung.

    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. Löschen Sie die Ressourcengruppe.

    Remove-AzResourceGroup $imageResourceGroup -Force
    

Nächste Schritte

Wenn Sie weitere Beispiele für VM Image Builder ausprobieren möchten, gehen Sie zu GitHub.