分享方式:


使用 VM Image Builder 和 PowerShell,建立 Azure 虛擬桌面映像

適用於:✔️ Windows VM

在本文中,您將了解如何使用下列自訂建立 Azure 虛擬桌面映像:

本文會討論如何使用 Azure VM Image Builder 將自訂自動化。 然後,您可以將映像發佈至 Azure Compute Gallery (先前為共用映像庫),在此處可將映像複製到其他區域、控制規模並在組織內外共用映像。

為了簡化 VM Image Builder 設定的部署,我們的範例會使用 Azure Resource Manager 範本,其中有巢狀 VM Image Builder 範本。 此方法能提供更多優點,例如變數和參數輸入。 您也可以從命令列傳遞參數。

本文旨在作為複製和貼上練習。

注意

您會發現在 GitHub 上安裝應用程式的指令碼。 這些指令碼僅供說明及測試用途。 請勿將這些指令碼用於生產工作負載。

組建 Windows 映像的秘訣

  • VM 大小:針對 Windows,請使用 Standard_D2_v2 或更新版本。 預設大小為 Standard_D1_v2,不適用於 Windows。

  • 本文使用 PowerShell 自訂工具指令碼。 請使用下列設定,否則組建將會停止回應:

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

    例如:

      {
          "type": "PowerShell",
          "name": "installFSLogix",
          "runElevated": true,
          "runAsSystem": true,
          "scriptUri": "https://raw.githubusercontent.com/azure/azvmimagebuilder/main/solutions/14_Building_Images_WVD/0_installConfFsLogix.ps1"
    
  • 為您的程式碼註解:VM Image Builder 組建記錄檔 customization.log 為詳細資訊。 如果您使用 'write-host' 為指令碼註解,這些指令碼將會傳送至記錄檔,此舉會使疑難排解作業更加輕鬆。

     write-host 'AIB Customization: Starting OS Optimizations script'
    
  • 結束代碼:VM Image Builder 預期所有指令碼都會傳回 0 結束代碼。 如果您使用非零結束代碼,VM Image Builder 會無法自訂並停止組建。 如果您有複雜指令碼,請新增檢測設備並發出結束代碼,其會顯示在 customization.log 檔案中。

     Write-Host "Exit code: " $LASTEXITCODE
    
  • 測試:在獨立 VM 上測試及重新測試程式碼。 請確認並無使用者提示,您使用的是正確的權限等等。

  • 網路:Set-NetAdapterAdvancedProperty 於最佳化指令碼中設定,但在 VM Image Builder 組建失敗。 由於中斷網路連線,其已註解化。我們正在調查此問題。

必要條件

您必須安裝最新的 Azure PowerShell Cmdlet。 如需詳細資訊,請參閱 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

設定環境及變數

# 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

權限、使用者身分識別和角色

  1. 建立使用者身分識別。

    # 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. 向身分識別指派權限以散發映像。 下列命令會下載範本,並使用先前指定的參數進行更新。

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

注意

如果您收到錯誤「New-AzRoleDefinition:已超出角色定義限制。 無法建立更多角色定義」,請參閱針對 Azure RBAC (角色型存取控制) 進行疑難排解

若您並無 Azure Compute Gallery,則須建立一個。

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

設定 VM Image Builder 範本

在此範例中,我們已準備範本,此範本使用先前指定的參數下載和更新 VM Image Builder 範本。 此範本會安裝 FSLogix、作業系統最佳化和 Microsoft Teams,並在結束時執行 Windows Update。

如果您開啟範本,就能在來源屬性中看到正在使用的映像。 在此範例中,會使用 Windows 10 多工作階段映像。

Windows 10 映像

您應該注意兩種主要映像類型:多工作階段和單一工作階段。

多工作階段映像適用於集區式使用方式。 以下為 Azure 中映像詳細資料的範例:

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

單一工作階段映像適用於個別使用方式。 以下為 Azure 中映像詳細資料的範例:

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

您也可以變更可用的 Windows 10 映像:

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

下載並設定範本

現在,請下載範本,並按您自身用途進行設定。

$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

您可以隨意檢視範本。 所有程式碼均可供檢視。

提交範本

您必須將範本提交至服務。 這麼做會下載任何相依成品 (例如指令碼),以及驗證、檢查權限,並將其儲存在開頭為 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

建置映像

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

注意

命令不會等候 VM Image Builder 服務完成映像組建,因此您可以查詢此處所顯示的狀態。

$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

建立 VM

現在已組建映像,您可以從中組建 VM。 使用 New-AzVM (Az PowerShell module.Compute) 中的範例。

清除資源

如果您不再需要在此流程中建立的資源,您可執行下列動作予以刪除:

重要

請先刪除資源群組範本。 如果您只刪除資源群組,則不會清除 VM Image Builder 所使用的暫存資源群組 (IT_)。

  1. 移除 VM Image Builder 範本。

    Remove-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name vd10ImageTemplate
    
  2. 刪除角色指派。

    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. 刪除該資源群組。

    Remove-AzResourceGroup $imageResourceGroup -Force
    

下一步

若要嘗試更多 VM Image Builder 範例,請移至 GitHub