Howdy my friend ­čÖé

This article is a 3rd part of a series regarding WVD deployment.

Previous articles from the series could be found here:

  1. https://www.azureblog.pl/2020/09/19/windows-virtual-desktop-deployment-1-5/
  2. https://www.azureblog.pl/2020/10/07/windows-virtual-desktop-deployment-2-5/

Today I’d like to walk you through the custom image creation using Image stored on a Shared Image Gallery (SIG)

Prerequisites

Before we proceed please deploy 1 VM described below:

  1. VM1: OS: Windows 10 Enterprise multi-session, Version 2004., Disk Type: Managed

Shared Image Gallery as a image source

When we want to use SIG as a source for our image we need to use VM with managed disk.

Image creation process is depicted on a diagram below

Image creation process
  1. VM deployment – This is a standard VM deployment with a managed disk.
  2. VM configuration – this is a part when you configure, optimize, and install all line of Business (LOB) applications i.e. Office, Acrobat Reader, etc. Just before making the Sysprep remember to create a disk snapshot (os disk). After Sysprep, you can create a Shared Image Gallery and upload the image.
  3. Session host deployment – at this stage will use Shared Image Gallery and your custom Image as a source for session host deployment.

VM Configuration

Our plan is to configure OS (install required updates), install Adobe Acrobat Reader DC (imitation of the LOB applications), and then turn off VM and create a snapshot.

Yes. We are going to create a VM snapshot. It will help us to reconfigure a VM without building it from scratch. It will be our point in time configuration

As you might know I like to automate most of the things so this time we are going to use PowerShell script to create VM snapshot.

Firstly we need to declare variables required by scripts

Import-Module Az.DesktopVirtualization
$resourceLocation = "NorthEurope"
$vmResourceGroupName = 'rg-WVD-Images'
$giResourceGroupName = 'rg-WVD-Images'
$vmName = Read-host -Prompt "Please Provide VM Name"
$date = Get-date -UFormat "%d_%m_%Y"
$snapshotName = "snap-" + $vmName + "_" + $date
$imageName = "img-" + $vmName + "_" + $date

As you can see we are going to use the same resource group to store VMs and images ‘rg-WVD-Images‘.

Variables declaration
Write-Verbose "Looking for VM:'$vmName'"
$vm = Get-AzVM -ResourceGroupName $vmResourceGroupName -Name $vmName 
$diskID = $vm.StorageProfile.OsDisk.ManagedDisk.Id
Write-Verbose "Creating Snapshoot config for '$vmName' OSDisk '$diskID'"
$snapshot = New-AzSnapshotConfig -SourceUri $diskID -Location $resourceLocation -CreateOption copy
$snapshotTest = Get-AzSnapshot -SnapshotName $snapshotName -ResourceGroupName $vmResourceGroupName -ErrorAction SilentlyContinue
if ($null -eq $snapshotTest) {
    Write-Verbose "Creating new snapshot for VM: '$vmName', SnapshootName: '$snapshotName'"
    New-AzSnapshot -Snapshot $snapshot -SnapshotName $snapshotName -ResourceGroupName $vmResourceGroupName
}
else {
    Write-Verbose "Snapshot for VM: '$vmName', SnapshootName: '$snapshotName' already created."
}
Creating snapshot

Sysprep

Let’s turn on the VM ang go to the Sysprep location (C:\Windows\System32\Sysprep) and run it.

Sysprep location

Remember to use Generalize and Shutdown option

Sysprep settings

Image Creation

Now we are ready to create new Image using the following script.

Script will deallocate the VM, create Image and remove VM

