使用 Azure VM 映像生成器的 PowerShell 创建 Windows VM

适用于:✔️ Windows VM

本文演示如何使用 Azure VM 映像生成器 PowerShell 模块创建自定义的 Windows VM 映像。

先决条件

如果没有 Azure 订阅,可在开始前创建一个试用帐户

如果选择在本地使用 PowerShell,则本文要求安装 Az PowerShell 模块,并使用 Connect-AzAccount cmdlet 连接到 Azure 帐户。 有关详细信息,请参阅安装 Azure PowerShell

某些步骤需要 Az.ImageBuilder 模块中的 cmdlet。 使用以下命令单独安装。

Install-Module -Name Az.ImageBuilder

如果有多个 Azure 订阅,请选择应当计费的资源所在的相应订阅。 使用 Set-AzContext cmdlet 选择特定订阅。

Set-AzContext -SubscriptionId 00000000-0000-0000-0000-000000000000

注册提供程序

如果尚未这样做,请注册以下要用于 Azure 订阅的资源提供程序:

  • Microsoft.Compute
  • Microsoft.KeyVault
  • Microsoft.Storage
  • Microsoft.Network
  • Microsoft.VirtualMachineImages
  • Microsoft.ManagedIdentity
  • Microsoft.ContainerInstance
Get-AzResourceProvider -ProviderNamespace Microsoft.Compute, Microsoft.KeyVault, Microsoft.Storage, Microsoft.VirtualMachineImages, Microsoft.Network, Microsoft.ManagedIdentity |
  Where-Object RegistrationState -ne Registered |
    Register-AzResourceProvider

定义变量

因为你将重复使用某些信息,所以要创建一些变量来存储这些信息:

# Destination image resource group name
$imageResourceGroup = 'myWinImgBuilderRG'

# Azure region
$location = 'ChinaNorth3'

# Name of the image to be created
$imageTemplateName = 'myWinImage'

# Distribution properties of the managed image upon completion
$runOutputName = 'myDistResults'

为你的 Azure 订阅 ID 创建变量。 若要确认 subscriptionID 变量是否包含订阅 ID,可以运行下面示例中的第二行:

# Your Azure Subscription ID
$subscriptionID = (Get-AzContext).Subscription.Id
Write-Output $subscriptionID

创建资源组

使用 New-AzResourceGroup cmdlet 创建 Azure 资源组。 资源组是在其中以组的形式部署和管理 Azure 资源的逻辑容器。

下面的示例创建一个资源组,该资源组基于在 $location 变量中指定的区域中 $imageResourceGroup 变量中的名称。 此资源组用于存储映像配置模板项目和映像。

New-AzResourceGroup -Name $imageResourceGroup -Location $location

创建用户身份并设置角色权限

使用以下示例授予 Azure VM 映像生成器在指定资源组中创建映像的权限。 如果没有此权限,则映像生成过程将不会成功完成。

  1. 为角色定义和身份名称创建变量。 这些值必须唯一。

    [int]$timeInt = $(Get-Date -UFormat '%s')
    $imageRoleDefName = "Azure Image Builder Image Def $timeInt"
    $identityName = "myIdentity$timeInt"
    
  2. 创建用户标识。

    New-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName -Location $location
    
  3. 将身份资源和主体 ID 存储在变量中。

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

为标识分配权限以分发映像

  1. 下载 JSON 配置文件,然后根据本文中定义的设置对其进行修改。

    $myRoleImageCreationUrl = 'https://raw.githubusercontent.com/azure/azvmimagebuilder/master/solutions/12_Creating_AIB_Security_Roles/aibRoleImageCreation.json'
    $myRoleImageCreationPath = "myRoleImageCreation.json"
    
    Invoke-WebRequest -Uri $myRoleImageCreationUrl -OutFile $myRoleImageCreationPath -UseBasicParsing
    
    $Content = Get-Content -Path $myRoleImageCreationPath -Raw
    $Content = $Content -replace '<subscriptionID>', $subscriptionID
    $Content = $Content -replace '<rgName>', $imageResourceGroup
    $Content = $Content -replace 'Azure Image Builder Service Image Creation Role', $imageRoleDefName
    $Content | Out-File -FilePath $myRoleImageCreationPath -Force
    
  2. 创建角色定义。

    New-AzRoleDefinition -InputFile $myRoleImageCreationPath
    
  3. 向 Azure VM 映像生成器服务主体授予角色定义。

    $RoleAssignParams = @{
      ObjectId = $identityNamePrincipalId
      RoleDefinitionName = $imageRoleDefName
      Scope = "/subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup"
    }
    New-AzRoleAssignment @RoleAssignParams
    

注意

如果收到此错误:“New-AzRoleDefinition: 已超出角色定义限制。 无法创建更多的角色定义”。请参阅排查 Azure 基于角色的访问控制 (RBAC) 问题

  1. 创建库。

    $myGalleryName = 'myImageGallery'
    $imageDefName = 'winSvrImages'
    
    New-AzGallery -GalleryName $myGalleryName -ResourceGroupName $imageResourceGroup -Location $location
    
  2. 创建库定义。

    $GalleryParams = @{
      GalleryName = $myGalleryName
      ResourceGroupName = $imageResourceGroup
      Location = $location
      Name = $imageDefName
      OsState = 'generalized'
      OsType = 'Windows'
      Publisher = 'myCo'
      Offer = 'Windows'
      Sku = 'Win2019'
    }
    New-AzGalleryImageDefinition @GalleryParams
    

