A new starter's laptop finishes provisioning. It reaches the desktop, it is Microsoft Entra joined, and it is enrolled in Intune. But two of the six applications you expected are missing. So you do what you have done for years. You open an elevated PowerShell prompt and you read the Autopilot registry keys.
They are empty. The tenant domain value is blank. The value that means "this device is not registered with Windows Autopilot" is set to 1. The Enrollment Status Page tracking hive does not exist at all. The Autopilot event log has warnings in it and no profile events. Every diagnostic you trust is telling you the same thing: this device was never provisioned by Autopilot.
And yet it provisioned perfectly. It went through Windows Autopilot device preparation, and device preparation writes none of those things.
Windows Autopilot device preparation is a re-architecture, not a new interface over the old flow. It assigns a policy to a user group instead of a deployment profile to a registered device, it requires that the device is not registered as an Autopilot device, and Microsoft documents that it does not use the Enrollment Status Page. That combination means the two client-side surfaces a decade of community diagnostics read - the cached Autopilot profile under Provisioning\Diagnostics\Autopilot and the ESP tracking tree under Windows\Autopilot\EnrollmentStatusTracking - are legitimately blank or absent on a healthy device preparation deployment. Microsoft documents no client-side registry or event log replacement for them, because the authoritative status now lives in the Intune deployment report. Rewrite your detection logic to return three states, not two.
The problem: diagnostics that report failure on a healthy device
Autopilot troubleshooting has a well-worn muscle memory. You press Shift+F10 during the out-of-box experience, or you open an elevated prompt after the fact, and you check three things in order.
First, did the device get an Autopilot profile? You read the cached profile values that Microsoft documents under the Provisioning hive. Second, did the Enrollment Status Page run, and what did it wait for? You read the tracking hive that the Enrollment Status Page populates. Third, what does the Autopilot event log say? You open Event Viewer and walk down to the Autopilot channel.
Every published community script, every internal runbook, and every support escalation template in this space is built on those three surfaces. They are documented by Microsoft, they are stable, and for classic Windows Autopilot they are correct.
Run the same three checks against a device provisioned by Windows Autopilot device preparation and you get this.
Read literally, that output says the device is not registered with Autopilot, never received a profile, and never ran an Enrollment Status Page. Every one of those readings is true. None of them means the deployment failed.
This is the most expensive misdiagnosis available in Autopilot device preparation today. An engineer sees blank profile values, concludes the provisioning never happened, wipes the device, and reruns it. The rebuild produces exactly the same blank values. Now there is a second ticket about a looping Autopilot failure that was never an Autopilot failure at all.
DevicePreparation. That subkey has nothing to do with Windows Autopilot device preparation. It is the ESP phase that waits for policy providers such as the Intune Management Extension before the device setup phase starts. Search your codebase for "device preparation" and you will hit both concepts. Confusing them sends you hunting for an ESP hive that device preparation deliberately never creates.Why it happens: a different assignment model and no Enrollment Status Page
Microsoft is blunt about this in the device preparation FAQ. Device preparation is described as a re-architecture of Windows Autopilot, where the experience for original equipment manufacturers, administrators and users is similar but the underlying architecture is different. Two of those architectural differences directly destroy the classic client-side footprint.
Difference one: nothing is assigned to the device, so nothing is cached on the device
In classic Windows Autopilot the hardware is registered with the Windows Autopilot deployment service first. A deployment profile is assigned to that registered device object, usually through a dynamic device group. When the device boots and reaches a network, it contacts the deployment service and downloads the profile. Microsoft documents that the downloaded profile settings are stored in the device's registry, and lists the values you can read there.
That download is the reason the registry keys exist. The keys are a local cache of a service-assigned artefact.
Device preparation removes the artefact. The device preparation policy is assigned to a user group, not to a device. Microsoft states plainly that devices do not need to be pre-staged, because the policy is deployed to a user group and the deployment begins once a user in that group signs in during the out-of-box experience. There is no hardware hash upload, no device registration, and no per-device profile for the client to fetch and cache.
The device group in a device preparation policy works in the opposite direction from a classic dynamic group. It is an assigned Microsoft Entra security group, and the device is added to it during enrollment. Microsoft calls this Enrollment Time Grouping. The point is that Intune knows the group membership before the device is grouped, so apps and policies deploy immediately rather than waiting for a dynamic group query to catch up.
IsAutopilotDisabled = 1 is exactly that: the device is not registered with Windows Autopilot. The value is not reporting a fault. It is reporting a prerequisite being met.Difference two: no Enrollment Status Page, so no ESP tracking hive
The second surface is even more clear cut. The Enrollment Status Page tracking hive is not written by Autopilot. It is written by the Enrollment Status Page.
Microsoft documents that the EnrollmentStatusTracking configuration service provider (CSP) was added in Windows 10, version 1903. It is used by Intune's agents, such as SideCar, to configure the Enrollment Status Page to block device use until required Win32 applications are installed. The CSP writes its state into the registry, and the Intune support documentation names the hive and walks its subkeys.
Windows Autopilot device preparation does not use the Enrollment Status Page. That is stated in three separate Microsoft articles: the device preparation FAQ, the device preparation troubleshooting FAQ, and the classic Autopilot troubleshooting FAQ. The troubleshooting FAQ even inverts the test for you. If the Enrollment Status Page appears during what you believe is a device preparation deployment, then the device is not running a device preparation deployment, and you should check whether it is Autopilot-registered or has an Autopilot profile assigned.
Instead of the ESP, the user sees a Setting up for work or school window with a round progress bar, followed by a completion page telling them setup is finished. No Enrollment Status Page means no EnrollmentStatusTracking CSP activity for the flow, which means no hive for your script to read.
Where the state actually lives now
The state moved to the service. Device preparation ships near real-time reporting: a per-device deployment report carrying a deployment status, a deployment phase, a policy name and version, per-application status and per-script status. Diagnostic logs are collected automatically when a deployment fails and can be downloaded from the report.
That is a genuine improvement in observability. It is also a hard break in tooling, because a report in the Intune admin center is not something a detection script running in SYSTEM context on the device can read.
Is there a documented client-side surface for device preparation?
No. This is worth stating plainly rather than dressing up.
Across the device preparation overview, requirements, FAQ, troubleshooting FAQ, known issues, what's new and reporting articles, Microsoft documents no registry path and no event log channel for Windows Autopilot device preparation. The documented troubleshooting surfaces are the deployment report, the automatically collected diagnostics, and the end-user Export logs option during the out-of-box experience. There is no published equivalent of the classic profile cache.
Community researchers have reverse-engineered undocumented values under the Provisioning\AutopilotSettings area of the registry, and that work is genuinely useful for understanding the flow. It is not a supported contract. An undocumented value can change name, meaning or existence in any cumulative update without a release note, and a confidently wrong registry path in a detection script produces confidently wrong remediation at scale. Treat those findings as reading material, not as an interface.
How to verify: read the classic surfaces and interpret their absence
The technique changes from "read the key" to "read the key and state explicitly whether it was present". A script that returns nothing tells you nothing. A script that returns "this documented value exists and is blank" tells you which flow ran.
Classic surface one: the cached Autopilot profile
Microsoft documents that Windows Autopilot profile settings received from the deployment service are stored under this key.
| Value | What Microsoft documents | On a device preparation device |
|---|---|---|
CloudAssignedTenantDomain | The Microsoft Entra tenant the device is registered with. Blank if the device is not registered with Windows Autopilot. | Expected blank - the device must not be Autopilot-registered |
CloudAssignedTenantId | The tenant GUID matching the domain above. Blank if the device is not registered with Windows Autopilot. | Expected blank |
IsAutopilotDisabled | Set to 1 when the device is not registered with Windows Autopilot, or when the profile could not be downloaded. | Expected 1, and it is not an error |
AadTenantId | The tenant GUID the signed-in user belongs to. A mismatch against registration produces an error for the user. | May be present from sign-in, but proves nothing about the flow |
TenantMatched | 1 if the user's tenant matches the tenant the device was registered with. 0 shows the user an error and forces a restart. | Meaningless without a registration to match |
CloudAssignedOobeConfig | Bitmap of configured Autopilot OOBE settings. SkipCortanaOptIn = 1, OobeUserNotLocalAdmin = 2, SkipExpressSettings = 4, SkipOemRegistration = 8, SkipEula = 16. | Not written - device preparation OOBE settings are not this profile |
Read that table the right way round and the diagnostic value flips. A blank CloudAssignedTenantDomain plus IsAutopilotDisabled = 1 on an Entra-joined, Intune-enrolled Windows 11 device is a positive indicator that classic Autopilot did not provision it. Combined with a device that clearly did provision, it is consistent with device preparation.
Classic surface two: the Enrollment Status Page tracking hive
This is the surface that is simply not there. Microsoft documents the hive and its structure for ESP troubleshooting, so its absence is meaningful rather than mysterious.
| Subkey or value | What it records | Documented values |
|---|---|---|
Device | Last step of the ESP device preparation phase, plus Win32 app deployment in the device setup phase | Container |
Device\DevicePreparation\PolicyProviders\<Provider>\InstallationState | Install state of a registered ESP policy provider, for example the Intune Management Extension (SideCar) | 1 NotInstalled, 2 NotRequired, 3 Completed, 4 Error |
Device\DevicePreparation\PolicyProviders\<Provider>\LastError | The HRESULT the provider set. ESP reads it only when InstallationState is 4 | Integer HRESULT |
Device\DevicePreparation\PolicyProviders\<Provider>\Timeout | Minutes the provider may run before ESP shows an error | Integer. Default 15 minutes |
Device\DevicePreparation\PolicyProviders\<Provider>\TrackedResourceTypes\Apps | Whether the provider is registered for app provisioning | Boolean. Default false |
Device\Setup\Apps\PolicyProviders\<Provider>\TrackingPoliciesCreated | Whether the provider created the tracking policies ESP needs | Boolean. Default false |
Device\Setup\Apps\Tracking\<Provider>\<AppName>\InstallationState | Per-app install state during the device setup phase | 1 NotInstalled, 2 InProgress, 3 Completed, 4 Error |
Device\Setup\Apps\Tracking\<Provider>\<AppName>\RebootRequired | Whether the app install requires ESP to reboot | 1 NotRequired, 2 SoftReboot, 3 HardReboot |
Setup\HasProvisioningCompleted | Set by ESP when it finishes, so providers know to stop reporting | Boolean |
ESPTrackingInfo\Diagnostics\Expected* | Timestamped status snapshots for MSI app packages, network profiles, certificate profiles, policies and modern app packages | Per-item subkeys named by timestamp |
<User_SID> | Account setup phase tracking. Created only if the device setup phase completed | Container |
On a device preparation deployment there is no Enrollment Status Page, so there is no reason for any of this to exist. Absence of the hive is a strong positive signal, but only if your script distinguishes three outcomes: hive absent, hive present but empty, and query failed.
Classic surface three: the Autopilot event log
Microsoft documents that Windows Autopilot writes to the event log, and gives the Event Viewer location as Applications and Services Logs › Microsoft › Windows › ModernDeployment-Diagnostics-Provider › Autopilot. Enumerate that channel rather than hard-coding a name string, so your script survives a rename.
| Event ID | Type and documented message | What it tells you |
|---|---|---|
| 100 | Warning - Autopilot policy [name] not found | Usually transient while waiting for a profile download. Persistent on a device that has no profile to get. |
| 101 | Info - AutopilotGetPolicyDwordByName succeeded | Numeric OOBE settings being retrieved from the profile |
| 103 | Info - AutopilotGetPolicyStringByName succeeded | String OOBE settings, such as the Microsoft Entra tenant name |
| 109 | Info - AutopilotGetOobeSettingsOverride succeeded | State-related OOBE settings being applied |
| 111 | Info - AutopilotRetrieveSettings succeeded | The profile settings controlling OOBE behaviour were retrieved |
| 153 | Info - AutopilotManager reported the state changed | Normally ProfileState_Unknown to ProfileState_Available. A profile was downloaded. |
| 160 | Info - AutopilotRetrieveSettings beginning acquisition | Profile download is starting |
| 161 | Info - AutopilotManager retrieve settings succeeded | The profile downloaded successfully |
| 163 | Info - Download is not required, device already provisioned | A profile is already cached. Sysprep /Generalize normally clears it. |
| 164 | Info - Internet is available to attempt policy download | The connectivity check passed |
| 171 | Error - Failed to set TPM identity confirmed | Trusted Platform Module attestation problem, needed for self-deploying mode |
| 172 | Error - Failed to set Autopilot profile as available | Typically follows event 171 |
| 807 | Error - ZtdDeviceIsNotRegistered | Hardware hash not uploaded, or no profile assigned |
| 809 | Error - ZtdDeviceHasNoAssignedProfile, assigned profile does not exist | The assigned profile was deleted without cleanup |
| 815 | Error - ZtdDeviceHasNoAssignedProfile, no profile and no tenant default | No profile is assigned to the device |
| 908 | Error - SerialNumberMismatch or ProductKeyIdMismatch | Recorded hardware does not match the physical device |
Notice what happens here. A device preparation device with no Autopilot registration can legitimately log 100, and can legitimately log 807 or 815 as the client asks for a profile that does not exist. Those are error-level events in a channel your runbook treats as authoritative. If your alerting pipeline scrapes this channel, device preparation will generate false failures at fleet scale.
The fourth surface: ESP settings under the enrollment key
One more classic surface is worth knowing, because it is the one people most often misquote. Intune support documentation locates the Enrollment Status Page settings received by the device here.
Note the path carefully. It is SOFTWARE\Microsoft\Enrollments, not SOFTWARE\Microsoft\Windows\CurrentVersion\Enrollments. The same documentation notes that when the device or user status page is skipped through the DMClient CSP, SkipDeviceStatusPage or SkipUserStatusPage is set to 0xffffffff under that key. Since device preparation never delivers ESP settings, this subkey will not carry them.
Putting the three-state test together
| Signal | Classic Windows Autopilot | Autopilot device preparation |
|---|---|---|
| Cached profile values populated | Yes. Tenant domain and tenant ID are set | No. Documented as blank when not Autopilot-registered |
IsAutopilotDisabled | 0 on a healthy registered device | 1, as a consequence of the prerequisite |
| ESP tracking hive | Present when an ESP profile applied | Absent. Device preparation does not use the ESP |
| Autopilot event channel | Profile lifecycle events including 111, 153 and 161 | May show 100, 807 or 815 with no profile events |
| Documented per-flow status surface | The Enrollment Status Page, plus the Windows 11 diagnostics page | The device preparation deployment report in Intune |
| Client-side status contract | Documented registry values and event IDs | None documented by Microsoft |
That honest third column is the deliverable. Your diagnostics were never wrong. They were answering a question about classic Autopilot on a device that did not run classic Autopilot.
The fix: move the source of truth to the service
There are three pieces of work. Point your people at the reports, teach your scripts to return three states, and stop alerting on the classic channel for device preparation fleets.
Step 1: read the device preparation deployment report
This is the documented source of truth for a device preparation deployment.
- Sign in to the Microsoft Intune admin center.
- On the Home screen, select Devices in the left hand pane.
- In the Devices | Overview screen, select Monitor.
- Under Report name, select Windows Autopilot device preparation deployments.
- In the Device enrollment - Autopilot deployments screen, read the per-device rows: Device name, Enrollment date, Deployment status, Phase, Serial number, Deployment time and UPN.
- Select a device name to open Device deployment details, which carries the Device, Apps and Scripts sections.
- For a failed deployment, download the automatically collected diagnostics from the Device tab.
The same report is reachable from a second path, added in August 2024: Devices › Device onboarding | Enrollment, then the Monitor tab.
The Phase column is the closest equivalent to the ESP phases you know. Microsoft documents three: Policy installation for initial setup and line-of-business app installation, Script installation for scripts, and App installation for Win32 and Microsoft Store apps. Application and script statuses are Installed, In progress, Skipped and Failed.
lgmsapeweu.blob.core.windows.net must not be blocked on your network. If you learned Autopilot troubleshooting on devices you could inspect weeks later, budget for a much shorter evidence window.Step 2: check the enrollment time grouping failures report
This report has no classic equivalent, and it covers the failure mode unique to device preparation. The device did not join the assigned device group, so apps and policies targeted at that group never applied.
- In the Microsoft Intune admin center, go to Devices.
- Select Monitor.
- Select Enrollment time grouping failures. The report shows failures only.
- Expect up to 20 minutes of latency before recent information appears.
- Confirm your role carries the
Microsoft.Intune/ManagedDevices/Readpermission, which is required to view it.
Microsoft recommends monitoring this report continuously, because a device that fails to join the group can have configuration changed or removed after enrollment. If group membership fails, verify that the Intune Provisioning Client service principal with AppID f1346770-5b25-470b-88bd-d5744ab7952c is still an owner of the device group, and that Microsoft Entra roles can be assigned to the group is set to No. In some tenants that service principal appears as Intune Autopilot ConfidentialClient. The AppID is what matters.
Step 3: review the policy settings that shape what you will see
- Sign in to the Microsoft Intune admin center and select Devices.
- Under By platform, select Windows.
- Under Device onboarding, select Enrollment.
- Under Windows Autopilot device preparation, select Device preparation policies.
- Open a policy and review Configuration settings. Under Out-of-box experience settings, check Minutes allowed before showing installation error. It applies to the whole deployment rather than to individual apps, and the accepted value is an integer between 15 and 720.
- Set Show link to diagnostics to Yes so a failing deployment offers the end user a log retrieval link.
- Note the Priority column on the policy list. Where several policies target one user, the smallest number wins.
Step 4: query the policies from Graph, read only
Device preparation policies surface in the Microsoft Graph beta endpoint for configuration policies, distinguished by the enrollment member of the deviceManagementConfigurationTechnologies enumeration. Microsoft's own enrollment time grouping documentation references the policy under that path when describing how to clear an enrollment time grouping target.
That second query is the decisive tenant-side check. Device preparation requires that the device is not registered as a Windows Autopilot device. If the serial number appears in windowsAutopilotDeviceIdentities, the classic profile wins, and you should expect classic behaviour including the Enrollment Status Page.
Step 5: rewrite the detection logic
Change every Autopilot detection script from a boolean to a tri-state. The three outcomes are evidence of classic Autopilot, evidence consistent with device preparation, and no evidence either way. That third state is the one that saves the reimage. Report the presence or absence of each documented surface separately, and never collapse "key missing" into "device unhealthy".
For the deep dive case, the documented log collection command still works and still produces the cab that the community diagnostics parser reads.
For self-deploying, pre-provisioning and other physical-device scenarios, Microsoft documents -area Autopilot;TPM instead. The cab's MDMDiagReport_RegistryDump.Reg file contains the MDM enrollment keys, Autopilot profile settings, policies and app install state. That is exactly the set you now want to read as three-state evidence.
Proof it worked: a three-state footprint report
The companion script reads the documented classic surfaces and reports each as present, blank or absent, then names the flow the evidence supports. It never writes, it never guesses at an undocumented device preparation key, and it refuses to report a clean result when a query fails.
Compare that with the same script on a classic Autopilot device, where surface one is populated, surface two exists and carries tracked apps, and surface three shows 111, 153 and 161. The two footprints are unmistakable once you print both the presence and the absence.
The script lives here:
References
Microsoft official documentation:
- Overview of Windows Autopilot device preparation - requirements, Enrollment Time Grouping, corporate identifiers
- Windows Autopilot device preparation FAQ - the re-architecture statement, no ESP, Entra join only, no pre-provisioning or self-deploying mode
- Windows Autopilot device preparation troubleshooting FAQ - documented troubleshooting surfaces and the Intune Provisioning Client requirement
- Windows Autopilot device preparation reporting and monitoring - the report, its columns and phases, and the 28 day cleanup
- Windows Autopilot device preparation requirements - software, networking, licensing, configuration and RBAC
- Windows Autopilot device preparation known issues
- What is new in Windows Autopilot device preparation - the enrollmentProfileName property, automatic mode, the app limit
- Create a Windows Autopilot device preparation policy - every configuration setting and the 15 to 720 minute range
- Windows Autopilot troubleshooting FAQ - the classic profile registry values and the Autopilot Event ID table
- Windows Autopilot Enrollment Status Page
- Troubleshoot the Enrollment Status Page (ESP) - the EnrollmentStatusTracking hive structure and the FirstSync key
- EnrollmentStatusTracking CSP - the node tree, installation states and the 15 minute default timeout
- Set up enrollment time grouping - the failures report, RBAC, and the Graph configuration policy path
- deviceManagementConfigurationTechnologies enum - the documented
enrollmentmember - List windowsAutopilotDeviceIdentities - checking whether a device is Autopilot-registered
Community deep dives, each fetched and confirmed on topic:
| Author | Article | Why it is worth reading |
|---|---|---|
| Rudy Ooms | Autopilot Device Preparation - Technical Flow - APv2 | Reverse-engineers the device preparation flow, including undocumented state values. Read it to understand the mechanism, not to build a supported check. |
| Rudy Ooms | Autopilot Device Preparation - Autopilot Version 2 - APv2 | Contrasts device preparation with classic Autopilot: no hardware hash, user targeting, corporate identifiers, enrollment time grouping. |
| MSEndpointMgr | Onboarding modern with Autopilot: Magic trick revealed | The best available walk-through of the classic Autopilot and ESP internals your existing scripts were written against. |
One closing point. The absence of a documented client-side surface for device preparation is not an oversight to work around with an undocumented registry read. It is a design decision. Status is a service concern now, and the report is the contract. Build your tooling against the contract, and use the classic keys for what they remain genuinely good at: proving, definitively, that classic Autopilot was not involved.
Download it from Imran76Awan/Windows-Autopilot-Scripts — no sign-in required. It is read-only: it reports and never changes a device or anything in Intune. Validate it in your own environment before relying on the output.