In this chapter, we will look at creating a custom image that we can use with Azure Virtual Desktop and some of the customization, updates, and publishing capabilities that are available in the Azure Compute gallery. It is important to note that the images for Azure Virtual Desktop are one of its core components as this is what the user will access. It's important to ensure that you configure and optimize them correctly so that you provide a good user experience. We will also take a look at troubleshooting some of the Operating System (OS) issues related to Azure Virtual Desktop.
In this chapter, we will cover the following topics:
In this section, we will look at provisioning a virtual machine (VM) in Microsoft Azure and preparing it for Azure Virtual Desktop.
To create a standardized template image for Azure Virtual Desktop, you will need to spin up a VM. In this section, we will look at doing just that.
To get started, you will need to navigate to the Azure portal at https://portal.azure.com. From there, follow these steps:
Tip
Your password must be at least 12 characters long and meet the required complexity. For more information, go to https://docs.microsoft.com/azure/virtual-machines/windows/faq#what-are-the-password-requirements-when-creating-a-vm-.
Once you have created the VM, you are ready to connect to it.
You can connect to an Azure VM using a remote desktop connection. You have two options – you can connect using a direct connection via a public IP address or connect using the local private IP address behind a VPN connection. Let's get started:
Important
Even though this section shows you how to connect using RDP via a public IP address, it is recommended that you connect over a VPN connection or Azure Bastion.
In Chapter 4, Implementing and Managing Networking for Azure Virtual Desktop, we learned how to configure Azure Bastion. It is recommended that you use Azure Bastion as RDP is insecure.
Once connected to the RDP session, you will see the session appear, as shown in the following screenshot:
Once you've connected to the VM via a public or local IP address, you can then modify/customize the image based on your organization's requirements.
Tip
You can also use Azure Bastion to connect to the VM if you don't want to connect via the Microsoft Terminal Services Client (MSTSC).
In the next section, we are going to learn how to modify a Session Host image, including customizing and optimizing it.
In this section, we will look at some of the customizations/optimizations you can apply to an image for Azure virtual Desktop.
Tip
When you're using Windows 10 Multi-Session images from Azure Gallery, FSLogix profile containers come pre-installed. It's recommended that you use an Azure Gallery template when possible.
When you're using pooled desktops, images are typically deployed centrally. First, updates are completed on the master image, and then VMs are redeployed to the host pool on the next scheduled maintenance window.
You should consider disabling Windows updates for Azure Virtual Desktop images as these should be carried out on the master image during a maintenance window. This enables control over patch updates and consistency through the deployed virtual desktop estate.
You may also want to consider configuring a validation environment, as discussed in Chapter 7, Configuring Azure Virtual Desktop Host Pools.
You can disable automatic updates directly on the Windows image using Regedit:
reg add "HKLMSOFTWAREPoliciesMicrosoftWindowsWindowsUpdateAU" /v NoAutoUpdate /t REG_DWORD /d 1 /f
Alternatively, you can use a Group Policy to apply the same change, as detailed in the following steps:
Now, let's install some language packs that we can use on the Azure Virtual Desktop image.
To use multiple languages within Azure Virtual Desktop, you need to ensure that all the required languages are installed.
Tip
Windows 11 onwards will only allow language packs to be distributed as .cab files, which can be used for imaging. LIP languages that aren't distributed as .cab files will only be available as .appx packages, which can be acquired through the Settings app after logging in.
Before you start customizing your image with multiple languages, you will need to download the required files for the language configuration; these can be found at the following links:
Important Note
Please note that the inbox apps that are included in the ISO are not the latest versions of the pre-installed Windows apps. You will need to update the apps using the Windows Store App and perform a manual search for updates after installing the additional languages.
You can find all the language ISO files here: https://docs.microsoft.com/azure/virtual-desktop/language-packs#prerequisites.
When you're installing languages on Windows 10 version 2004, 20H2, and 21H1, it's recommended that you check the known issues to ensure you choose the correct ISO: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/language-packs-known-issue.
Tip
You can read more about language packs here: https://docs.microsoft.com/en-gb/azure/virtual-desktop/language-packs.
The following summary steps will show you how to create a custom Windows 10 Enterprise Multi-Session image and connect the repository as a drive letter:
Important Note
Please note that the script should be customized to your needs and requirements. Running the entire script can take some time to complete.
You can find the script for adding languages to run Windows images here: https://github.com/PacktPublishing/Remote-Productivity-with-Windows-Virtual-Desktop/blob/main/B17392_07/Languages_winimage.ps1/.
Once the script has finished running, you can check that the language packs have been installed correctly by navigating to Start | Settings | Time & Language | Language. If the language files have been installed, you will see them here.
Once you have confirmed that the licenses have been installed, you can install the inbox apps for each required language. Then, you can update the inbox apps by refreshing the pre-installed apps using the inbox app's ISO image. You can use the PowerShell script template to automate this process and update only the installed versions for the inbox apps with no internet access: https://github.com/PacktPublishing/Remote-Productivity-with-Windows-Virtual-Desktop/blob/main/B17392_07/Update%20inbox%20Apps%20for%20Multi%20Language.ps1.
Once you have finished, make sure that you disconnect the share you attached previously (for example, drive Z).
Tip
To ensure that modern apps can use the additional language packs, you should use the following PowerShell cmdlet, which is used to disable language pack cleanup:
Disable-ScheduledTask -TaskPath "MicrosoftWindowsAppxDeploymentClient" -TaskName "Pre-staged app cleanup"
You can also find this within the example script provided here: https://github.com/PacktPublishing/Remote-Productivity-with-Windows-Virtual-Desktop/blob/main/B17392_07/Languages_winimage.ps1/.
Now, let's learn how to optimize an image.
In this section, we will look at two ways to optimize Azure Virtual Desktop images. Optimizing an image can improve the user experience for Azure Virtual Desktop users and can also improve user density per Session Host.
Important Note
Remember, turning off/disabling features and services can impact the functionality and behavior of the user desktop and applications that are running. Make sure that you fully understand what you are optimizing before applying it.
The VMware OS Optimization Tool allows you to analyze the current optimization state and available optimizations. You can even take a backup, which will allow you to roll back the changes you make.
To get started, download the VMware Optimization Tool by going to https://flings.vmware.com/vmware-os-optimization-tool:
Once it's been downloaded, run the application:
You will be presented with the screen shown in the preceding screenshot. Next, select the required template and click Analyze.
Once the application has finished reviewing the configurations, you will see an analysis summary and several optimizations that you can apply. Once you have finished choosing the required optimizations for your image, you can go ahead and click on Optimize, which is located in the bottom right-hand corner, as shown in the following screenshot:
Once you have clicked Optimize and the process has finished, you will see a table of optimizations that have been applied to the image, as shown in the following screenshot:
If you need to roll back the configurations to the previous state, you can complete this by following these steps:
The following screenshot shows these three steps, numbered as 1, 2, and 3:
There you have it. I have shown you how to analyze the current state, apply a set of optimizations, and roll them back if required.
Tip
You can export your selections using the Export selections button for future image creation. This means that you can import a different image into the VMware OS Optimization Tool and maintain optimizations from a previously tested configuration.
The second option would be to use the optimization tool and a set of PowerShell scripts that you can run on the template image to configure optimizations for the Virtual Desktop image.
You can access these scripts by going to the following GitHub repository https://github.com/The-Virtual-Desktop-Team/Virtual-Desktop-Optimization-Tool.
First, you will need to download the scripts from the aforementioned GitHub repository. Once you've downloaded them, you must find the build version of your OS – for example, C: empoptfilesConfigurationFiles – and change the required settings to Enabled (default) or Disabled. The following screenshot provides an example of the JSON configuration file for AppxPackages.json:
Once you have finished customizing the configuration files, you need to run the optimization script using PowerShell.
First, open PowerShell as an administrator, then set the execution policy to Bypass:
Set-ExecutionPolicy -ExecutionPolicy Bypass
The following screenshot shows the set execution policy's bypass cmdlets that have been run:
Once set, you need to run the script. Remember to use the required Windows version you are using. In this example, you will note that -WindowsVersion is 2004:
.Win10_VirtualDesktop_Optimize.ps1 -WindowsVersion 2004 -Verbose
The following screenshot shows the script being run and that the optimization process is in progress, as denoted by the progress bar:
Once complete, the script will finish and prompt you to reboot:
Once you have rebooted, you may notice that the processes and threads may have reduced within the TaskManager | Performance tab.
The following screenshot shows the number of processes and threads before optimization:
The following optimization screenshot shows a reduction in processes, threads, and handles:
Important Note
The Azure Virtual Desktop optimization script is community-driven and not supported by Microsoft.
Remember, optimizations have an impact on the user experience and some can be difficult to restore. So, ensure you create a snapshot before applying such changes to your image as it is not as easy to roll back using the Virtual Desktop optimization script.
In the next section, we will look at capturing an image template.
In this section, we will look at capturing an image template so that you can distribute the same image across multiple hosts within a host pool or even multiple host pools.
Important Note
Before you capture a VM in an image, make sure that you run the following command first:
C:WindowsSystem32SysprepSysprep.exe /oobe /generalise/shutdown
Once you've run this, make sure that the VM has been stopped in Azure. Then, you can proceed with the capture process.
It is also important to note that installing Microsoft Store apps or updating existing Store apps before generalizing a Windows image can cause Sysprep to fail. Sysprep also requires all apps to be provisioned for all users. When you update an app from the Microsoft Store, that application will become associated with the user account. You will then see the following error message:
<package name> was installed for a user, but not provisioned for all users. This package will not function properly in the Sysprep image.
This will be located within the Sysprep log file, here: %WINDIR%System32SysprepPanther.
You can read more about Sysprep here: https://docs.microsoft.com/windows-hardware/manufacture/desktop/Sysprep--generalize--a-windows-installation?view=windows-11.
To capture a template, follow these steps:
The Create image page will then appear.
For Resource group, use the existing one, select one from the dropdown, or create a new one.
In this section, we created an image from a VM and customized it. I will now show you how to create and use an Azure Compute Gallery.
A Shared Image Gallery (SIG) is a service that distributes images that can be shared across multiple regions and subscriptions within an Azure Active Directory (AAD) tenant. This is extremely useful for Azure Virtual Desktop as SIGs enable easy deployment of standard company desktop/server image templates across multiple Azure Regions. One of the other benefits of SIGs is that you can have different image versions and the newest can be referenced easily.
The following table details the different resource types within a SIG:
Tip
It is recommended that you become familiar with the terms within the following table before continuing.
The preceding table was taken from Microsoft's documentation: https://docs.microsoft.com/en-us/azure/virtual-machines/windows/shared-images-portal.
This section provided an overview of ACG and some of the specific terms that are used. In the next section, we will look at creating an ACG.
In this section, you will learn how to create an ACG, ready for you to capture an image inside it:
Important Note
SIG has been renamed Azure Compute Gallery (ACG). Note that some of the new names have not been fully updated on the Microsoft documentation site. You can read more here: https://docs.microsoft.com/azure/virtual-machines/create-gallery.
There you have it; we have now created an ACG and are ready to add image definitions. In the next section, we will capture an image in an ACG and create an image definition and our first version.
In this section, we will capture an image in the ACG we created previously. Similar to the capture process shown in the previous section, when we captured a template, we can capture the image from a generalized VM within the Virtual machines page:
Important Note
What does a generalized VM mean? Before you can deploy a Windows image to your Azure Virtual Desktop environment, you need to run a process called Generalize. This essentially removes computer-specific information such as the computer's security identifier (SID) and other items, such as drivers. This process enables you to turn the OS into a deployable template.
Important Note
An image definition's purpose is to carry information about the image and its requirements. This information is for IT use, and you can include release notes, as well as the minimum/maximum memory. You can also enter a publisher, offer, and SKU code, which is typically used for Azure Marketplace deployments.
The Azure Marketplace uses the following terminology:
Publisher: The organization that created the image; for example, MicrosoftWindowsServer.
Offer: The name of a group of related images that have been created by a publisher; for example, WindowsServer.
SKU: An instance of an offer, such as the major release of a distribution; for example, 2019-Datacenter Version, which is the version number of the image's SKU.
If you are not using the Azure Marketplace, you don't have to enter descriptive information, though it is recommended that you provide a description so that other IT admins can identify the specific image definition.
As shown in the following screenshot, I have provided the Publisher, Offer, and SKU fields with non-descriptive information. However, it is recommended that Publisher is set to your organization's name, Offer is set to the OS type (Windows 11), and SKU is set to the version (MultiSession):
The following are the four fields within the Version details section:
Once you've finished, click Go to resource. You will see the new image version:
With that, we have captured an image in the ACG; this has created both an image definition and an image version. Next, we will look at creating an image definition without using the capture feature shown previously.
This section will show you how to create a new image definition from the ACG:
In this short section, we looked at creating an image definition from a SIG. Now, let's learn how to create an image version.
In this section, we will learn how to create an image version within the image definition:
Tip
Image versions are useful for updating images and their general management.
The following table shows the specific details for each source type:
The preceding table was taken from Microsoft's documentation: https://docs.microsoft.com/azure/virtual-machines/linux/shared-images-portal.
In this section, we looked at creating an image version. Now, let's learn how to troubleshoot OS image issues related to Azure Virtual Desktop.
In this section, we will learn how to troubleshoot Session Host configuration issues. We will focus on the most common issues, including domain joins and communication between the Azure Virtual Desktop service and session host agent.
VMs not joining a domain typically occurs because the username and password that were entered during the host pool's setup/adding VMs were incorrect. Make sure that you check your password and use the full UPN of your Active Directory domain; for example, domJoin.company.local.
Important Note
When you're using AAD joined hosts, you would expect to see the hosts joined without the domain extension shown previously.
The other issue that may be preventing your VMs from joining the domain is a networking-related one, specifically DNS. Ensure that you have configured DNS correctly so that it points to your Active Directory Domain Service's infrastructure before trying to deploy session hosts.
Tip
Ensure that the account that you used for the domain join does not have multi-factor authentication (MFA) configured. You should use a service account with its password expiry set to disabled. You should also make sure that the account has delegated permissions to make sure the account can join multiple devices to the domain.
You should also check that you have configured the correct permissions for the domain join account; otherwise, the domain join process will fail. As shown in the following screenshot, there is no check password feature in the form. It is advised that you write the password out in text form and copy and paste it into the form to ensure it's correct:
In this section, we looked at how to troubleshoot domain joins issues when deploying session hosts to a host pool within Azure Virtual Desktop. We will now look at some of the Azure Desktop Agent and Bootloader issues that may occur.
For Azure Virtual Desktop to see the Session Hosts, you need to ensure that the Session Hosts have Azure Virtual Desktop Agent and Azure Virtual Desktop Bootloader installed. You can check this by reviewing the installed programs via Control Panel | Programs | Programs and Features. Alternatively, you can review the scriptlog.log file by navigating to the c:windows empScriptLog.log file path. The log file will show error messages to help you diagnose the root cause.
Important Note
Azure Desktop Agent and Virtual Desktop Bootloader should not be installed on the master image. This is installed automatically through a VM deployment for a host pool or a manual process.
If the ScriptLog.log file is missing, this would indicate that the Azure Resource Manager template had the incorrect permissions entered into it or that these credentials do not have the required permissions. Likewise, if PowerShell DSC was unable to start and run, this would indicate a permissions issue, that the hostname is incorrect, or that MFA is enabled, causing the sign-in process to fail.
The next section will look at Azure Virtual Desktop Agent not registering issues.
If you encounter an issue where the Session Host is unavailable within the Azure Virtual Desktop portal, this is typically due to the agent not communicating correctly with the Azure Virtual Desktop service. It is advised that you check connectivity from the Session Host to the Azure Virtual Desktop service using Sysinternals tools such as PSPing.
You can download PSPing from https://docs.microsoft.com/en-us/Sysinternals/downloads/psping/.
To test your connectivity, run the following as an administrator within the command line:
Important Note
For those who have already deployed an AVD environment, you can use the WVDAgentUrlTool.exe tool, which can be found in the C:Program FilesMicrosoft RDInfraRDAgent_* folder.
psping rdbroker.wvdselfhost.microsoft.com:443
The following screenshot shows using PSPing to confirm that the host can communicate with the Rdbroker for Azure Virtual Desktop:
Tip
This test is also useful if the Azure Virtual Desktop agent is not reporting a heartbeat when you run the Get-AzWvdSessionHost PowerShell cmdlet.
Once you have checked your network connectivity and confirmed that this is not the issue, you should follow these steps to update the agent manually:
If the Azure Virtual Desktop Agent registry entry called IsRegistered shows a value of 0, then the registration token has expired. You will need to generate a new registration token to fix this:
You can check this using a Powershell cmdlet.
Remove-AzWvdRegistrationInfo
Further Information
For more information on common Virtual Desktop Agent issues, you can find a complete list of errors and troubleshooting guidance at https://docs.microsoft.com/azure/virtual-desktop/troubleshoot-agent.
This section looked at some of the troubleshooting issues that may affect how the image communicates with Azure Virtual Desktop. We will now look at basic performance troubleshooting in Azure Virtual Desktop.
In this section, we will look at ways to identify and resolve common performance issues that may occur on Session Hosts within an Azure Virtual Desktop environment.
Four key resources can impact performance on a Session Host, as follows:
The typical performance issues you may experience include capacity, constraints, and overall performance degradation or lag.
First, we will look at troubleshooting CPU performance issues.
CPU constraints are a common issue with session-based desktops. Performance and high CPU utilization issues can occur for several reasons and not be due to a single app or service. The web browser can be one such suspect, especially if hardware rendering has been left set to on once the master image has been optimized. You can view your CPU usage by going to Task Manager, and then go to Azure monitoring features within the Azure portal for specific VM and using Sysinternals Process Explorer:
Tip
You can download process explorer here: https://docs.microsoft.com/Sysinternals/downloads/process-explorer.
The following screenshot shows using the Sysinternals process explorer to gauge the CPU usage when monitoring the performance of an OS:
The following screenshot shows using the Sysinternals process explorer to monitor running processes to see which are consuming the most CPU and memory. This is a great tool for identifying processes that are consuming excessive resources:
The following are some useful tips for when you're troubleshooting CPU resource issues:
Tip
It is recommended that you build more session hosts with fewer CPUs. This is advised because when you increase the number of cores, the system's synchronization overhead also increases. Smaller resourced VMs would perform better than fewer and larger specification VMs.
Here are a few examples of potential symptoms you may see when the CPU is under contention:
Now, let's look at a few RAM performance issues and how to spot some of them.
Modern applications consume more RAM. For example, when you combine Microsoft Office Suite, Microsoft Teams, and have multiple other applications open simultaneously, this can impact RAM consumption. When RAM reaches high consumption or becomes full, it will revert to the page file as secondary storage for the main memory.
The challenge with page file is speed. For example, a Solid State Drive (SSD) could have a typical write speed of 456 MB per second, whereas RAM writes at estimated speeds of 12,800 MB per second. When all the RAM has been consumed, the performance drops as secondary storage is being used. This performance drop will be seen by users and will most likely cause performance degradation for multiple users on a session host.
You can view your session host RAM utilization in Azure monitoring, as shown in the following screenshot:
The following are some tips for troubleshooting RAM issues:
Some of the symptoms you may see with RAM issues are as follows:
We now move on to the next section where we look at disk performance and troubleshooting.
This is a common problem as it's easy to forget about the OS disk when it comes to multi-session deployments. Within Microsoft Azure, different sized disks have different performance outputs, which are measured in input/output operations per second (IOPS). To avoid any disk performance degradation, you should size the disk based on IOPS and factor in the expected total number of users per session host. P15 Azure Managed Disks or higher is recommended to ensure there's enough IOPS to serve all users and applications in use. Every environment can be different; it is advised to baseline your requirements for IOPS by using one or two users on a Session Host to generate IOPS consumption. You can then see the total usage of the disk over a set period from the test users carrying out their typical day-to-day tasks.
You can then use the data that's been collected to calculate the requirements and estimate the required IOPS based on a set number of users per Session Host.
See the following link for a list of the premium SSD disk sizes and their allocated IOPS: https://docs.microsoft.com/en-us/azure/virtual-machines/disks-types#premium-ssd-size.
Tip
It is also important to note that choosing a VM that's the wrong size may limit the throughput that's allowed by the disk. So, you must check the VM specs as well as the disk IOPS output. The following link provides a table detailing the max IOPS per VM size: https://docs.microsoft.com/en-us/azure/virtual-machines/dav4-dasv4-series#dav4-series.
The following command can help you identify disk performance issues by spotting high disk queues:
typeperf -si 2 "PhysicalDisk(*)Avg. Disk Queue Length"
The following screenshot shows the output of the current disk queue length of the OS. This is a great tool for identifying any issues with the disk performance on the OS:
For a centralized view of potential disk performance issues, you can use Azure Monitor or Log Analytics. Azure Monitor and Log Analytics will be covered in Chapter 18, Monitoring and Managing Performance and Health.
The following are some key points regarding disk troubleshooting:
Now, let's take a look at the symptoms. The following are some disk performance symptoms:
This section looked at disk performance issues, as well as some troubleshooting hints and tips that you can use to resolve some of the issues you may face.
Networking issues can occur in three areas: the user endpoint device, Azure Virtual Desktop's management service, and the session host itself. When you're reviewing network issues, it is recommended that you start with the client device and then look at the Azure Virtual Desktop management service and session host connectivity.
There are four typical network contention issues that you can experience:
These issues are usually found on the user side, all of which can be due to many different reasons. However, it is important to follow the necessary processes and check all three areas. There can be issues with the broker service, gateway communication, and even the Session Host agent service.
You can also review the connection information by right-clicking on the Session title bar, as shown in the following screenshot:
Click the Connection information button to see the Connection information window appear. Click show details to view the connection details for the client connection. Note that the round trip time, available bandwidth, and frame rate are shown here:
The following are some tips for identifying network issues:
Using Azure Virtual Desktop's Insights dashboard to view end user latency and poor user bandwidth. Azure Monitor and Azure Virtual Desktop Insights will be covered in Chapter 18, Monitoring and Managing Performance and Health.
This section looked at some hints and tips for spotting possible issues and resource contentions that may impact or affect your Session Hosts and connecting users.
In this chapter, we looked at creating a gold image for Azure Virtual Desktop, as well as modifying the session image, including customizing it, optimizing it, and capturing it in an image template. Then, we created an ACG, including creating image definitions and image versions. Finally, we looked at troubleshooting the OS and diagnosing possible performance and resource contention issues.
In the next chapter, we will look at managing access and configuring IT admin and user security permissions.
Answer the following questions to test your knowledge of this chapter: