Windows Autopilot In-Depth Processes from Device Side – Part 3

0
Windows Autopilot

Let’s get into another deep dive blog post about Windows Autopilot processes. I call it behind the scene processes and data flows.

Related Posts

Introduction

I discussed about the working block and concepts of Windows Autopilot from the perspective of IT Admin setup in my previous post. In this post, I will be talking about the workings of Windows Autopilot In-Depth from the device side processes.

Know About Windows Configuration Passes

Before we start, I would like to give some insights on Windows Configuration Passes. People with OSD background will be already familiar with this Windows Configuration.

Windows Setup - Configuration Passes - Windows Autopilot In-Depth Processes
Windows Setup – Configuration Passes – Windows Autopilot In-Depth Processes

Installing Windows on a device – Windows Setup, happens in a series of configuration passes (phases?) in a specific order. There are 7 of these as listed below, however it is important to note that a particular installation might not go through all them.

  1. Windows PE  
  2. OfflineServicing
  3. Generalize
  4. Specialize  
  5. auditSystem
  6. auditUser
  7. oobeSystem

An answer file (unattend.xml) can be used to customize/automate the Windows Setup in one or many of these configuration passes.

Note: At the beginning of each phase, it checks the Answer file to see if there are any values provided to drive that phase. If found, it uses those values and continues, else will resort to user input to continue. This is how traditionally in OSD the Windows Setup is customized.

What configuration passes a Windows Setup goes through?

Below is the schematic representation showing the configuration passes through which Windows Setup process handles the OS installation (generalized).

Windows Setup Config Pass
Windows Setup – Configuration Passes (generalized)

Configuration pass -> WindowsPE

This is the pass in which we boot from install media and start the Windows Setup which then copies the OS Image to local drive and prepares the system to boot from local drive. There is a restart when done.

  • Windows Autopilot In-Depth Processes from Device Side - Part 3 1
  • Windows Autopilot In-Depth Processes from Device Side - Part 3 2
  • Windows Autopilot In-Depth Processes from Device Side - Part 3 3
  • Windows Autopilot In-Depth Processes from Device Side - Part 3 4
  • Windows Autopilot In-Depth Processes from Device Side - Part 3 5
  • Windows Autopilot In-Depth Processes from Device Side - Part 3 6

Configuration pass -> OfflineServicing

Post restart, Setup continues from local drive and not boot media. During this time, it initializes the drivers and prepares the system to support Windows for 1st boot.

There is a restart again post which starts the actual first boot of the OS – this is when the OS (NT kernel) initializes on the system for the 1st time marking the end of OfflineServicing pass.

At this stage, the Kernel is initialized and it launches the smss.exe, first user mode SYSTEM process which initializes the csrss.exe process which initializes the Win32 subsystem to support windows environment.

Windows Setup Pass OfflineServicing and Generalize -  Windows Autopilot In-Depth Processes
Windows Setup Pass OfflineServicing and GeneralizeWindows Autopilot In-Depth Processes

Configuration pass -> Generalize

Post end of OfflineServicing pass and entering the oobeSystem pass, there is a small transition in between – Generalize pass.

Specialize configuration pass always runs after a computer has been generalized, regardless of whether the computer is configured to boot to audit mode or Windows Welcome.

