PowerShell から Azure Image Builder を使用して Windows VM を作成する

この記事では、Azure VM Image Builder PowerShell モジュールを使用して、カスタマイズした Windows イメージを作成する方法について説明します。

前提条件

Azure サブスクリプションをお持ちでない場合は、開始する前に無料アカウントを作成してください。

ローカルで PowerShell を使用する場合は、Az PowerShell モジュールをインストールしたうえで、Connect-AzAccount コマンドレットを使用して自分の Azure アカウントに接続する必要があります。 Az PowerShell モジュールのインストールの詳細については、「Azure PowerShell のインストール」を参照してください。

Azure Cloud Shell を使用する

Azure では、ブラウザーを介して使用できる対話型のシェル環境、Azure Cloud Shell がホストされています。 Cloud Shell で Bash または PowerShell を使用して、Azure サービスを操作できます。 ローカル環境に何もインストールしなくても、Cloud Shell にプレインストールされているコマンドを使用して、この記事のコードを実行できます。

Azure Cloud Shell を開始するには:

オプション 例とリンク
コード ブロックの右上隅にある [使ってみる] を選択します。 [使ってみる] を選択しても、コードは Cloud Shell に自動的にコピーされません。 Azure Cloud Shell の [使ってみる] の例
https://shell.azure.com に移動するか、 [Cloud Shell を起動する] ボタンを選択して、ブラウザーで Cloud Shell を開きます。 新しいウィンドウで Cloud Shell を起動する
Azure portal の右上にあるメニュー バーの [Cloud Shell] ボタンを選択します。 Azure Portal の [Cloud Shell] ボタン

Azure Cloud Shell でこの記事のコードを実行するには:

  1. Cloud Shell を開始します。

  2. [コピー] ボタンを選択して、コード ブロックをコードにコピーします。

  3. Windows と Linux では Ctrl+Shift+V キーを選択し、macOS では Cmd+Shift+V キーを選択して、コードを Cloud Shell セッションに貼り付けます。

  4. Enter キーを選択して、コードを実行します。

複数の Azure サブスクリプションをお持ちの場合は、リソースが課金の対象となる適切なサブスクリプションを選択してください。 Set-AzContext コマンドレットを使用して、特定のサブスクリプションを選択します。

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

機能の登録

Azure サブスクリプションで使用する次のリソースプロバイダーを登録します (まだ登録していない場合)。

  • Microsoft.Compute
  • Microsoft.KeyVault
  • Microsoft.Storage
  • Microsoft.Network
  • Microsoft.VirtualMachineImages
Get-AzResourceProvider -ProviderNamespace Microsoft.Compute, Microsoft.KeyVault, Microsoft.Storage, Microsoft.VirtualMachineImages, Microsoft.Network |
  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 が格納されていることを確認するには、次の例の 2 行目を実行します。

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

リソース グループを作成する

New-AzResourceGroup コマンドレットを使用して、Azure リソース グループを作成します。 リソース グループとは、複数の Azure リソースをまとめてデプロイ、管理する際の論理コンテナーです。

次の例では、$location 変数に指定されたリージョンに、$imageResourceGroup 変数内の名前に基づいてリソース グループを作成します。 このリソース グループは、イメージ構成テンプレート成果物およびイメージを格納するために使用されます。

New-AzResourceGroup -Name $imageResourceGroup -Location $location

ユーザー ID を作成してロールのアクセス許可を設定する

以下の例を使用して、指定したリソース グループにイメージを作成するためのアクセス許可を Azure Image Builder に付与します。 このアクセス許可がないと、イメージのビルド プロセスが正常完了しません。

ロールの定義と ID の名前に使用する変数を作成します。 これらの値は一意である必要があります。

[int]$timeInt = $(Get-Date -UFormat '%s')
$imageRoleDefName = "Azure Image Builder Image Def $timeInt"
$identityName = "myIdentity$timeInt"

ユーザー ID を作成します。

New-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName

ID リソースとプリンシパル ID を変数に格納します。

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

イメージを配布するためにアクセス許可を ID に割り当てる

.json 構成ファイルをダウンロードし、この記事で定義した設定に基づいてファイルに変更を加えます。

$myRoleImageCreationUrl = 'https://raw.githubusercontent.com/azure/azvmimagebuilder/master/solutions/12_Creating_AIB_Security_Roles/aibRoleImageCreation.json'
$myRoleImageCreationPath = "$env:TEMP\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

ロール定義を作成します。

New-AzRoleDefinition -InputFile $myRoleImageCreationPath

Image Builder のサービス プリンシパルにロールの定義を付与します。

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

注意

エラー "New-AzRoleDefinition: ロールの定義の制限を超えました。ロールの定義をこれ以上作成することはできません" が表示された場合は、「Azure RBAC のトラブルシューティング」を参照してください。

ギャラリーを作成します。

$myGalleryName = 'myImageGallery'
$imageDefName = 'winSvrImages'

New-AzGallery -GalleryName $myGalleryName -ResourceGroupName $imageResourceGroup -Location $location

ギャラリーの定義を作成します。

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

イメージを作成する

Azure Image Builder のソース オブジェクトを作成します。 有効なパラメーター値については、Azure PowerShell を使用して Azure Marketplace で Windows VM イメージを検索する方法に関するページを参照してください。

$SrcObjParams = @{
  SourceTypePlatformImage = $true
  Publisher = 'MicrosoftWindowsServer'
  Offer = 'WindowsServer'
  Sku = '2019-Datacenter'
  Version = 'latest'
}
$srcPlatform = New-AzImageBuilderSourceObject @SrcObjParams

Azure Image Builder のディストリビューター オブジェクトを作成します。

$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-AzImageBuilderDistributorObject @disObjParams

Azure Image Builder のカスタマイズ オブジェクトを作成します。

$ImgCustomParams01 = @{
  PowerShellCustomizer = $true
  CustomizerName = 'settingUpMgmtAgtPath'
  RunElevated = $false
  Inline = @("mkdir c:\\buildActions", "mkdir c:\\buildArtifacts", "echo Azure-Image-Builder-Was-Here  > c:\\buildActions\\buildActionsOutput.txt")
}
$Customizer01 = New-AzImageBuilderCustomizerObject @ImgCustomParams01

2 番目の Azure Image Builder のカスタマイズ オブジェクトを作成します。

$ImgCustomParams02 = @{
  FileCustomizer = $true
  CustomizerName = 'downloadBuildArtifacts'
  Destination = 'c:\\buildArtifacts\\index.html'
  SourceUri = 'https://raw.githubusercontent.com/azure/azvmimagebuilder/master/quickquickstarts/exampleArtifacts/buildArtifacts/index.html'
}
$Customizer02 = New-AzImageBuilderCustomizerObject @ImgCustomParams02

Azure Image Builder テンプレートを作成します。

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

完了するとメッセージが返され、Image Builder 構成テンプレートが $imageResourceGroup に作成されます。

テンプレートの作成プロセスが成功したかどうかは、次の例を使用して調べることができます。

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

また、バックグラウンドで、ステージング リソース グループがサブスクリプションに作成されます。 このリソース グループがイメージのビルドに使用されます。 これは、IT_<DestinationResourceGroup>_<TemplateName> という形式になっています。

警告

ステージング リソース グループは直接削除しないでください。 イメージ テンプレート成果物を削除します。そうすることで、ステージング リソース グループが削除されます。

イメージ構成テンプレートの送信中にサービスによって障害が報告された場合、次を実行します。

Remove-AzImageBuilderTemplate -ImageTemplateName $imageTemplateName -ResourceGroupName $imageResourceGroup

イメージのビルドを開始する

VM Image Builder サービスにイメージ構成を送信します。

Start-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name $imageTemplateName

イメージ ビルド プロセスが完了するまで待ちます。 このステップには最大 1 時間かかることがあります。

エラーが発生した場合は、「Azure VM Image Builder (AIB) 障害のトラブルシューティング」を参照してください。

VM の作成

VM のログイン資格情報を変数に格納します。 パスワードは複雑なものにする必要があります。

$Cred = Get-Credential

作成したイメージを使用して VM を作成します。

$ArtifactId = (Get-AzImageBuilderRunOutput -ImageTemplateName $imageTemplateName -ResourceGroupName $imageResourceGroup).ArtifactId

New-AzVM -ResourceGroupName $imageResourceGroup -Image $ArtifactId -Name myWinVM01 -Credential $Cred

カスタマイズを確認する

VM を作成したときに設定したユーザー名とパスワードを使用して、VM へのリモート デスクトップ接続を作成します。 VM 内で PowerShell を開き、次の例のように Get-Content を実行します。

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

イメージ カスタマイズ プロセス中に作成されたファイルの内容に基づいて出力が表示されます。

Azure-Image-Builder-Was-Here

同じ PowerShell セッションから、次の例に示すように、ファイル c:\buildArtifacts\index.html が存在するか調べて、2 番目のカスタマイズが正常に完了したことを確認します。

Get-ChildItem c:\buildArtifacts\

結果は、イメージのカスタマイズ プロセス中にダウンロードされたファイルを示すディレクトリの一覧になります。

    Directory: C:\buildArtifacts

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

リソースをクリーンアップする

この記事で作成したリソースが不要であれば、次の例を実行して削除できます。

Image Builder テンプレートを削除する

Remove-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name $imageTemplateName

イメージ リソース グループを削除する

注意事項

次の例では、指定されたリソース グループとそれに含まれるすべてのリソースを削除します。 指定したリソース グループにこの記事の範囲外のリソースが含まれている場合、それらも削除されます。

Remove-AzResourceGroup -Name $imageResourceGroup

次のステップ

この記事で使用されている .json ファイルのコンポーネントの詳細については、Image Builder テンプレートのリファレンスに関するページを参照してください。