Mar 09, 2022 Azure

Creating an Image from a VMSS Instance

An interesting question came up yesterday from a colleague. He asked me the following:
Can I create an image version on my Azure Compute gallery from a Virtual Machine Scale Set Instance?

Their company has a large operation running over Azure Virtual Machine Scale Sets. For a better understanding of the VMSS functionality and their application behaviour, was built a similar environment for development and pre-production.

He told me that the most painful thing is that after solving some bug/issue, they need to create a new VM from the Azure Compute Gallery and re-apply all of those settings, build a new image version and, sometimes, the team forgets to delete disks, VMs, etc.

Based on their scenario design, I was able to help by creating a new image version from a snapshot of the instance once the OS disk is generalized.

If you’re using “Trusted Launch Virtual Machines” you’ll wont be able to create an image version.

Trusted Launch Virtual Machines | Microsoft Docs

Let’s take a look at the code!

Variables Section

#Azure Login Parameters

$tenantId = ""
$subscriptionId = ""

#Instance Parameters

$vmssName = ""
$resourceGroupName = ""
$snapshotName = ""
$instanceId =

#Azure Compute gallery Parameters

$galleryName = ""
$galleryImageDefinition = ""
$imageVersion = ""


Once we defined the value of the variables, the script will execute the commands:

Those commands are responsible to login in your tenant and select the desired subscription.

$null = az login --tenant $tenantId
$null = az account set --subscription $subscriptionId

Once you’re logged in, the magic starts!

The command below will get the instance properties, this variable is used to get the

$vmssConfig = az vmss show --name $vmssName --resource-group $resourceGroupName --instance-id $instanceId | ConvertFrom-Json
if($null -eq $vmssConfig){
Write-Error -Message "Not able to find the instance $instanceId on $vmssName"
Write-Host"Instance $instanceId does exist on VMSS $vmssName"

Well, to keep it easy to use I decided to use the run-command extension to SYSPREP the os.

Once this command succeeds, the guest O.S will be shut down.

$null = az vmss run-command invoke -g $resourceGroupName -n $vmssName --command-id RunPowerShellScript --instance-id $instanceId --scripts "c:\windows\system32\sysprep\sysprep.exe /generalize /shutdown /oobe"

Once the SYSPREP is done, it will take a snapshot from the O.S Disk.

$snapshotCreation = az snapshot create -g $resourceGroupName -n $snapshotName --source $ | ConvertFrom-Json

The condition bellow will check the snapshot provisioningState.

if($snapshotCreation.provisioningState -eq "Succeeded"){
Write-Host"Snapshot provisioned with success" -ForegroundColor Green
}else {
Write-Error"Error While provisioning Disk Snapshot"
exit 1

Once our snapshot is done, a new image version will be created on your Azure Compute Gallery based on this snapshot.

$provisioningImage = az sig image-version create --resource-group $resourceGroupName --gallery-name $galleryName --gallery-image-definition $galleryImageDefinition --gallery-image-version $imageVersion --os-snapshot $ | ConvertFrom-Json

The condition below will check the provisioningState of the new image and if it succeeds, the instance and the disk snapshot will be deleted =D

if($provisioningImage.provisioningState -eq "Succeeded"){
Write-Host"New image version provisioned with success" -ForegroundColor Green
#Deleting Instance After creating the Snapshot and Sysprep
Write-Warning -Message "Deleting the Generalized Instance"
$null = az vmss delete-instances --name $vmssName --resource-group $resourceGroupName --instance-id $instanceId --no-wait
Write-Warning -Message "Deleting Snapshot"
$null = az snapshot delete --ids $
Write-Error"Error While provisioning new image version"

You can download the whole code on the link below:

Used commands:

az snapshot create | Microsoft Docs

az vmss show | Microsoft Docs

az vmss delete-instances | Microsoft Docs

az sig image-version create | Microsoft Docs

az vmss run-comand invoke | Microsoft Docs

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.