-----------------SYSPREP (Generalize Config Pass)-------------------------------
[windeploy.exe] Waiting for essential OOBE services to start…
[windeploy.exe] Essential OOBE services started successfully.
[windeploy.exe] Windeploy: Executing PreSysprep commands
[windeploy.exe] ExecuteCommandFromValue: Executing command line: C:\$WINDOWS.~BT\Sources\SetupPlatform.exe /presysprep
[windeploy.exe] Found generalization state [0x4], setup.exe completion flag [False] --> launching setup.exe.
[windeploy.exe] Windeploy: Running default setup.
[windeploy.exe] Windeploy: Executing PostSysprep commands
[windeploy.exe] ExecuteCommandFromValue: Executing command line: C:\$WINDOWS.~BT\Sources\SetupPlatform.exe /postsysprep
[windeploy.exe] OrchestrateDetermineComputerNameChange: Checking computer name change conditions:
[windeploy.exe]   Did Setup change computer name? TRUE
[windeploy.exe]   Could OOBE change computer name? TRUE
[windeploy.exe] ShouldShutdownAfterSetup: Checking reboot conditions:
[windeploy.exe]   Are only OOBE services running? FALSE
[windeploy.exe]   Is there a computer name change? TRUE
[windeploy.exe]   Was Winlogon reboot requested? TRUE
[windeploy.exe]   Is Upgrade in progress? FALSE
[windeploy.exe]   Is this Audit mode boot? FALSE
[windeploy.exe] Reboot required after setup.exe and PostSysprep commands, before launching OOBE.
[windeploy.exe] An immediate reboot or shutdown was requested/required…

Configuration pass -> oobeSystem

This is when Setup enters the user mode GUI setup or what Microsoft likes to call it by the name Out-Of-Box-Experience.

[windeploy.exe] Launching [C:\WINDOWS\system32\oobe\oobeldr.exe /system /quiet]…
[oobeldr.exe] Found no unattend file for oobeSystem pass; skipping pass.
[oobeldr.exe] Launching [C:\WINDOWS\system32\oobe\msoobe.exe]…
[msoobe.exe] Starting OOBE
[msoobe.exe] Running OOBE wizard…
  • Windows Autopilot In-Depth Processes from Device Side - Part 3 7
  • Windows Autopilot In-Depth Processes from Device Side - Part 3 8
  • Windows Autopilot In-Depth Processes from Device Side - Part 3 9
  • Windows Autopilot In-Depth Processes from Device Side - Part 3 10

But why are we discussing about the configuration passes?

Autopilot device provisioning happens during the oobeSystem phase of Windows Setup.

However, it is important to note that before Setup enters the oobeSytem config pass, it searches for an Answer file (unattend.xml) which is used to customize the entire configuration pass.

A sample unattend file example:

<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="oobeSystem">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <OOBE>
                <HideEULAPage>true</HideEULAPage>
                <HideLocalAccountScreen>true</HideLocalAccountScreen>
                <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
                <HideOnlineAccountScreens>true</HideOnlineAccountScreens>
                <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
                <NetworkLocation>Home</NetworkLocation>
                <ProtectYourPC>3</ProtectYourPC>
                <SkipMachineOOBE>true</SkipMachineOOBE>
                <SkipUserOOBE>true</SkipUserOOBE>
                <UnattendEnableRetailDemo>false</UnattendEnableRetailDemo>
            </OOBE>
</component>
</settings>
</unattend>

If setup finds an unattend.xml to drive the oobeSystem pass which happens mostly in case of custom prepared images, the device will not trigger Autopilot provisioning even if it is assigned – the reason why a custom prepared OS image is not suggested with Autopilot provisioning.

For a non-customized OS image as well as an OEM image, it won’t find one and as such will continue with the default values – showing all the OOBE screens as required.

Windows Out-Of-Box-Experience…

The Out-Of-BoxExperience (OOBE) is the first boot setup process, as Microsoft like to call it that way.

What’s so special about Windows 10 OOBE?

For Windows 10, the OOBE is web driven and carried out in a special host process called CloudExperienceHost. This process runs under a temporal user account “defaultuser0” (yes the same way we see in case of KIOSK deployment)

What is this defaultuser0 account?

Post installation as Setup starts the OOBE (First Boot Setup), Windows is already fully functional at the point but devoid of a working user account profile.

For security reasons, starting with Windows 10, the Built-in Administrator account is in disabled state by default.

OOBE requires a user account to work as it cannot run in Session 0

Session 0 is the SYSTEM session which is the reserved session for system processes which usually do not require access to GUI for user interaction. But OOBE requires user interaction to work…

