Compartir a través de


Creación de una imagen de Azure Virtual Desktop mediante VM Image Builder y PowerShell

Se aplica a: ✔️ Máquinas virtuales Windows

En este artículo, aprenderá a crear una imagen de Azure Virtual Desktop con estas personalizaciones:

En el artículo se describe cómo automatizar las personalizaciones mediante Azure VM Image Builder. Después, puede distribuir la imagen a una instancia de Azure Compute Gallery (anteriormente Shared Image Gallery), donde puede replicarla en otras regiones, controlar el escalado y compartir la imagen dentro y fuera de la organización.

Para simplificar la implementación de una configuración de VM Image Builder, en este ejemplo se usa una plantilla de Azure Resource Manager con la plantilla de VM Image Builder anidada dentro. Este enfoque proporciona algunas ventajas más, como variables y entradas de parámetros. También puede pasar parámetros desde la línea de comandos.

Este artículo pretende ser un ejercicio de copiar y pegar.

Nota

Encontrará los scripts para instalar las aplicaciones en GitHub. Son solo con fines ilustrativos y de prueba. No los utilice para cargas de trabajo de producción.

Sugerencias para compilar imágenes de Windows

  • Tamaño de máquina virtual: para Windows, use Standard_D2_v2 o superior. El tamaño predeterminado es Standard_D1_v2, que no es adecuado para Windows.

  • En este artículo se usan los scripts del personalizador de PowerShell. Use la siguiente configuración o la compilación dejará de responder:

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

    Por ejemplo:

      {
          "type": "PowerShell",
          "name": "installFSLogix",
          "runElevated": true,
          "runAsSystem": true,
          "scriptUri": "https://raw.githubusercontent.com/azure/azvmimagebuilder/main/solutions/14_Building_Images_WVD/0_installConfFsLogix.ps1"
    
  • Comenta el código: el registro de compilación de VM Image Builder, customization.log, es detallado. Si comenta los scripts mediante "write-host", se enviarán a los registros, lo cual debería facilitar la solución de problemas.

     write-host 'AIB Customization: Starting OS Optimizations script'
    
  • Códigos de salida: VM Image Builder espera que todos los scripts devuelvan un código de salida 0. Si usa un código de salida distinto de cero, en VM Image Builder se producirá un error en la personalización y se detendrá la compilación. Si tiene scripts complejos, agregue instrumentación y emita códigos de salida, que se mostrarán en el archivo customization.log.

     Write-Host "Exit code: " $LASTEXITCODE
    
  • Prueba: pruebe varias veces el código en una máquina virtual independiente. Asegúrese de que no haya ninguna solicitud de usuario, que esté usando los privilegios correctos, etc.

  • Redes: Set-NetAdapterAdvancedProperty se establece en el script de optimización, pero se produce un error en la compilación de Vm Image Builder. Dado que desconecta la red, está marcado con un comentario. Estamos investigando este problema.

Requisitos previos

Debe tener instalados los cmdlets de Azure PowerShell más recientes. Para obtener más información, consulte la Overview of Azure PowerShell (Introducción a 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

Configuración del entorno y las 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

Permisos, identidad de usuario y rol

  1. Cree una identidad de usuario.

    # 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. Asigne permisos a la identidad para distribuir imágenes. Los siguientes comandos descargan y actualizan la plantilla con los parámetros especificados anteriormente.

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

Nota

Si recibe el error: "New-AzRoleDefinition: se ha superado el límite de definición de roles. No se pueden crear más definiciones de roles", consulte Solución de problemas de RBAC (control de acceso basado en rol) de Azure.

Si aún no tiene una instancia de Azure Compute Gallery, debe crearla.

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

Configuración de la plantilla de VM Image Builder

En este ejemplo, hemos preparado una plantilla que descarga y actualiza la plantilla de VM Image Builder con los parámetros especificados anteriormente. La plantilla instala FSLogix, las optimizaciones del sistema operativo y Microsoft Teams, y ejecuta Windows Update al final.

Si abre la plantilla, puede ver en la propiedad Source la imagen que se está utilizando. En este ejemplo, se usa una imagen de varias sesiones de Windows 10.

Imágenes de Windows 10

Debe tener en cuenta dos tipos clave de imágenes: de sesión múltiple y sesión única.

Las imágenes de sesión múltiple están pensadas para el uso agrupado. Este es un ejemplo de los detalles de imagen en Azure:

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

Las imágenes de sesión única están pensadas para su uso individual. Este es un ejemplo de los detalles de imagen en Azure:

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

También puede cambiar qué imágenes de Windows 10 están disponibles:

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

Descarga y configuración de la plantilla

Ahora, descargue la plantilla y configúrela para su propio uso.

$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

Vea la plantilla con total libertad. Todo el código es visible.

Envío de la plantilla

La plantilla se debe enviar al servicio. Al hacerlo, descarga los artefactos dependientes, como los scripts, y valida y comprueba los permisos y los almacena en el grupo de recursos de almacenamiento provisional, que incluye el prefijo 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

Compilación de la imagen

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

Nota

El comando no espera a que el servicio VM Image Builder complete la compilación de la imagen, por lo que puede consultar el estado como se indica aquí.

$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

Crear una VM

Ahora que la imagen está creada, puede compilar una máquina virtual a partir de ella. Use los ejemplos de New-AzVM (Az PowerShell module.Compute).

Limpieza de los recursos

Si ya no necesita los recursos que se crearon durante este proceso, puede eliminarlos haciendo lo siguiente:

Importante

Elimine primero la plantilla del grupo de recursos. Si elimina solo el grupo de recursos, el grupo de recursos de almacenamiento provisional (IT_) que usa VM Image Builder no se limpiará.

  1. Elimine la plantilla de VM Image Builder.

    Remove-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name vd10ImageTemplate
    
  2. Elimine la asignación de roles.

    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. Elimine el grupo de recursos.

    Remove-AzResourceGroup $imageResourceGroup -Force
    

Pasos siguientes

Para probar más ejemplos de VM Image Builder, vaya a GitHub.