你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用 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 Cloud Shell

Azure 托管 Azure Cloud Shell(一个可通过浏览器使用的交互式 shell 环境)。 可以将 Bash 或 PowerShell 与 Cloud Shell 配合使用来使用 Azure 服务。 可以使用 Cloud Shell 预安装的命令来运行本文中的代码,而不必在本地环境中安装任何内容。

若要启动 Azure Cloud Shell,请执行以下操作:

选项 示例/链接
选择代码或命令块右上角的“试用”。 选择“试用”不会自动将代码或命令复制到 Cloud Shell。 Screenshot that shows an example of Try It for Azure Cloud Shell.
转到 https://shell.azure.com 或选择启动 Cloud Shell 按钮可在浏览器中打开 Cloud Shell。 Button to launch Azure Cloud Shell.
选择 Azure 门户右上角菜单栏上的 Cloud Shell 按钮。 Screenshot that shows the Cloud Shell button in the Azure portal

若要使用 Azure Cloud Shell,请执行以下操作:

  1. 启动 Cloud Shell。

  2. 选择代码块(或命令块)上的“复制”按钮以复制代码或命令。

  3. 在 Windows 和 Linux 上选择 Ctrl+Shift+V,或在 macOS 上选择 Cmd+Shift+V 将代码或命令粘贴到 Cloud Shell 会话中。

  4. 选择“Enter”运行代码或命令。

如果有多个 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 = 'WestUS2'

# 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 映像生成器模板参考