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

Abgeschlossen

In dieser Lerneinheit wird erläutert, wie Sie die Anpassungen mithilfe von 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.

Diese Lerneinheit ist als Übersicht über den Prozess oder eine Übung zum Kopieren und Einfügen konzipiert.

Überlegungen zum Erstellen von Windows-Images

  • VM-Größe: Verwenden Sie für Windows Standard_D2_v2 oder höher. Die Standardgröße ist Standard_D1_v2. Sie ist nicht für Windows geeignet.

  • 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 Exitcode von Null 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"
    

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

Sie haben eine Vorlage vorbereitet, die die VM Image Builder-Vorlage mit den Parametern herunterlädt und aktualisiert, die zuvor angegeben wurden. 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.

Ü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).