So what system does is,

  • Creates a temporary user profile causing Winlogon to initiate a new login session – Session 1 which is a user mode session.
  • In that session, it creates the CloudExperienceHost process which is running the OOBE and tags it to WinSta0 desktop object making it capable of user interaction.

This temporary user account is the defaultuser0 and it has full access to Windows.

[msoobe.exe] TASK: Begin running task PrepareUserOOBE...
[msoobe.exe] Creating a new default account
[msoobe.exe] Not setting autologon since this is an upgrade or the machine is domain-joined.
[msoobe.exe] Default account: defaultuser0 is created successfully
[msoobe.exe] TASK: End successfully running task PrepareUserOOBE
[msoobe.exe] Post-setup for the default account is run successfully
OOBE running under defaultuser0 account -  Windows Autopilot In-Depth Processes
OOBE running under defaultuser0 accountWindows Autopilot In-Depth Processes

This account is deleted at the point when setup has provisioned the actual user profile (usually post completion of the ESP 2nd stage – Device setup) and can continue by using it.

Difference from Windows 7 and Windows 8/8.1?

In Windows 7 and Windows 8/8.1 (also called as Windows downlevel), the OOBE setup used local pages and ran under SYSTEM context making them incompatible with Windows Autopilot.

Windows Autopilot OOBE flow (simplified overview only)

  • Setup starts the CloudExperienceHost process. (windeploy.exe -> oobeldr.exe -> msoobe.exe which starts the CloudExperienceHost process, refer above)
  • CloudExperienceHost renders the Cortana Welcome Screen.
  • CloudExperienceHost renders the Language (Region) selection screen.
  • CloudExperienceHost renders the Keyboard layout selection and additional Keyboard layout selection screens.
  • If Windows Setup detects that there is no Ethernet connection, CloudExperienceHost renders the Network screen. Else this is skipped.
Each of this OOBE screen as rendered are essentially webapps (in the form of
html, oobe<part>.html) utilizing JavaScript (client code implementation of 
Worker API, as oobe<part>-page.js) capable of calling WinRT API via the
CloudHostExperience process and can be found here under the path
"C:\Windows\SystemApps\Microsoft.Windows.CloudExperienceHost_cw5n1h2txyewy\webapps\inclusiveOobe"

Each of these webapps is also supported by the Cortana voice-over functionality
via JavaScript (oobe<part>-vm.js) which gives voice guidance to the user 
through the OOBE, enabling users to complete parts of setup using speech 
(voice command) as well. However, with Windows 10 1903 and later, this 
voice-over feature is disabled by default for Pro, Enterprise and Education SKU.

Where does the real action starts from?

As the device gets connected to the network is where the real things starts. There are a lot of background activities performed like:

  • Windows Critical Updates (Windows Zero Day patches as we call them)
  • Windows Activation license check, and yes the most important
  • Autopilot check.

NOTE: Till Win 10 v1709, Autopilot activation check was initiated post connecting to network. (If using wired connection, this page is skipped by default, but Autopilot check used to start post the OOBE Network screen timeframe before the EULA screen was to be rendered). As the device got connected to network, device initiated the autopilot check and downloaded the profile from Autopilot service to drive the rest of OOBE.

NOTE: From Win 10 v1803, Autopilot activation check is initiated as soon as it enters OOBE setup, essentially from the Region screen and if using wired connection, reaches out to Autopilot service to get the profile downloaded while the device might still be in OOBE keyboard selection screen. If there is no wired connection, it will wait till the device gets connected to a network in OOBE.

Thus for Windows 10 1803 and above, if you are using Wireless connection, this explains the reason why you would expect to see the below entries in the Autopilot events

Event ID 100 AutoPilot policy [AUTOPILOT_OOBE_SETTINGS_AAD_AUTH_USING_DEVICE_TICKET] not found. 

Event ID 165 AutoPilotManager determined Internet is not available; policy download will queue when available. 

Event ID 167 AutoPilotManager reported Internet is still not available. 

Want to see the Worker API (client code) responsible for the Autopilot check?

