Share via


Créer une image Azure Virtual Desktop en utilisant VM Image Builder et PowerShell

S’applique à : ✔️ Machine virtuelles Windows

Dans cet article, vous allez apprendre à créer une image Azure Virtual Desktop avec ces personnalisations :

L’article explique comment automatiser les personnalisations en utilisant Azure VM Image Builder. Vous pouvez ensuite distribuer l’image à une galerie Azure Compute Gallery (anciennement Shared Image Gallery), où vous pouvez la répliquer dans d’autres régions, contrôler l’échelle et partager l’image au sein et au-delà de votre organisation.

Pour simplifier le déploiement d’une configuration VM Image Builder, notre exemple utilise un modèle Azure Resource Manager dans lequel le modèle VM Image Builder est imbriqué. Cette approche offre quelques avantages supplémentaires, tels que des variables et des entrées de paramètres. Vous pouvez également transmettre des paramètres à partir de la ligne de commande.

Cet article est conçu comme un exercice de copier-coller.

Notes

Vous trouverez les scripts pour installer les applications sur GitHub. Ils sont uniquement fournis à des fins d’illustration et de test. Ne les utilisez pas pour les charges de travail de production.

Conseils pour la création d’images Windows

  • Taille de machine virtuelle : pour Windows, utilisez Standard_D2_v2 ou une taille plus grande. La taille par défaut, Standard_D1_v2, n’est pas adaptée à Windows.

  • Cet article utilise les scripts du personnalisateur PowerShell. Utilisez les paramètres suivants ; sinon la build ne répondra plus :

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

    Par exemple :

      {
          "type": "PowerShell",
          "name": "installFSLogix",
          "runElevated": true,
          "runAsSystem": true,
          "scriptUri": "https://raw.githubusercontent.com/azure/azvmimagebuilder/main/solutions/14_Building_Images_WVD/0_installConfFsLogix.ps1"
    
  • Commentez votre code : le journal de génération de VM Image Builder, customization.log, est détaillé. Si vous commentez vos scripts en utilisant 'write-host', ils seront envoyés aux journaux, ce qui devrait faciliter la résolution des problèmes.

     write-host 'AIB Customization: Starting OS Optimizations script'
    
  • Codes de sortie : VM Image Builder s’attend à ce que tous les scripts retournent un code de sortie 0. Si vous utilisez un code de sortie différent de zéro, VM Image Builder ne parvient pas à effectuer la personnalisation et arrête la build. Si vous avez des scripts complexes, ajoutez une instrumentation et émettez des codes de sortie, qui s’afficheront dans le fichier customization.log.

     Write-Host "Exit code: " $LASTEXITCODE
    
  • Test : testez et retestez votre code sur une machine virtuelle autonome. Vérifiez qu’il n’y a pas d’invites utilisateur, que vous utilisez les privilèges appropriés, etc.

  • Réseau : Set-NetAdapterAdvancedProperty est défini dans le script d’optimisation, mais la build VM Image Builder échoue. Dans la mesure où le réseau est déconnecté, des commentaires sont fournis. Investiguons ce problème.

Prérequis

Les dernières applets de commande Azure PowerShell doivent être installées. Pour plus d’informations, voir Présentation d’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

Configurer l’environnement et les variables

# 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

Autorisations, identité de l’utilisateur et rôle

  1. Créez une identité d’utilisateur.

    # 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. Attribuez des autorisations à l’identité pour distribuer des images. Les commandes suivantes téléchargent et mettent à jour le modèle avec les paramètres précédemment spécifiés.

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

Notes

Si vous recevez l’erreur « New-AzRoleDefinition : Limite de définition de rôle dépassée. Aucune autre définition de rôle ne peut être créée. », consultez Résoudre les problèmes liés au contrôle d’accès en fonction du rôle (RBAC) Azure.

Si vous n’avez pas encore de galerie Azure Compute Gallery, vous devez en créer une.

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

Configurer le modèle VM Image Builder

Pour cet exemple, nous avons préparé un modèle qui télécharge et met à jour le modèle VM Image Builder avec les paramètres spécifiés précédemment. Le modèle installe FSLogix, les optimisations du système d’exploitation et Microsoft Teams, puis exécute Windows Update à la fin.

Si vous ouvrez le modèle, vous pouvez voir dans la propriété source l’image qui est utilisée. Dans cet exemple, une image multisession Windows 10 est utilisée.

Images Windows 10

Vous devez avoir connaissance des deux types d’images clés : multisession et monosession.

Les images multisessions sont destinées à une utilisation en pool. Voici un exemple des détails de l’image dans Azure :

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

Les images monosessions sont destinées à une utilisation individuelle. Voici un exemple des détails de l’image dans Azure :

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

Vous pouvez également modifier les images Windows 10 disponibles :

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

Télécharger et configurer le modèle

Maintenant, téléchargez le modèle et configurez-le pour votre propre utilisation.

$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

N’hésitez pas à consulter le modèle. Tout le code est visible.

Envoyer le modèle

Votre modèle doit être envoyé au service. Cette opération télécharge tous les artefacts dépendants, comme les scripts, puis les valide, vérifie leurs autorisations et les stocke dans le groupe de ressources intermédiaire avec le préfixe 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

Créer l’image

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

Notes

La commande n’attend pas que le service VM Image Builder termine la génération de l’image. Vous pouvez donc interroger l’état comme indiqué ici.

$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

Créer une machine virtuelle

L’image étant désormais générée, vous pouvez créer une machine virtuelle à partir de celle-ci. Utilisez les exemples de New-AzVM (Az PowerShell module.Compute).

Nettoyer vos ressources

Si vous n’avez plus besoin des ressources qui ont été créées durant ce processus, vous pouvez les supprimer en effectuant les étapes suivantes :

Important

Supprimez d’abord le modèle de groupe de ressources. Si vous supprimez uniquement le groupe de ressources, le groupe de ressources intermédiaire (IT_) utilisé par VM Image Builder ne sera pas nettoyé.

  1. Supprimez le modèle VM Image Builder.

    Remove-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name vd10ImageTemplate
    
  2. Supprimez l’attribution de rôle.

    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. Supprimez le groupe de ressources.

    Remove-AzResourceGroup $imageResourceGroup -Force
    

Étapes suivantes

Pour essayer d’autres exemples de VM Image Builder, accédez à GitHub.