共用方式為


建立 Windows 映像並將其發佈到 Azure Compute Gallery

適用於:✔️ Windows VM

在本文中,您會了解如何使用 Azure VM Image Builder 及 Azure PowerShell 在 Azure Compute Gallery (先前稱作共用映像庫) 中建立映像版本,然後以全域方式發佈該映像。 您也可以使用 Azure CLI 來執行此工作。

本文會使用 JSON 範本來設定此映像,您可以在 armTemplateWinSIG.json中找到此範本。 您將下載並編輯該範本的本機版本,因此您也會使用本機的 PowerShell 工作階段。

為了將映像散發到 Azure Compute Gallery,範本會使用 sharedImage 作為範本 distribute 區段的值。

VM Image Builder 會自動執行 Sysprep 來將映像一般化。 此命令是一般 Sysprep 命令,如果您需要的話可以將其 覆寫

請注意您將自訂分層的次數。 您可以對單一 Windows 映像執行有限次數的 Sysprep 命令。 達到 Sysprep 限制之後,您必須重新建立 Windows 映像。 如需詳細資訊,請參閱關於 Sysprep 執行次數的限制

註冊提供者

若要使用 VM Image Builder,您必須註冊提供者。

  1. 檢查您的提供者註冊。 請確定每一個都有傳回 Registered

    Get-AzResourceProvider -ProviderNamespace Microsoft.VirtualMachineImages | Format-table -Property ResourceTypes,RegistrationState
    Get-AzResourceProvider -ProviderNamespace Microsoft.Storage | Format-table -Property ResourceTypes,RegistrationState 
    Get-AzResourceProvider -ProviderNamespace Microsoft.Compute | Format-table -Property ResourceTypes,RegistrationState
    Get-AzResourceProvider -ProviderNamespace Microsoft.KeyVault | Format-table -Property ResourceTypes,RegistrationState
    Get-AzResourceProvider -ProviderNamespace Microsoft.Network | Format-table -Property ResourceTypes,RegistrationState
    Get-AzResourceProvider -ProviderNamespace Microsoft.ContainerInstance | Format-table -Property ResourceTypes,RegistrationState
    
  2. 如果未傳回 Registered,請執行下列命令來註冊提供者:

    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
    
  3. 安裝 PowerShell 模組:

    'Az.ImageBuilder', 'Az.ManagedServiceIdentity' | ForEach-Object {Install-Module -Name $_ -AllowPrerelease}
    

建立變數

因為您會重複使用某些資訊,因此請建立一些變數來儲存這些資訊。

將變數的值 (例如 usernamevmpassword) 取代為您自己的資訊。

# Get existing context
$currentAzContext = Get-AzContext

# Get your current subscription ID. 
$subscriptionID=$currentAzContext.Subscription.Id

# Destination image resource group
$imageResourceGroup="aibwinsig"

# Location
$location="westus"

# Image distribution metadata reference name
$runOutputName="aibCustWinManImg02ro"

# Image template name
$imageTemplateName="helloImageTemplateWin02ps"

# Distribution properties object name (runOutput).
# This gives you the properties of the managed image on completion.
$runOutputName="winclientR01"

# Create a resource group for the VM Image Builder template and Azure Compute Gallery
New-AzResourceGroup `
   -Name $imageResourceGroup `
   -Location $location

建立使用者指派的身分識別,並在資源群組上設定權限

VM Image Builder 會使用所提供的使用者身分識別,將映像插入 Azure Compute Gallery。 在此範例中,您會建立具有發布映像特定動作的 Azure 角色定義。 然後此將角色定義指派給使用者身分識別。

# 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 an Azure PowerShell module to support AzUserAssignedIdentity
Install-Module -Name Az.ManagedServiceIdentity

# Create an identity
New-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName

$identityNameResourceId=$(Get-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName).Id
$identityNamePrincipalId=$(Get-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName).PrincipalId

為身分識別指派權限以散發映像

使用此命令下載 Azure 角色定義範本,然後使用先前指定的參數加以更新。

$aibRoleImageCreationUrl="https://raw.githubusercontent.com/azure/azvmimagebuilder/master/solutions/12_Creating_AIB_Security_Roles/aibRoleImageCreation.json"
$aibRoleImageCreationPath = "aibRoleImageCreation.json"

# Download the configuration
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 和 VM Image Builder,您需要有現有的資源庫和映像定義。 VM Image Builder 不會為您建立資源庫和映像定義。

如果您尚未有可用的映像庫和映像定義,請先建立。

# Gallery name
$sigGalleryName= "myIBSIG"

# Image definition name
$imageDefName ="winSvrimage"

# Additional replication region
$replRegion2="eastus"

# Create the gallery
New-AzGallery `
   -GalleryName $sigGalleryName `
   -ResourceGroupName $imageResourceGroup  `
   -Location $location

# Create the image definition
New-AzGalleryImageDefinition `
   -GalleryName $sigGalleryName `
   -ResourceGroupName $imageResourceGroup `
   -Location $location `
   -Name $imageDefName `
   -OsState generalized `
   -OsType Windows `
   -Publisher 'myCompany' `
   -Offer 'WindowsServer' `
   -Sku 'WinSrv2019'

下載並設定範本

下載 JSON 範本並使用變數來設定。


$templateFilePath = "armTemplateWinSIG.json"

Invoke-WebRequest `
   -Uri "https://raw.githubusercontent.com/azure/azvmimagebuilder/master/quickquickstarts/1_Creating_a_Custom_Win_Shared_Image_Gallery_Image/armTemplateWinSIG.json" `
   -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 '<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 '<region2>',$replRegion2 | Set-Content -Path $templateFilePath
