Criar uma imagem da Área de Trabalho Virtual do Azure usando o Construtor de Imagens de VM e o PowerShell

Aplica-se a: ✔️ VMs do Windows

Neste artigo, você aprenderá a criar uma imagem da Área de Trabalho Virtual do Azure com estas personalizações:

O artigo discute como automatizar as personalizações usando o Azure VM Image Builder. Em seguida, você pode distribuir a imagem para uma Galeria de Computação do Azure (anteriormente Galeria de Imagens Compartilhadas), onde pode replicá-la para outras regiões, controlar a escala e compartilhar a imagem dentro e fora da sua organização.

Para simplificar a implantação de uma configuração do Construtor de Imagens de VM, nosso exemplo usa um modelo do Azure Resource Manager com o modelo do Construtor de Imagens de VM aninhado nele. Essa abordagem oferece mais alguns benefícios, como variáveis e entradas de parâmetros. Você também pode passar parâmetros da linha de comando.

Este artigo pretende ser um exercício de copiar e colar.

Nota

Você encontrará os scripts para instalar os aplicativos no GitHub. Eles são apenas para fins de ilustração e teste. Não os use para cargas de trabalho de produção.

Dicas para criar imagens do Windows

  • Tamanho da VM: para Windows, use Standard_D2_v2 ou superior. O tamanho padrão é Standard_D1_v2, que não é adequado para Windows.

  • Este artigo usa scripts de personalizador do PowerShell. Use as seguintes configurações ou a compilação deixará de responder:

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

    Por exemplo:

      {
          "type": "PowerShell",
          "name": "installFSLogix",
          "runElevated": true,
          "runAsSystem": true,
          "scriptUri": "https://raw.githubusercontent.com/azure/azvmimagebuilder/main/solutions/14_Building_Images_WVD/0_installConfFsLogix.ps1"
    
  • Comente seu código: O log de construção do VM Image Builder, customization.log, é detalhado. Se você comentar seus scripts usando 'write-host', eles serão enviados para os logs, o que deve facilitar a solução de problemas.

     write-host 'AIB Customization: Starting OS Optimizations script'
    
  • Códigos de saída: o VM Image Builder espera que todos os scripts retornem um 0 código de saída. Se você usar um código de saída diferente de zero, o VM Image Builder falhará na personalização e interromperá a compilação. Se você tiver scripts complexos, adicione instrumentação e emita códigos de saída, que serão mostrados no arquivo customization.log .

     Write-Host "Exit code: " $LASTEXITCODE
    
  • Teste: teste e teste novamente seu código em uma VM autônoma. Certifique-se de que não há solicitações do usuário, que você está usando os privilégios corretos e assim por diante.

  • Rede: é definido no script de otimização, Set-NetAdapterAdvancedProperty mas falha na compilação do VM Image Builder. Porque ele desconecta a rede, é comentado. Estamos investigando esse problema.

Pré-requisitos

Você deve ter os cmdlets mais recentes do Azure PowerShell instalados. Para obter mais informações, consulte Visão geral do 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

Configurar o ambiente e as variáveis

# 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

Permissões, identidade do usuário e função

  1. Crie uma identidade de usuário.

    # 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. Atribua permissões à identidade para distribuir imagens. Os comandos a seguir baixam e atualizam o modelo com os 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

Se você receber o erro "New-AzRoleDefinition: limite de definição de função excedido. Não é possível criar mais definições de função", consulte Solucionar problemas do RBAC do Azure (controle de acesso baseado em função).

Se você ainda não tiver uma Galeria de Computação do Azure, precisará criar uma.

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

Configurar o modelo do Construtor de Imagens de VM

Para este exemplo, preparamos um modelo que baixa e atualiza o modelo do Construtor de Imagens de VM com os parâmetros especificados anteriormente. O modelo instala o FSLogix, otimizações do sistema operacional e o Microsoft Teams, e executa o Windows Update no final.

Se você abrir o modelo, poderá ver na propriedade source a imagem que está sendo usada. Neste exemplo, ele usa uma imagem de várias sessões do Windows 10.

Imagens do Windows 10

Você deve estar ciente de dois tipos principais de imagens: multi-sessão e sessão única.

As imagens de várias sessões destinam-se ao uso em pool. Aqui está um exemplo dos detalhes da imagem no Azure:

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

As imagens de sessão única destinam-se a uso individual. Aqui está um exemplo dos detalhes da imagem no Azure:

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

Você também pode alterar quais imagens do Windows 10 estão disponíveis:

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

Baixar e configurar o modelo

Agora, baixe o modelo e configure-o para seu próprio 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

Sinta-se à vontade para visualizar o modelo. Todo o código é visível.

Enviar o modelo

O seu modelo deve ser enviado para o serviço. Isso baixa todos os artefatos dependentes, como scripts, e valida, verifica permissões e os armazena no grupo de recursos de preparação, que é prefixado com 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

Criar a imagem

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

Nota

O comando não espera que o serviço VM Image Builder conclua a compilação da imagem, para que você possa consultar o status conforme mostrado aqui.

$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

Criar uma VM

Agora que a imagem foi criada, você pode criar uma VM a partir dela. Use os exemplos de New-AzVM (módulo Az PowerShell. Computação).

Limpar os recursos

Se você não precisar mais dos recursos que foram criados durante esse processo, poderá excluí-los fazendo o seguinte:

Importante

Exclua primeiro o modelo de grupo de recursos. Se você excluir apenas o grupo de recursos, o grupo de recursos de preparo (IT_) usado pelo Construtor de Imagens de VM não será limpo.

  1. Remova o modelo do Construtor de Imagens da VM.

    Remove-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name vd10ImageTemplate
    
  2. Exclua a atribuição de função.

    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. Exclua o grupo de recursos.

    Remove-AzResourceGroup $imageResourceGroup -Force
    

Próximos passos

Para tentar mais exemplos do Construtor de Imagens de VM, vá para o GitHub.