Azure Windows VM Provisioning Insights

Recently I was exploring and trying to understanding Windows Virtual Machine provisioning in Azure and creating custom image using sysprep and thought to write this post with some explanation of what happens at Windows OS level when we create Windows VM in Azure and how the customization happens during “specialize” phase of Windows VM in Azure.

As we all are aware that System Preparation (Sysprep) is a native Windows tool helps “generalizing” the Windows installation that allows us to capture custom standardize image of Windows Operating System that can be used to deploy multiple Windows systems in the organization. Sysprep has been used since decades and are still used in cloud environments as well.

If you want to create “generalized” image of Windows machine then you need to run following command, when you run sysprep it looks for an answer file called “unattend.xml”. Answer files (unattend.xml) is used to modify Windows settings in images during Setup, we can also specify settings that trigger scripts in images that run after the first user creates their account and picks their default language. Windows Setup looks for answer file during each phase, including initial installation and after applying and boot an image. If an answer file is found, and it contains settings for the given configuration pass, it processes those settings.

%WINDIR%\system32\sysprep\sysprep.exe /generalize /shutdown /oobe

On a high level sysprep goes through the following phases, also called as “Configuration Pass”.

1. Generalize Configuration Pass:
At this phase, the unique security ID (SID) and other hardware-specific settings are removed from the image including  the computer name, the event logs, and specific drivers. When you “generalize” Azure VM, we don’t remove drivers because the “PersistAllDeviceInstalls” setting is set to true by default.  Please refer below generalize configuration pass from answer file of the Azure Windows VM.

 If something fails at this phase, please look into the log files available under following locations.

Generalize phase logs:

2. Specialize Configuration Phase:
After the generalize pass finishes, the next time that Windows image boots, the specialize configuration pass runs, Plug and Play scans the computer and installs drivers for any detected devices. After the Windows image boots for the first time, the specialize configuration pass runs. During this pass, unique security IDs (SIDs) are created and Computer Name is also created. Additionally, you can configure many Windows features, including network settings, international settings, and domain information. We also specify and execute any scripts during this phase, below xml is the “specialize” configuration pass defined in answer file of the Azure Windows VM. If you look at this xml, there are various Windows unattended setup components related to Windows Defender, Terminal Services, Windows Shell Setup and so on.
Windows VM provisioning and customization is handled by Azure Provisioning Agent (PA) which is installed by default in the Azure marketplace images provided by Microsoft. Provisioning Agent is basically part of Azure VM Guest Agent packages which contains below two packages and to prepare and boot Windows VM in Azure we must have Provisioning Agent installed.

  -Provisioning Agent (PA)
  -Windows Guest Agent (WinGA)

If you look at below xml file closely, you would see it runs “unattend.wsf” script during “specialize” phase, this script is located under “%SystemRoot%\OEM\Unattend.wsf” in Azure Windows VM and this is the main script which is completely responsible for preparing and getting your Windows VM ready. This script runs few other child scripts related to RDP certificate generation, Windows License activation and so on, In short this “unattend.wsf” script does following to prepare Windows VM during “specialize” phase.

–Configure Boot Status Policy
–Configure Time Service and Time Settings   
–Configure San Policy  
–Configure Rdp KeepAlive and Update RDPCertificate Thumbprint  
–Set Screen AlwaysOn  
–Configure BCD   
–Configure Recovery Enabled     
–Copy Custom Data 
–Run AzSec Agent         
–Configure Certificates   
–Configure Windows Remote Management (WinRM)
–Configure Windows Automatic Updates  
–Configure Guest Agent Service     
–Activate Windows license

If something fails at this phase, please look into the log files available under following locations.

Specialize phase:

3. Out-of-Box Experience (OOBE) Configuration Pass:
OOBE phase is generally used to configure Windows Shell options, create user accounts, and specify language and locale settings. If you look at below OOBE configuration pass from “unattend.xml” file from Windows VM in Azure “SkipMachineOOBE” and “SkipUserOOBE” is set to TRUE which means its skipping OOBE phase at least in Windows VM provisioning in Azure possibly because customization and setup of Windows VM is completely handled by Provisioning Agent that handles OOBE part as well. In general scenario outside Azure it may not work if you skip OOBE phase, Microsoft says “Do not use SkipMachineOOBE or SkipUserOOBE in your Unattend.xml file. These settings are deprecated and can have unintended effects if used.”

If something fails at this phase, please look into the log files available under following locations.
Unattended Windows Setup actions (OOBE):

After the Virtual Machine is provisioned successfully and you are able to connect it via RDP, you can look at the below registry key to find some interesting details about your Virtual Machine.

HKLM\Software\Microsoft\Virtual Machine

I hope you find this helpful, if you want to dive deeper into Windows Sysprep you may refer following Microsoft documentations.

Windows Setup States:

Unattended settings that can be set in Windows 10 and Windows Server 2016:


Unattended Settings Components:

How Configuration Passes Work:

Automate OOBE:

4 thoughts on “Azure Windows VM Provisioning Insights”

Leave a Reply

Your email address will not be published.