title | description | author | ms.author | ms.reviewer | ms.date | ms.topic | ms.service | ms.subservice | ms.collection | ms.custom |
---|---|---|---|---|---|---|---|---|---|---|
Create a Windows VM with Azure VM Image Builder by using PowerShell |
In this article, you create a Windows VM by using the VM Image Builder PowerShell module. |
kof-f |
kofiforson |
jushiman |
11/10/2022 |
how-to |
virtual-machines |
image-builder |
windows |
devx-track-azurepowershell |
Applies to: ✔️ Windows VMs
This article demonstrates how to create a customized Windows VM image by using the Azure VM Image Builder PowerShell module.
If you don't have an Azure subscription, create a free account before you begin.
If you choose to use PowerShell locally, this article requires that you install the Azure PowerShell module and connect to your Azure account by using the Connect-AzAccount cmdlet. For more information, see Install Azure PowerShell.
Some of the steps require cmdlets from the Az.ImageBuilder module. Install separately by using the following command.
Install-Module -Name Az.ImageBuilder
[!INCLUDE cloud-shell-try-it]
If you have multiple Azure subscriptions, choose the appropriate subscription in which the resources should be billed. Select a specific subscription by using the Set-AzContext cmdlet.
Set-AzContext -SubscriptionId 00000000-0000-0000-0000-000000000000
If you haven't already done so, register the following resource providers to use with your Azure subscription:
- 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
Because you'll be using some pieces of information repeatedly, create some variables to store that information:
# 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'
Create a variable for your Azure subscription ID. To confirm that the subscriptionID
variable contains your subscription ID, you can run the second line in the following example:
# Your Azure Subscription ID
$subscriptionID = (Get-AzContext).Subscription.Id
Write-Output $subscriptionID
Create an Azure resource group by using the New-AzResourceGroup cmdlet. A resource group is a logical container in which Azure resources are deployed and managed as a group.
The following example creates a resource group that's based on the name in the $imageResourceGroup
variable in the region that you've specified in the $location
variable. This resource group is used to store the image configuration template artifact and the image.
New-AzResourceGroup -Name $imageResourceGroup -Location $location
Grant Azure image builder permissions to create images in the specified resource group by using the following example. Without this permission, the image build process won't finish successfully.
-
Create variables for the role definition and identity names. These values must be unique.
[int]$timeInt = $(Get-Date -UFormat '%s') $imageRoleDefName = "Azure Image Builder Image Def $timeInt" $identityName = "myIdentity$timeInt"
-
Create a user identity.
New-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName -Location $location
-
Store the identity resource and principal IDs in variables.
$identityNameResourceId = (Get-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName).Id $identityNamePrincipalId = (Get-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName).PrincipalId
-
Download the JSON configuration file, and then modify it based on the settings that are defined in this article.
$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
-
Create the role definition.
New-AzRoleDefinition -InputFile $myRoleImageCreationPath
-
Grant the role definition to the VM Image Builder service principal.
$RoleAssignParams = @{ ObjectId = $identityNamePrincipalId RoleDefinitionName = $imageRoleDefName Scope = "/subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup" } New-AzRoleAssignment @RoleAssignParams
Note
If you receive the error "New-AzRoleDefinition: Role definition limit exceeded. No more role definitions can be created," see Troubleshoot Azure RBAC (role-based access control).
-
Create the gallery.
$myGalleryName = 'myImageGallery' $imageDefName = 'winSvrImages' New-AzGallery -GalleryName $myGalleryName -ResourceGroupName $imageResourceGroup -Location $location
-
Create a gallery definition.
$GalleryParams = @{ GalleryName = $myGalleryName ResourceGroupName = $imageResourceGroup Location = $location Name = $imageDefName OsState = 'generalized' OsType = 'Windows' Publisher = 'myCo' Offer = 'Windows' Sku = 'Win2019' } New-AzGalleryImageDefinition @GalleryParams
-
Create a VM Image Builder source object. For valid parameter values, see Find Windows VM images in Azure Marketplace with Azure PowerShell.
$SrcObjParams = @{ PlatformImageSource = $true Publisher = 'MicrosoftWindowsServer' Offer = 'WindowsServer' Sku = '2019-Datacenter' Version = 'latest' } $srcPlatform = New-AzImageBuilderTemplateSourceObject @SrcObjParams
-
Create a VM Image Builder distributor object.
$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
-
Create a VM Image Builder customization object.
$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
-
Create a second VM Image Builder customization object.
$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
-
Create a VM Image Builder template.
$ImgTemplateParams = @{ ImageTemplateName = $imageTemplateName ResourceGroupName = $imageResourceGroup Source = $srcPlatform Distribute = $disSharedImg Customize = $Customizer01, $Customizer02 Location = $location UserAssignedIdentityId = $identityNameResourceId } New-AzImageBuilderTemplate @ImgTemplateParams
When the template has been created, a message is returned, and a VM Image Builder configuration template is created in $imageResourceGroup
.
To determine whether the template creation process was successful, use the following example:
Get-AzImageBuilderTemplate -ImageTemplateName $imageTemplateName -ResourceGroupName $imageResourceGroup |
Select-Object -Property Name, LastRunStatusRunState, LastRunStatusMessage, ProvisioningState
In the background, VM Image Builder also creates a staging resource group in your subscription. This resource group is used for the image build. It's in the format IT_<DestinationResourceGroup>_<TemplateName>
.
Warning
Don't delete the staging resource group directly. To cause the staging resource group to be deleted, delete the image template artifact.
If the service reports a failure when the image configuration template is submitted, do the following:
-
Before you retry submitting the template, delete it by following this example:
Remove-AzImageBuilderTemplate -ImageTemplateName $imageTemplateName -ResourceGroupName $imageResourceGroup
Submit the image configuration to the VM Image Builder service by running the following command:
Start-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name $imageTemplateName
Wait for the image building process to finish, which could take up to an hour.
If you encounter errors, review Troubleshoot Azure VM Image Builder failures.
-
Store the VM login credentials in a variable. The password must be complex.
$Cred = Get-Credential
-
Create the VM by using the image you created.
$ArtifactId = (Get-AzImageBuilderTemplateRunOutput -ImageTemplateName $imageTemplateName -ResourceGroupName $imageResourceGroup).ArtifactId New-AzVM -ResourceGroupName $imageResourceGroup -Image $ArtifactId -Name myWinVM01 -Credential $Cred
-
Create a Remote Desktop connection to the VM by using the username and password that you set when you created the VM.
-
Inside the VM, open PowerShell and run
Get-Content
, as shown in the following example:Get-Content -Path C:\buildActions\buildActionsOutput.txt
The output is based on the contents of the file that you created during the image customization process.
Azure-Image-Builder-Was-Here
-
From the same PowerShell session, verify that the second customization finished successfully by checking for the presence of
c:\buildArtifacts\index.html
, as shown in the following example:Get-ChildItem c:\buildArtifacts\
The result should be a directory listing showing that the file was downloaded during the image customization process.
Directory: C:\buildArtifacts Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 29/01/2021 10:04 276 index.html
If you no longer need the resources that were created during this process, you can delete them by doing the following:
-
Delete the VM Image Builder template.
Remove-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name $imageTemplateName
-
Delete the image resource group.
[!CAUTION] The following example deletes the specified resource group and all the resources that it contains. If any resources outside the scope of this article exist in the resource group, they'll also be deleted.
Remove-AzResourceGroup -Name $imageResourceGroup
To learn more about the components of the JSON file that this article uses, see the VM Image Builder template reference.