Let’s get into another deep-dive blog post about Windows Autopilot In-Depth Processes from Device Side – Part 3. I call it behind-the-scenes processes and data flows.
In my previous post, I discussed the functional blocks and concepts of Windows Autopilot from the perspective of IT Admin setup
In this post, I will discuss the workings of Windows Autopilot In-Depth from the device-side processes.
Related Posts
- Part 1 Windows Autopilot FAQ Clarifying the General Misconceptions
- Part 2 Windows Autopilot from the perspective of IT Admin setup
- Part 3 Windows Autopilot In-Depth Processes from Device Side (This Post)
- Part 4 Windows Autopilot WhiteGlove Provisioning Deep Dive (Coming Soon)
Know About Windows Configuration Passes
Before we start, I want to provide some insights on Windows Configuration Passes. People with an OSD background will already be familiar with this Windows Configuration.
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 of them.
- Windows PE
- OfflineServicing
- Generalize
- Specialize
- auditSystem
- auditUser
- oobeSystem
An answer file (unattend.xml) can be used to customize/automate the Windows Setup in one or any of these configuration passes.
Note: At the beginning of each phase, it checks the Answer file to see if any values are 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 does a Windows Setup go through?
Below is the schematic representation showing the configuration passes through which the Windows Setup process handles the OS installation (generalized).
Configuration pass -> WindowsPE
This is the pass we boot from install media and start the Windows Setup, which copies the OS Image to the local drive and prepares the system to boot from the local industry. When done, there is a restart.
Configuration pass -> OfflineServicing
Post-restart, Setup continues from the local drive and not boot media. During this time, it initializes the drivers and prepares the system to support Windows for the first 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 the OfflineServicing pass.
At this stage, the Kernel is initialized, and it launches the smss.exe, the first user-mode SYSTEM process. This process initializes the csrss.exe process, which initializes the Win32 subsystem to support the Windows environment.
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 calls 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…
But why are we discussing 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 OOB system 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="https://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>
Suppose Setup finds an unattend.xml to drive the oobeSystem pass, which happens mostly in the case of custom prepared images. In that case, the device will not trigger Autopilot provisioning even if it is assigned – the reason why a business-designed OS image is not suggested with Autopilot provisioning.
It won’t find a non-customized OS image or an OEM image and will continue with the default values, showing all the OOBE screens as required.
Windows Out-Of-Box-Experience…
The Out-Of-Box Experience (OOBE) is the first boot setup process, as Microsoft likes to call it.
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 the case of KIOSK deployment)
What is this default user 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 disabled 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 that usually do not require access to GUI for user interaction. But OOBE requires user interaction to work…
So what the 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 of running the OOBE and tags it to WinSta0, a 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
This account is deleted at the point when Setup has provisioned the existing user profile (usually post completion of the ESP 2nd stage – Device setup) and can continue by using it.
What is the difference between Windows 7 and Windows 8/8.1?
In Windows 7 and 8/8.1 (also called Windows downlevel), the OOBE setup used local pages and ran under SYSTEM, 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 theCloudExperienceHost
process, refer to 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 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 start from?
As the device gets connected to the network, the real things start. 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 the network. (If using a wired connection, this page is skipped by default, but Autopilot check was used to start to post the OOBE Network screen timeframe before the EULA screen was to be rendered). As the device connected to the network, the device initiated the autopilot check and downloaded the profile from the 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 a 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 until the machine connects to a network in OOBE.
Thus for Windows 10 1803 and above, if you are using a 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
The worker API essentially calls WinRT functions via CloudExperienceHost implemented in the autopilot.dll
Want to see the actual sequence of Activities 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), 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
Now add the Regions of Interest to the Graph Analysis view, and you can see the activity sequence as performed. As can be seen, the Autopilot process starts before the OOBE Welcome page is rendered.
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 the network?
To give a clearer picture, you would require a network capture to see the connections the device is making while it goes through the OOBE.
You can use the netsh trace and analyze with Netmon (windows parser). You can use Wireshark or any tool you like. I used 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. 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 Windows Autopilot relies on many other Microsoft online services to function. See the network requirements for Autopilot.
How is the Autopilot check performed?
As we connect the device (Windows 10 build 18362.356) to a wireless network and proceed
The device connects to the Windows Update channel fe2cr.update.microsoft.com to process the OOBE-ZDP updates (Windows Zero-Day-Patch updates).
Note: No security or feature updates are performed, but only the critical driver updates and patches are processed per the Windows Update catalog as maintained in the cloud, commonly referred to as Windows Zero-Day Patch. This is a mandate, and users 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 relates 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. 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 a 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, a Windows Activation endpoint, and a lot of traffic to the oscp.digicert.com endpoint, which you can understand for the SSL cert checks.
When the device is doing the above, you get the below screen.
How to confirm if the device is doing the Autopilot flow?
The device will restart as soon as the OOBE ZDP updates are completed 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 the Autopilot profile)
Else OOBE will skip the rest of the normal OOBE flow (EULA) and load the CloudDomainJoin
web app https://login.microsoftonline.com/WebApp/CloudDomainJoin/10 HTTP/1.1
If a device has picked up the Autopilot profile and custom branding is configured in Azure, the 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.
If the Autopilot check is returned false, the device starts the consumer OOBE flow, and the end-user is presented with the EULA screen followed by the default Sign-in with Microsoft Azure sign-in page instead.
In such a case, you need to check the autopilot profile assignment status and device membership.
After checking and verifying, if you are running Windows 10 1809, you can restart at this point, which will cause AutopilotManager to re-download the profile and start again.
Does the custom branded Sign-in page confirm autopilot provisioning?
For a user-driven normal autopilot deployment, the device will still show you the custom branded sign-in page if you have deleted the pre-created Azure AD object. Provisioning will resort to the normal OOBE AAD joining the flow. I mentioned this in my previous Autopilot post here.
The explanation: I registered a VM with a serial number 2012-7193-2759-5095-3412-1583-38 and, post DDS registration, deleted the associated Azure AD object.
The device properties under the Windows Autopilot device are shown below.
As the device connects to the network, it reaches out to the Autopilot service to check the provisioning status. The query response will be true as the device is registered with DDS, and a profile is also assigned.
Thus it gets the profile downloaded to drive the OOBE and pre-negotiate to render the custom sign-in page.
As the user performs sign-in, it reaches out to Azure DRS with the join request.
At this time, Azure DRS will fail to find a match. However, Azure DRS will create a new device object to continue the join since this is a user-driven flow.
Device provisioning will continue with ESP taking over, and there will be a restart post-ESP 2nd stage—Device setup.
As the device returns from the restart, it will come up with the Privacy and other consumer OOBE flow screens before continuing with the ESP the last stage – Account setup.
For Self-Deploy and WhiteGlove, deleting the associated Azure AD object will fail device provisioning. This is a security mechanism implemented in Azure DRS for non-user-based device provisioning.
If the device completes the provisioning, you will get the Event ID 303 in the Autopilot events.
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 a .ps1 script to a USB drive and insert it into the device while still in the OOBE cloud sign-in screen. Open the CMD console (Shift + F10) and start PowerShell (powershell.exe).
You can’t change the 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)
What is CloudAssignedOobeConfig?
As you can see, the value 28, as shown in the snap, is 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 are over.
As the user enters credentials to authenticate, the Azure AD join mechanism takes over the provisioning, which is covered here in this Microsoft Technet blog post (original credit Jairo Cadena). ESP tracks the device provisioning.
As the device provisioning completes, ESP gives way to what Microsoft calls the First Sign-in Animation (FSIA) screen.
This is when the Winlogon process is initiated for the original user account.
If the tenant is managed, the 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 the case of Hybrid Azure AD join), the 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 the user completes the Hello setup, Winlogon calls the Userinit process to prepare the User environment for the 1st time, starting the Explorer process and giving the end-user the Desktop.
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
Noticed the newly added Autopilot-related keys. Well, 1903 has a few more surprises for you.
Event Viewer:
For Windows 10 version till 1809: Application and Services Logs –> Microsoft –> Windows –> Provisioning-Diagnostics-Provider –> AutoPilot
For Windows 10 version 1903 and above: Application and Services Logs –> Microsoft –> Windows –> ModernDeployment-Diagnostics-Provider –> AutoPilot
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
Do you want to generate a complete log set for review or be sent to MS support?
Open elevated CMD and from C:\Windows\System32
the run. MdmDiagnosticsTool.exe -area Autopilot -cab c:\autopilotlogs.zip
This is nearly equivalent to the below GUI log collection method, which gives you a CAB file at C:\Users\Public\Documents\MDMDiagnosticsHowever, the above CMD method will provide you with a log set specific to the Autopilot area.
Both the CMD and GUI method uses the registry path HKLM\Software\Microsoft\MdmDiagnostics
to know what to collect
The resulting CAB/ZIP file contains all the data you would need for analysis.
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 cover Autopilot for an existing device, still adding this up as you might find it useful.
Suppose you try Win 10 1903 using the default task sequence template from Config Manager for Autopilot for the existing devices. In that case, there is a good chance that you have encountered the issue as posted in this blog by 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 Capture
is essentiallysysprep /generalize /oobe
which deletes the Autopilot profile as copied toC:\Windows\Provisioning\Autopilot
via theApply Windows Autopilot configuration
step. The suggested workaround is to delete thegeneralize
step from task sequence and add asysprep /oobe
instead for a successful deployement.
This made me wonder if 1809 was working fine with the Generalize pass and what had changed with 1903, which led me to this file path.
C:\Windows\System32\Sysprep\ActionFiles\Generalize.xml
The Generalize.xml from an 1809 image does not contain 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……Windows Autopilot In-depth Processes
In my next post, I will highlight the WhiteGlove process introduced in Autopilot. Until then, read and learn something every day!
Resources
- Windows Autopilot from the perspective of IT Admin setup Part 2
- Windows Autopilot FAQ Clarifying the General Misconceptions Part 1
- https://www.anoopcnair.com/mdm-diagnostics-tool-windows-autopilot/
- Repurpose Existing Devices to Windows Autopilot – SCCM or MDT?
We are on WhatsApp. To get the latest step-by-step guides and news updates, Join our Channel. Click here –HTMD WhatsApp.
Author
Joymalya Basu Roy is an experienced IT service professional with almost 5 years of experience working with Microsft Intune. He is currently working as a Senior Consultant – Architect with Atos India. He is an ex-MSFT, where he worked as a Premiere Support Engineer for Microsoft Intune. He was also associated with Wipro and TCS in the early stages of his career. He was awarded the Microsoft MVP award for Enterprise Mobility in 2021. You can find all his latest posts on his own blog site MDM Tech Space at https://joymalya.com
Thank you, this is very detailed and helpful. The comment:
“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”
Is only partly true. You can still have an unattend.xml if you remove the section “Settings pass=oobeSystem”. In my case, I am using the unattend.xml to upload the hardware hash to Intune. I was able to keep unattened.xml, but remove that section and it worked.
Hi Lance,
Yes that’s true. You can have an unattend.xml but it cannot have the Settings pass=oobeSystem.
That was the purpose of mentioninig this, because if you are providing an answer file, you can for the other config passes but not for oobeSystem config pass.
Hi there, thanks for this incredibly useful blog. I have an issue I’m trying to deal with — devices that go through Autopilot which are then logged onto by the final end user don’t ever show up as a user’s device in Azure AD (Normally I would see it under Intune -> Users – All Users -> John Doe -> Devices). We base our Conditional Access Control on the devices that a user has assigned to them. Is there a reason the autopiloted device doesn’t show up under the Devices screen?
Thanks, this is really informative to a relative Azure Noob like me! A question about this comment though:
“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.”
So, if we apply a standard MS W10 2004 image to a device, and have it plugged into the network sat at the OOBE Region screen while we harvest the HWID – it has already checked that there is no autopilot profile.
We then power the machine off, and upload the HWID to Intune. When the machine is powered back on, it should check again and /not/ return “Autopilotmanager determined download is not required….” – is this correct? Also, is there any official MS documentation for this – as I have a customer who thinks this is their problem!
Thanks!
Mike.
Hi, is there any chance we can expect the ‘white-glove deep-dive’ soon?
Hello! We are going through setups right now and seeing the defaultuser0 account on the device ones it’s fully setup and it isn’t being removed when the device is fully provisioned and actual user is logged in.
Do you have any thoughts on this? It’s messing with password compliance policies based on our testing.