The client code (JavaScript – Worker API) is autoPilot.js found at C:\Windows\SystemApps\Microsoft.Windows.CloudExperienceHost_cw5n1h2txyewy\js

autoPilot.js - client code -  Windows Autopilot In-Depth Processes
autoPilot.js – client codeWindows Autopilot In-Depth Processes

The worker API essentially calls WinRT functions via CloudExperienceHost implemented in the autopilot.dll

autopilot.dll functions
Windows Autopilot – component autopilot.dll – functions

Want to see the actual sequence of Activity as performed during the OOBE?

You can use Windows Performance Recorder (WPR) to capture an ETW trace (initiated from CMD in OOBE) . Open the trace as captured with Windows Performance Analyzer (WPA) which is part of the Windows 10 ADK.

Expand the System Activity > Add the Generic Events to the Graph Analysis view. The Event Series Microsoft.Windows.Shell.CloudExperienceHost.Common will contain Windows Autopilot activities

WPA - Microsoft.Windows.Shell.CloudExperienceHost.Common - Windows Autopilot In-Depth Processes
WPA – Microsoft.Windows.Shell.CloudExperienceHost.Common – Windows Autopilot In-Depth Processes

Now add the Regions of Interest to the Graph Analysis view and you can see the sequence of activity as performed. As can be seen, the Autopilot process starts before the OOBE Welcome page is rendered.

OOBE Webactivity WPA - Region of Interest - Windows Autopilot In-Depth Processes
WPA – Region of Interest – Windows Autopilot In-Depth Processes
Till Win 10 1803, the autopilot profile as downloaded was cached locally 
which remained persistent and as such required a re-generalize 
(sysprep /generalize /oobe) or reset to remove the settings, even if you 
had not completed the entire OOBE. 

For Win 10 1809 and above, the profile as downloaded can be removed by just
rebooting the system while still in OOBE to get a new profile. However, once 
it completes the OOBE, the profile is persistent and then it would still 
require a re-generalize or reset.

What happens as the device gets connected to network?

You would require to have a network capture to see the connections the device is making while it goes through the OOBE to give a more clear picture. You can use the netsh trace and analyze with Netmon (windows parser), you can use Wireshark or any tool you like. I used both Netsh and Fiddler running from USB to see and compare the network traffic.

Off the topic, want to know how to make Fiddler run from USB?

Extract the FiddlerSetup.exe as downloaded to USB via 7zip and you get a folder
named $PLUGINSDLR inside which you would get another FiddlerSetup.exe. 
Extract it again using 7zip to the root of the USB. Now you get the runtime
executable which is Fiddler.exe which can run from the USB stick itself. 

Windows Autopilot In-Depth Processes from Device Side - Part 3 11
How to run Fiddler from USB while still in OOBE? 

While in the initial pages of OOBE and if not connected to network, insert the
USB drive as prepared above. Press Shift+F10 to open the CMD console. 
You can use DISKPART > LIST VOL function to check the USB volume drive letter.
Then you can simply run Fiddler with command line <Vol_Drive_Letter>:\Fiddler.exe

Start the network capture and continue to OOBE. Fiddler will go to background.
Want to stop capture or bring it to front - use the CMD console to open 
Task Manager (taskmgr) to bring Fiddler on front. Simple isn't it! 

Windows Autopilot dependencies?

Before we start analyzing the network trace, it is important to understand that Wndows Autopilot relies on many other Microsoft online services to function. See the network requirements for Autopilot.

How Autopilot check is performed?

As we connect the device (Windows 10 build 18362.356) to a wireless network and proceed

Netsh ETL trace - Netmon Windows Parser - Windows Autopilot In-Depth Processes
Netsh ETL trace – Netmon Windows Parser – Windows Autopilot In-Depth Processes

Device starts connecting to the Windows Update channel fe2cr.update.microsoft.com to process the OOBE-ZDP updates (Windows Zero-Day-Patch updates).