Write-Verbose "Looking for VM:'$vmName'"
$vm = Get-AzVM -ResourceGroupName $vmResourceGroupName -Name $vmName 
$vmStatus = (Get-AZVM -ResourceGroupName $vmResourceGroupName -Name $vmName -status).statuses[1].DisplayStatus
if ($vmStatus -ne 'VM Deallocated') {
    Write-Verbose "Stopping vm:'$vmName'"
    Stop-AzVM -ResourceGroupName $vmResourceGroupName -Name $vmName -Force
}
else {
    Write-Verbose "VM:'$vmName' deallocated."
}
$diskID = $vm.StorageProfile.OsDisk.ManagedDisk.Id
$imageTest = Get-AZimage -ResourceGroupName $giResourceGroupName -ImageName $imageName -ErrorAction SilentlyContinue
if ($null -eq $imageTest) {
    Write-Verbose "Creating image config for vm: '$vmName', OSDisk '$diskID'"
    $imageConfig = New-AzImageConfig -Location $resourceLocation
    $imageConfig = Set-AzImageOsDisk -Image $imageConfig -OsState Generalized -OsType Windows -ManagedDiskId $diskID
    Write-Verbose "Creating new image for VM: '$vmName', imageName: '$imageName'"
    New-AzImage -ImageName $imageName -ResourceGroupName $giResourceGroupName -Image $imageConfig
    Write-Verbose "Removing vm '$vmName' from resourcegroup '$vmResourceGroupName'"
    Remove-AzVM -ResourceGroupName $vmResourceGroupName -Name $vmName -Force
}
else {
    Write-Verbose "Image from VM: '$vmName', ImageName: ''$imageName' already created."
}
Image creation

At this point, we should have an image resource created. We will use it in the next step.

Deploying Shared Image Gallery

To deploy shared image gallery please run the following code.

You will be asked to provide SIG name.

$galleryName = Read-host -Prompt "Please provide SharedImageGallery name"
$galleryTest = Get-AZGallery -ResourceGroupName $giResourceGroupName -GalleryName $galleryName -ErrorAction SilentlyContinue
if ($null -eq $galleryTest) {
    Write-Verbose "Creating image gallery: '$galleryName'"
    New-AzGallery -GalleryName $galleryName -ResourceGroupName $giResourceGroupName -Location $resourceLocation
}
else {
    Write-Verbose "Gallery '$galleryName' already created."
}
Shared Image Gallery creation

The next block of code will create a new image definition ‘Windows10-MU-AcrobatDC’ and image version ‘1.0.0’ under the shared image gallery

Write-Verbose "Looking for SharedImageGallery: '$galleryName'"
$gallery = Get-AzGallery -Name $galleryName -ResourceGroupName $giResourceGroupName
$imageID = (Get-AzImage -ResourceGroupName $giResourceGroupName -ImageName $imageName).id

Write-Verbose "Creating ImageDefinition"
$imageDefinition = New-AzGalleryImageDefinition -GalleryName $gallery.Name -ResourceGroupName $giResourceGroupName -Location $resourceLocation -Name 'Windows10-MU-AcrobatDC' -OsState Generalized -OsType Windows -Publisher 'Azureblog' -Offer 'Azureblog' -Sku '1'

$region1 = @{Name='northeurope';ReplicaCount=1}
$targetRegions = @($region1)
    
Write-Verbose "Creating ImageVersion"
New-AzGalleryImageVersion -GalleryImageDefinitionName $imageDefinition.Name -GalleryImageVersionName '1.0.1' -GalleryName $gallery.Name -ResourceGroupName $giResourceGroupName -Location $resourceLocation -TargetRegion $targetRegions -SourceImageId $imageID -PublishingProfileEndOfLifeDate '2021-10-06' -asJob 
Image definition creation

Wait until the Provisioning State will change to Successes

Image definition overview

Session Host deployment

From now you can use this Shared Image Gallery and Image.
You can do this using the following steps:

  1. During the Virtual Machine deployment chose Image type: Gallery
  2. Under Image, section chose Browse all images and disks
Selecting image type

3. Then under Select Image go to My Items tab.

4. From Shared Images section chose proper image.

Image selection from SIG

Complete the session host deployment and connect to the WVD environment.

Next steps

What to do next ?

We will work on the optimization and configuration of the WVD.

Write A Comment