创建映像

  1. 创建 Azure VM 映像生成器源对象。 若要了解有效的参数值,请参阅使用 Azure PowerShell 在 Microsoft Azure 市场中查找 Windows VM 映像

    $SrcObjParams = @{
      PlatformImageSource = $true
      Publisher = 'MicrosoftWindowsServer'
      Offer = 'WindowsServer'
      Sku = '2019-Datacenter'
      Version = 'latest'
    }
    $srcPlatform = New-AzImageBuilderTemplateSourceObject @SrcObjParams
    
  2. 创建 Azure VM 映像生成器分发服务器对象。

    $disObjParams = @{
      SharedImageDistributor = $true
      ArtifactTag = @{tag='dis-share'}
      GalleryImageId = "/subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup/providers/Microsoft.Compute/galleries/$myGalleryName/images/$imageDefName"
      ReplicationRegion = $location
      RunOutputName = $runOutputName
      ExcludeFromLatest = $false
    }
    $disSharedImg = New-AzImageBuilderTemplateDistributorObject @disObjParams
    
  3. 创建 Azure VM 映像生成器自定义对象。

    $ImgCustomParams01 = @{
      PowerShellCustomizer = $true
      Name = 'settingUpMgmtAgtPath'
      RunElevated = $false
      Inline = @("mkdir c:\\buildActions", "mkdir c:\\buildArtifacts", "echo Azure-Image-Builder-Was-Here  > c:\\buildActions\\buildActionsOutput.txt")
    }
    $Customizer01 = New-AzImageBuilderTemplateCustomizerObject @ImgCustomParams01
    
  4. 创建第二个 Azure VM 映像生成器自定义对象。

    $ImgCustomParams02 = @{
      FileCustomizer = $true
      Name = 'downloadBuildArtifacts'
      Destination = 'c:\\buildArtifacts\\index.html'
      SourceUri = 'https://raw.githubusercontent.com/azure/azvmimagebuilder/master/quickquickstarts/exampleArtifacts/buildArtifacts/index.html'
    }
    $Customizer02 = New-AzImageBuilderTemplateCustomizerObject @ImgCustomParams02
    
  5. 创建 Azure VM 映像生成器模板。

    $ImgTemplateParams = @{
      ImageTemplateName = $imageTemplateName
      ResourceGroupName = $imageResourceGroup
      Source = $srcPlatform
      Distribute = $disSharedImg
      Customize = $Customizer01, $Customizer02
      Location = $location
      UserAssignedIdentityId = $identityNameResourceId
    }
    New-AzImageBuilderTemplate @ImgTemplateParams
    

创建模板后,将返回一条消息,并在 $imageResourceGroup 中创建 Azure VM 映像生成器配置模板。

若要确定模板创建过程是否成功,可以使用以下示例:

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

在后台,Azure VM 映像生成器还会在你的订阅中创建一个暂存资源组。 此资源组用于映像生成过程。 其格式为:IT_<DestinationResourceGroup>_<TemplateName>

警告

请勿直接删除暂存资源组。 若要删除暂存资源组,请删除映像模板项目。

如果在提交映像配置模板时服务报告失败,请执行以下操作:

  • 请参阅排查 Azure VM 映像生成器故障

  • 在重试提交模板之前,请通过以下示例将其删除:

    Remove-AzImageBuilderTemplate -ImageTemplateName $imageTemplateName -ResourceGroupName $imageResourceGroup
    

启动映像生成

运行以下命令,将映像配置提交到 Azure VM 映像生成器服务:

Start-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name $imageTemplateName

等待映像生成过程完成,可能需要长达一小时。

如果遇到错误,请查看排查 Azure VM 映像生成器故障

创建 VM

  1. 将 VM 的登录凭据存储在一个变量中。 密码必须是复杂密码。

    $Cred = Get-Credential
    
  2. 使用创建的映像创建 VM。

    $ArtifactId = (Get-AzImageBuilderTemplateRunOutput -ImageTemplateName $imageTemplateName -ResourceGroupName $imageResourceGroup).ArtifactId
    
    New-AzVM -ResourceGroupName $imageResourceGroup -Image $ArtifactId -Name myWinVM01 -Credential $Cred
    

验证自定义项

  1. 使用创建 VM 时设置的用户名和密码创建与 VM 的远程桌面连接。

  2. 在 VM 中,打开 PowerShell 并运行 Get-Content,如以下示例所示:

    Get-Content -Path C:\buildActions\buildActionsOutput.txt
    

    输出基于映像自定义过程中创建的文件内容。

    Azure-Image-Builder-Was-Here
    
  3. 在同一 PowerShell 会话中,验证第二个自定义项是否已成功完成,方法是检查是否存在文件 c:\buildArtifacts\index.html,如以下示例所示:

    Get-ChildItem c:\buildArtifacts\
    

    结果应为目录列表,其中该文件是在映像自定义过程中下载的。

        Directory: C:\buildArtifacts
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    -a---          29/01/2021    10:04            276 index.html
    

清理资源

如果不再需要在此过程中创建的资源,可以通过以下操作将其删除:

  1. 删除 Azure VM 映像生成器模板。

    Remove-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name $imageTemplateName
    
  2. 删除映像资源组。

    注意

    以下示例删除指定的资源组及其包含的所有资源。 如果资源组中存在本文范围外的资源,这些资源也会被删除。

    Remove-AzResourceGroup -Name $imageResourceGroup
    

后续步骤

若要详细了解本文中使用的 JSON 文件的组件,请参阅 Azure VM 映像生成器模板参考