Note: At this point, no security or feature updates are performed but only the critical driver updates and patches are processed as per Windows Update catalog as maintained in the cloud, commonly referred to as Windows Zero Day Patch. This is a mandate and user can’t opt-out of this. With 1903, Autopilot component updates are also processed in this OOBE ZDP update phase.

Essentially it uses the same Windows Update channel endpoint to reach out to login.live.com, a device authentication endpoint to check if it is Autopilot enabled or not. This activation check is essentially done against the device registration details (HWHash) in Autopilot Service (DDS). If positive, it gets the ZTDID with which

  • it connects to cs.dds.microsoft.com endpoint to download the Concierge profile (AutopilotConciergeFile.json)
  • it connects to ztd.dds.microsoft.com endpoint to download the Autopilot profile (AutopilotDDSZTDFile.json).
The AutopilotConciergeFile.json as introduced from Windows 1809, is behind 
the customization of the OOBE Language (Region) and Keyboard selection screens.
But this is only available for the self-deploy mode.

Windows Autopilot In-Depth Processes from Device Side - Part 3 12
For other autopilot deployment modes, the AutopilotDDSZTDFile.json is the one
which drives the OOBE.

NOTE: Due to issues with TPM attestation in Windows 1809, self-deploy mode support has been moved to Windows 1903 and is in preview state.

The event logs for the same are

Event ID 166 AutoPilotManager reported Internet is now available.

Event ID 164 AutoPilotManager determined Internet is available to attempt policy download.

Event ID 704 Autopilot downloader retrieved an empty profile for ConciergePolicyManager (applicable for 1903)

Event ID 703 Autopilot downloader retrieved an empty profile for DdsZtdPolicyManager (applicable for 1903)

Event ID 161 AutoPilotManager retrieve settings succeeded.

Event ID 153 AutoPilotManager reported the state changed from ProfileState_Unknown to ProfileState_Available.

Event ID 170 AutoPilotManager reported that Autopilot profile download is now complete

Event ID 163 AutoPilotManager determined download is not required and the device is already provisioned.  Clean or reset the device to change this.

Event IDs 101, 103 and 109 are the events of AutopilotManager retrieving the settings from the profile to drive the OOBE. 

As I mentioned above, with 1809 and above, if autopilot is processed and you are at the custom Azure sign-in page and haven't signed-in yet, a restart will result the autopilot profile present to be cleared and there will be attempt to download profile again in the subsequent device start. The event (this is from 1903 though) for the same would be 

Event ID 705 Autopilot downloader cleared the local profile for DdsZtdPolicyManager

We will also see the device connecting to licensing.mp.microsoft.com which is a Windows Activation endpoint and a lot of traffic to oscp.digicert.com endpoint which is as you can understand, for the SSL cert checks.

When the device is doing the above, you get the below screen.

OOBE-ZDP update check and Autopilot Activation - Windows Autopilot In-Depth Processes
OOBE-ZDP update check and Autopilot Activation – Windows Autopilot In-Depth Processes

How to confirm if device is doing the Autopilot flow?

As soon as the OOBE ZDP updates are completed, the device will restart to implement the device name change, if you have used a custom Device naming convention in your Autopilot profile. (This restart is an indication that the device has picked up Autopilot profile)

Else OOBE will skip the rest of the normal OOBE flow (EULA) and load the CloudDomainJoin webapp https://login.microsoftonline.com/WebApp/CloudDomainJoin/10 HTTP/1.1

If device has picked up the Autopilot profile and custom branding is configured in Azure, CloudExperienceHost process will render the custom Azure sign-in page. (This custom branded Azure sign-in page confirms the device has successfully picked up the Autopilot profile)

Simultaneously, you can see in network trace that it reaches out to
https://login.microsoftonline.com/common/.well-known/openid-configuration
HTTP/1.1 
to prefetch the auth endpoints by retrieving the OpenID configuration. 