((Get-Content -path $templateFilePath -Raw) -replace '<imgBuilderId>',$identityNameResourceId) | Set-Content -Path $templateFilePath

建立映像版本

您必須將範本提交至服務。 下列命令會下載任何相依成品 (例如指令碼),並將其儲存在暫存資源群組中,該群組的前置詞為 IT_

New-AzResourceGroupDeployment `
   -ResourceGroupName $imageResourceGroup `
   -TemplateFile $templateFilePath `
   -ApiVersion "2022-02-14" `
   -imageTemplateName $imageTemplateName `
   -svclocation $location

若要建置映像,請在範本上叫用「Run」。

Invoke-AzResourceAction `
   -ResourceName $imageTemplateName `
   -ResourceGroupName $imageResourceGroup `
   -ResourceType Microsoft.VirtualMachineImages/imageTemplates `
   -ApiVersion "2022-02-14" `
   -Action Run

建立映像並將其同時複寫到兩個區域,這可能需要一些時間。 請先等到此部分完成,再開始建立 VM。

Get-AzImageBuilderTemplate -ImageTemplateName $imageTemplateName -ResourceGroupName $imageResourceGroup |
  Select-Object -Property Name, LastRunStatusRunState, LastRunStatusMessage, ProvisioningState

建立 VM

根據您使用 VM Image Builder 所建立的映像版本來建立 VM。

  1. 取得您所建立的映像版本:

    $imageVersion = Get-AzGalleryImageVersion `
    -ResourceGroupName $imageResourceGroup `
    -GalleryName $sigGalleryName `
    -GalleryImageDefinitionName $imageDefName
    $imageVersionId = $imageVersion.Id
    
  2. 在映像複寫所在的第二個區域建立 VM:

    $vmResourceGroup = "myResourceGroup"
    $vmName = "myVMfromImage"
    
    # Create user object
    $cred = Get-Credential -Message "Enter a username and password for the virtual machine."
    
    # Create a resource group
    New-AzResourceGroup -Name $vmResourceGroup -Location $replRegion2
    
    # Network pieces
    $subnetConfig = New-AzVirtualNetworkSubnetConfig -Name mySubnet -AddressPrefix 192.168.1.0/24
    $vnet = New-AzVirtualNetwork -ResourceGroupName $vmResourceGroup -Location $replRegion2 `
    -Name MYvNET -AddressPrefix 192.168.0.0/16 -Subnet $subnetConfig
    $pip = New-AzPublicIpAddress -ResourceGroupName $vmResourceGroup -Location $replRegion2 `
    -Name "mypublicdns$(Get-Random)" -AllocationMethod Static -IdleTimeoutInMinutes 4
    $nsgRuleRDP = New-AzNetworkSecurityRuleConfig -Name myNetworkSecurityGroupRuleRDP  -Protocol Tcp `
    -Direction Inbound -Priority 1000 -SourceAddressPrefix * -SourcePortRange * -DestinationAddressPrefix * `
    -DestinationPortRange 3389 -Access Deny
    $nsg = New-AzNetworkSecurityGroup -ResourceGroupName $vmResourceGroup -Location $replRegion2 `
    -Name myNetworkSecurityGroup -SecurityRules $nsgRuleRDP
    $nic = New-AzNetworkInterface -Name myNic -ResourceGroupName $vmResourceGroup -Location $replRegion2 `
    -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -NetworkSecurityGroupId $nsg.Id
    
    # Create a virtual machine configuration using $imageVersion.Id to specify the image
    $vmConfig = New-AzVMConfig -VMName $vmName -VMSize Standard_D1_v2 | `
    Set-AzVMOperatingSystem -Windows -ComputerName $vmName -Credential $cred | `
    Set-AzVMSourceImage -Id $imageVersion.Id | `
    Add-AzVMNetworkInterface -Id $nic.Id
    
    # Create a virtual machine
    New-AzVM -ResourceGroupName $vmResourceGroup -Location $replRegion2 -VM $vmConfig
    

確認自訂

使用您在建立 VM 時所設定的使用者名稱與密碼,建立與該 VM 的遠端桌面連線。 在 VM 中開啟命令提示字元視窗,然後執行下列命令:

dir c:\

您應該會看見名為 buildActions 的目錄,其是在映像自訂期間建立。

清除資源

注意

如果您現在想要嘗試重新自訂映像版本以建立相同映像的新版本,請略過這裡概述的步驟並移至使用 VM Image Builder 建立另一個映像版本

如果不再需要您依照本文程序所建立的資源,您可以刪除這些資源。

下列程序會刪除您建立的映像和其他所有資源檔。 刪除資源之前,請確定您已完成此部署。

請先刪除資源群組範本。 否則就不會清除 VM Image Builder 所使用的暫存資源群組 (IT_)。

  1. 取得映像範本的 ResourceID。

    $resTemplateId = Get-AzResource -ResourceName $imageTemplateName -ResourceGroupName $imageResourceGroup -ResourceType Microsoft.VirtualMachineImages/imageTemplates -ApiVersion "2022-02-14"
    
  2. 刪除映像範本。

    Remove-AzResource -ResourceId $resTemplateId.ResourceId -Force
    
  3. 刪除角色指派。

    Remove-AzRoleAssignment -ObjectId $identityNamePrincipalId -RoleDefinitionName $imageRoleDefName -Scope "/subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup"
    
  4. 移除定義。

    Remove-AzRoleDefinition -Name "$identityNamePrincipalId" -Force -Scope "/subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup"
    
  5. 刪除身分識別。

    Remove-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName -Force
    
  6. 刪除該資源群組。

    Remove-AzResourceGroup $imageResourceGroup -Force
    

下一步

若要更新本文中您所建立的映像版本,請參閱使用 VM Image Builder 建立另一個映像版本