AutopilotManager already has the tenant details based on which it calls the
CloudDomainJoin webapp. In normal scenario, the OpenID config is retrieved 
as part of home-realm discovery, post user enters the UPN and clicks on next.
Custom branded Azure Sign-in page - confirms Autopilot flow -  Windows Autopilot In-Depth Processes
Custom branded Azure Sign-in page – confirms Autopilot flowWindows Autopilot In-Depth Processes

If Autopilot check is returned false, device starts the consumer OOBE flow and end user is presented with the EULA screen followed by the default Sign-in with Microsoft Azure sign-in page instead.

Default Cloud Sign-in Page
Sign-in with Microsoft – Not Autopilot

In such case, you need to check the autopilot profile assignment status and device membership. Post checking and verification, if you are running Windows 10 1809, you can just restart at this point which will cause the AutopilotManager to re-download the profile and start again.

Does the custom branded Sign-in page really confirms autopilot provisioning?

For a user-driven normal autopilot deployement, if you have deleted the pre-created Azure AD object, the device will still show you the custom branded sign-in page but provisioning will resort to the normal OOBE AAD join flow. I have this mentioned in my previous Autopilot post here.

The explanation – I regsitered a VM with serial number 2012-7193-2759-5095-3412-1583-38 and post DDS registration, deleted the associated Azure AD object. As such the device properties under Windows Autopilot device shows as below

Windows Autopilot In-Depth Processes from Device Side - Part 3 13
Windows Autopilot – Have you deleted the associated Azure AD object?

As device gets connected to network, it reaches out to Autopilot service to check provisioning status. The query response will be true as the device is regsitered with DDS and there is a profile assigned as well. Thus it gets the profile downloaded to drive the OOBE and pre-negotiate to render the custom sign-in page.

Windows Autopilot In-Depth Processes from Device Side - Part 3 14
Windows Autopilot – Still getting the custom sign-in page though associated Azure AD object is deleted?

As the user performs sign-in, it reaches out to Azure DRS with the join request. It is at this time that Azure DRS will fail to find a match. But since this is a user driven flow, Azure DRS will create a new device object to continue the join.

The device provisioning will conitnue with ESP taking over and there will be a restart post ESP 2nd stage – Device setup. As the device comes back from restart, it will come up with the Privacy and other consumer OOBE flow screens before continuing with the ESP last stage – Account setup.

For Self-Deploy and WhiteGlove, deleting the associated Azure AD object will result in device provisioning failure. This is a security mechanism implemented in Azure DRS for non-user based device provisioning.

Only if the device succesfully completes the provisioning, you will get the Event ID 303 in the Autopilot events.

Windows Autopilot - Event ID 303 - Success
Windows Autopilot – Event ID 303 – Success

Want to validate the profile as being used by the device while still in OOBE?

You are just in luck as you can use this script.

#Get Windows Version
$WinVersion = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows
NT\CurrentVersion" -Name ReleaseId).ReleaseId
Write-Host ""
Write-Host "WindowsVersion"= $WinVersion
if ($WinVersion -eq '1803' -OR $WinVersion -eq '1809')
{ 
Write-Host ""
Write-Host "AutoPilot Registry Entries"
Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Provisioning\Diagnostics\AutoPilot'
#Show AutoPilot events
Write-Host "AutoPilot Event Logs"
Write-Host ""
Get-WinEvent -MaxEvents 10 -LogName 'Microsoft-Windows-Provisioning-Diagnostics-Provider/AutoPilot'
}
elseif ($WinVersion -eq '1903')
{
Write-Host ""
Write-Host "AutoPilot Registry Entries"
Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Provisioning\Diagnostics\AutoPilot'
#Show AutoPilot events
Write-Host "AutoPilot Event Logs"
Write-Host ""
Get-WinEvent -MaxEvents 10 -LogName 'Microsoft-Windows-ModernDeployment-Diagnostics-Provider/AutoPilot'
} 

Save it as .ps1 script to a USB drive and insert it to the device when you are still in the OOBE cloud sign-in screen. Open the CMD console (Shift + F10) and start PowerShell (powershell.exe). You can’t change directory to point to the USB drive here in OOBE so that way to run the script is PS C:Windows\system32> E:\.\Autopilotcheck.ps1 where E:\ is the USB drive letter. (Make sure to enable running script is allowed if you get an error using Set-ExecutionPolicy)

Script Output - Autopilot profile check from OOBE - Windows Autopilot In-Depth Processes
Autopilot profile check from OOBE – Windows Autopilot In-Depth Processes

What is CloudAssignedOobeConfig?

As you can see the value 28 as shown in the snap, it is actually a bitmap value which translates to SkipExpressSettings (4) + SkipOemRegistration (8) + SkipEula (16) = 28 as configured in my autopilot profile.

Bit values as can be possible
SkipCortanaOptIn = 1
OobeUserNotLocalAdmin = 2
SkipExpressSettings = 4
SkipOemRegistration = 8
SkipEula = 16  

With the Azure sign-in page displayed, the role and scope of Windows Autopilot is over.

As user enters credentials to authenticate, the provisioning is taken over by the Azure AD join mechanism which is covered here in this Microsoft Technet blog post (original credit Jairo Cadena). The device provisioning is tracked by ESP

ESP page - ESP tracking the device provisioning -  Windows Autopilot In-Depth Processes
ESP tracking the device provisioning – Windows Autopilot In-Depth Processes

As the device provisioning completes, ESP gives way to what Microsoft calls the First Sign-in Animation (FSIA) screen.

  • Windows Autopilot In-Depth Processes from Device Side - Part 3 15
  • Windows Autopilot In-Depth Processes from Device Side - Part 3 16

This is the time when Winlogon process is initiated for the original user account. If the tenant is a managed tenant, user is not presented with the Winlogon UI as it uses the buffered credentials from the CloudDomainJoin process. If it is a federated tenant (or in case of Hybrid Azure AD join) user is presented with the Winlogon UI for login.

If Hello for Business is enabled (or required), user is presented with the
helloEnrollmentPage webapp.

Event ID 358 under User Device Registration

Windows Hello for Business provisioning will be launched. 
 Device is AAD joined ( AADJ or DJ++ ): Yes 
 User has logged on with AAD credentials: Yes 
 Windows Hello for Business policy is enabled: Yes 
 Windows Hello for Business post-logon provisioning is enabled: Yes 
 Local computer meets Windows hello for business hardware requirements: Yes 
 User is not connected to the machine via Remote Desktop: Yes 
 User certificate for on premise auth policy is enabled: No 

As user completes the Hello setup, Winlogon calls Userinit process to prepare the User environment for the 1st time, which starts the Explorer process and gives the end user the Desktop.

End Result - Windows Autopilot In-Depth Processes
End Result – Windows Autopilot In-Depth Processes

Log and events check

Autopilot Profile Path:

For version till 1809, AutoPilotManager saves configuration file to path:
C:\Windows\Provisioning\AutoPilot\AutoPilotConfigurationFile.json 

For version 1903 and above, Autopilot downloader saves the new profile to
C:\Windows\ServiceState\Autopilot\<config file name>

With 1903, there are two config files now - 
AutopilotConciergeFile.json and AutopilotDDSZTDFile.json 

Though for existing device scenario, profile location remains the same.

Registry Path:

HKLM\SOFTWARE\Microsoft\Provisioning\Diagnostics\AutoPilot

Windows 10 1809 - Autopilot regsitry -  Windows Autopilot In-Depth Processes
Windows 10 1809 – Autopilot regsitry – Windows Autopilot In-Depth Processes
Windows 10 1903 - Autopilot regsitry - Windows Autopilot In-Depth Processes
Windows 10 1903 – Autopilot regsitry – Windows Autopilot In-Depth Processes

Noticed the newly added Autopilot related keys. Well 1903 has few more surprises for you.

Event Viewer:

For Windows 10 version till 1809: Application and Services Logs –> Microsoft –> Windows –> Provisioning-Diagnostics-Provider –> AutoPilot

Windows Autopilot In-Depth Processes  - Autopilot Event Logs
Windows Autopilot In-Depth Processes – Autopilot Event Logs

For Windows 10 version 1903 and above: Application and Services Logs –> Microsoft –> Windows –> ModernDeployment-Diagnostics-Provider –> AutoPilot

Windows Autopilot In-Depth Processes  - Autopilot Event Logs 2
Windows Autopilot In-Depth Processes – Autopilot Event Logs 2
Autopilot Events Functions
==========================

AutopilotGetPolicyStringByName function is to retrieve string values 
like CloudAssignedTenantDomain from the loaded profile.

AutoPilotGetPolicyDwordByNamefunction is to retrieve integer values 
like CloudAssignedDomainJoinMethod from the loaded profile.
 
AutoPilotRetrieveSettings function is to retrieve the OOBE bitmap 
value CloudAssignedOobeConfig from the profile. 

AutoPilotGetOobeSettingsOverride function shows if AutopilotManager succeeded 
in overriding the OOBE with the profile retrieved values 

Want to generate complete log set for review or to be sent to MS support?

Open elevated CMD and from C:\Windows\System32 run MdmDiagnosticsTool.exe -area Autopilot -cab c:\autopilotlogs.zip

MDMDiagnosticTool Autopilot log collection -  Windows Autopilot In-Depth Processes
MDMDiagnosticTool Autopilot log collection – Windows Autopilot In-Depth Processes

This is nearly equivalent to the below GUI log collection method which gives you a CAB file at C:\Users\Public\Documents\MDMDiagnostics, but above CMD method will give you log set specific to Autopilot area.

Export Autopilot Logs  -  Windows Autopilot In-Depth Processes
Export Autopilot Logs – Windows Autopilot In-Depth Processes

Both the CMD and GUI method uses the registry path HKLM\Software\Microsoft\MdmDiagnostics to know what to collect

MDMDiagnostics Registry -  Windows Autopilot In-Depth Processes
MDMDiagnostics Registry – Windows Autopilot In-Depth Processes

The resulting CAB/ZIP file contains all the data that you would need for analysis

Diagnostic generated logs -  Windows Autopilot In-Depth Processes
MDMDiagnostic generated logs – Windows Autopilot In-Depth Processes

Want to know what information you would get from each of these. Read this excellent blog post from Vimal Das.

Trying out Autopilot for existing device flow with Windows 10 v1903

Though this post does not covers Autopilot for existing device, still adding this up as you might find it usefull.

If you are trying Win 10 1903 using the default task sequence template from Config Manager for Autopilot for existing device, there is a good chance that you have encountered the issue as posted in this blog of Michael Niehaus.

Due to a change in behavior of Autopilot from 1903, the process will fail as 
the last step of the task sequencePrepare Windows for Captureis
essentiallysysprep /generalize /oobe which deletes the Autopilot profile
as copied to C:\Windows\Provisioning\Autopilotvia theApply Windows Autopilot configurationstep.

The suggested workaround is to delete the generalize step from task sequence 
and add asysprep /oobeinstead for a successful deployement.

This made me think, if 1809 was working fine with the Generalize pass, what has changed with 1903 which led me to this file path

C:\Windows\System32\Sysprep\ActionFiles\Generalize.xml

The Generalize.xml from a 1809 image does not contains the below lines which the same from a 1903 image contains, justifying the workaround as suggested…

fileActions
deleteDirectory path="$(runtime.windows)\Provisioning\Autopilot"
deleteDirectory path="$(runtime.windows)\ServiceState\Autopilot"
registryActions
deleteKey
path="HKEY_LOCAL_MACHINE\Software\Microsoft\Provisioning\AutopilotPolicy"
deleteKey path="HKEY_LOCAL_MACHINE\Software\Microsoft\Provisioning\Diagnostics\Autopilot"

To Be Continued….

In my next post, I will be highlighting the WhiteGlove process as introduced in Autopilot. Till then, read something everyday, learn something everyday!

Resources

LEAVE A REPLY

Please enter your comment!
Please enter your name here

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