Autopilot v2 Troubleshooting Without Clicking Through Two Portals: A Microsoft Graph Approach

Autopilot device preparation rarely fails loudly. The device joins Entra, lands on the desktop, and the apps you expected simply never show up. This article walks through a read-only PowerShell script that checks every tenant-side link of the Autopilot v2 chain in one run, and explains how to read and act on its report.

01 – Why Autopilot v2 fails silently

Windows Autopilot device preparation (DPP, often called Autopilot v2) was re-architected around one key idea: no hardware hash registration. The user signs in during OOBE, the device joins Microsoft Entra ID, enrolls in Intune, and the Intune Provisioning Client service principal adds the device to a pre-defined security group. Apps and scripts assigned as Required to that group are then delivered in a serialized way before the user reaches the desktop.

That design removes the hash import burden, but it moves the complexity elsewhere. A successful deployment depends on a dozen independent objects configured in two different portals: Entra ID and Intune. When one of them is wrong, DPP does not always throw a clear error. It may just skip the device preparation phase entirely, and the user gets a bare desktop.

  • Silent skip : The user is not targeted by any DPP policy. OOBE completes, but no device preparation page ever appears.
  • Empty group : The Intune Provisioning Client is not owner of the device group, so the device is never added and nothing installs.
  • Wrong precedence : A leftover Autopilot v1 registration takes precedence and the device follows the classic profile instead.

Troubleshooting these cases by clicking through the portals is slow and error-prone, especially in tenants that run v1 and v2 side by side during a migration. The script presented here turns that checklist into a single, repeatable, read-only audit.

02 – The dependency chain the script audits

Every DPP deployment walks the same path. Each step depends on tenant-side objects, and each object maps to one section of the script.

03 – Read-only by design

A diagnostic tool that runs in production must be safe to hand to a level 2 technician or to run during an incident. The script enforces that at two independent levels.

  • Level 1: the token
    • Only *.Read.All delegated scopes are requested at connection time. Even if the code were modified, a token without write scopes cannot change anything in the tenant. If an existing Graph session already carries ReadWrite scopes, the script warns you and recommends reconnecting.
  • Level 2: the code
    • Every Graph request goes through a single function, Get-Graph, which only issues GET calls, follows @odata.nextLink paging, and returns an { Ok; Data; Error } object so that “empty result” and “access denied” are never confused.

04 – Running the diagnostic

Parameters

ParameterEffect
-UserPrincipalNameEnables user checks: licenses, transitive groups, MDM scope, join permission, Entra and Intune quotas, CA evaluation, policy targeting, enrollment failure events.
-SerialNumberEnables device checks: Autopilot v1 conflict, corporate identifier, Intune and Entra objects, OS build, DPP group membership.
-PolicyNameWildcard filter on DPP policy names, for example "DPP*".
-DeviceGroupIdOne or more group objectIds to audit in addition to the groups owned by the Intune Provisioning Client.
-TenantIdTarget tenant, useful for MSPs and multi-tenant operators.
-LookbackDaysWindow for enrollment failure events, 1 to 90 days (default 14).
-ExportPathLocal folder for the HTML and CSV report.
-PassThruAlso returns the results as objects for pipeline processing.

Three ways to use it

# 1. Tenant health check (no user, no device): prerequisites, CA, policies, groups, apps
.\Test-AutopilotDevicePrep-EN.ps1 -ExportPath C:\Temp\DPP

# 2. Incident on one device: full chain for a user and a serial number
.\Test-AutopilotDevicePrep-EN.ps1 -UserPrincipalName jdoe@contoso.org -SerialNumber 5CG1234XYZ -ExportPath C:\Temp\DPP

# 3. Automation: keep only blocking items and feed them to another tool
$r = .\Test-AutopilotDevicePrep-EN.ps1 -UserPrincipalName jdoe@contoso.org -PolicyName 'DPP*' -PassThru
$r | Where-Object Status -eq 'FAIL' | Format-Table Category, Check, Remediation -Wrap

05 – The Audit script

check the script directly on my Github repo :

https://github.com/aymenjaz/PowerShell/blob/main/1%20-%20Microsoft%20365/Intune/Test-AutopilotDevicePrep-EN.ps1

06 – Reading the report

Each check produces one row with five columns: Status, Category, Check, Detail, Remediation. The HTML report follows the system light or dark theme; the CSV is ready for Excel or Power BI.

StatusMeaningAction
__FAIL__ A blocking misconfiguration. DPP will fail or be skipped.Fix first, in the order of the summary.
__WARN__Risky or ambiguous configuration that may cause partial failures.Review and decide.
__PASS__ Check validated.None.
__INFO__ Context: settings, counts, identifiers.Use for correlation.
SKIPCheck not run: missing parameter, scope or role.Never read a SKIP as a PASS. Fix permissions and rerun.

Example of HTML report page

Autopilot device preparation diagnostic
Sample report with fictitious data (tenant, users, devices and IDs are invented). Published by CloudSecOp.com to illustrate the output of Test-AutopilotDevicePrep.ps1.

Autopilot device preparation diagnostic

User: jdoe@contoso.org | Serial number: 5CG1234XYZ | Generated on 2026-11-09 09:14
PASS 23 | WARN 9 | FAIL 9 | INFO 38 | SKIP 0

StatusCategoryCheckDetailRemediation
INFOTenantTenantContoso Ltd (3f8a1c2e-6b4d-4e9a-a1f0-9c2d7e5b8a13), account: auditor@contoso.org
PASSTenantIntune Provisioning Client SPIntune Provisioning Client present and enabled (objectId 7c1e4b2a-93d5-4f61-b0a8-2e5d9c3f1a74)
INFOTenantIntune MDM user scopeMDM user scope: Some (SG-Intune-MDM-Users)
INFOTenantEntra join allowedSelected: 0 user(s), 1 group(s)
INFOTenantEntra device quota20 device(s) max per user
INFOTenantMFA to join devicesnotRequired
PASSUserAccountJohn Doe enabled (id 9d4e2f1a-5c7b-4a38-8e61-0b2f3c4d5e6f)
WARNUserUsage locationNo usageLocation set.Set usageLocation, otherwise license assignment may fail.
PASSUserIntune licenseINTUNE_A active
PASSUserEntra ID P1/P2 licensePresent (required for automatic MDM enrollment)
INFOUserGroupsMember of 14 group(s) (transitive)
PASSUserIn MDM scopeUser is a member of an MDM scope group
PASSUserAllowed to joinUser is in the Entra join selection
PASSUserEntra quota3 / 20 owned devices
PASSRestrictionsWindows platformAllowed by ‘All users’ (effective for jdoe@contoso.org)
INFORestrictionsPersonal devicesPersonal Windows enrollment blocked: each DPP device needs a corporate identifier (checked in section 7 with -SerialNumber).
PASSRestrictionsIntune device limit2 / 5 (‘All users’)
FAILConditional AccessCompliant device requirement‘CA012-AllApps-RequireCompliantDevice’ (enabled) targets Intune enrollment, controls: compliantDevice, user scope: IncludedChicken-and-egg blocker: exclude the “Microsoft Intune Enrollment” app (d4ebce55-015a-49b5-a083-c84d1797ae8c) and do not require a compliant device on the Register or join devices action.
WARNConditional AccessCompliant device requirement‘CA020-RegisterDevice-RequireCompliant’ (enabledForReportingButNotEnforced) targets Register or join devices user action, controls: compliantDevice, user scope: Included (report-only)Would block enrollment if enabled.
INFOConditional AccessPolicy in scope‘CA001-AllUsers-RequireMFA’ (enabled) targets Intune enrollment, controls: mfa, user scope: Included
INFOPolicy: DPP-UserDriven-CorpIdentityid 5b9e1d3c-2a47-4f8e-9c16-7d0a3b2e4f58, last modified 2026-10-28T14:22:07Z
INFOPolicy: DPP-UserDriven-CorpAllow diagnostics collectionallowdiagnostics_1
INFOPolicy: DPP-UserDriven-CorpAllow users to skipallowskip_1
INFOPolicy: DPP-UserDriven-CorpCustom error messageContact the Contoso Service Desk at ext. 4357
INFOPolicy: DPP-UserDriven-CorpUser account typeaccountype_0 (Standard user)
INFOPolicy: DPP-UserDriven-CorpDeployment modedeploymentmode_0 (User-driven)
INFOPolicy: DPP-UserDriven-CorpDeployment typedeploymenttype_0
INFOPolicy: DPP-UserDriven-CorpJoin typejointype_0 (Microsoft Entra joined)
INFOPolicy: DPP-UserDriven-CorpInstallation timeout (minutes)60
INFOPolicy: DPP-UserDriven-CorpAllowed apps6 app(s) selected
INFOPolicy: DPP-UserDriven-CorpAllowed scripts2 script(s) selected
INFOPolicy: DPP-UserDriven-CorpAssignmentsIncluded: SG-DPP-Users-Corp | Excluded: none
PASSPolicy: DPP-UserDriven-CorpUser targetingUser is targeted by this policy
INFOPolicy: DPP-Pilot-FinanceIdentityid 8e2c4a6b-1d3f-4b5a-9e7c-0f1a2b3c4d5e, last modified 2026-09-15T09:41:53Z
INFOPolicy: DPP-Pilot-FinanceAllow diagnostics collectionallowdiagnostics_1
INFOPolicy: DPP-Pilot-FinanceAllow users to skipallowskip_0
INFOPolicy: DPP-Pilot-FinanceCustom error messagePilot build: contact the Endpoint team
INFOPolicy: DPP-Pilot-FinanceUser account typeaccountype_1 (Administrator)
INFOPolicy: DPP-Pilot-FinanceDeployment modedeploymentmode_0 (User-driven)
INFOPolicy: DPP-Pilot-FinanceDeployment typedeploymenttype_0
INFOPolicy: DPP-Pilot-FinanceJoin typejointype_0 (Microsoft Entra joined)
INFOPolicy: DPP-Pilot-FinanceInstallation timeout (minutes)90
INFOPolicy: DPP-Pilot-FinanceAllowed apps3 app(s) selected
INFOPolicy: DPP-Pilot-FinanceAllowed scripts1 script(s) selected
INFOPolicy: DPP-Pilot-FinanceAssignmentsIncluded: SG-DPP-Users-Pilot | Excluded: none
PASSPolicy: DPP-Pilot-FinanceUser targetingUser is targeted by this policy
WARNDPP policyOverall targetingSeveral policies target the user: DPP-UserDriven-Corp, DPP-Pilot-FinanceOnly the highest priority policy applies: check the order in the portal.
INFODevice groupGroups owned by Intune Provisioning Client2 group(s): SG-DPP-Devices-Corp, SG-DPP-Devices-Pilot
PASSGroup: SG-DPP-Devices-CorpMembership typeAssigned
PASSGroup: SG-DPP-Devices-CorpIntune Provisioning Client ownerConfirmed via: SP ownedObjects ; owners, objectId 7c1e4b2a-93d5-4f61-b0a8-2e5d9c3f1a74
INFOGroup: SG-DPP-Devices-CorpMembers41 member(s)
PASSGroup: SG-DPP-Devices-PilotMembership typeAssigned
WARNGroup: SG-DPP-Devices-PilotRole-assignableGroup is assignable to Entra roles.Not recommended for DPP: use a standard security group.
PASSGroup: SG-DPP-Devices-PilotIntune Provisioning Client ownerConfirmed via: SP ownedObjects ; owners, objectId 7c1e4b2a-93d5-4f61-b0a8-2e5d9c3f1a74
INFOGroup: SG-DPP-Devices-PilotMembers4 member(s)
FAILGroup: SG-Autopilot-Devices-LegacyMembership typeDynamic group ((device.devicePhysicalIds -any (_ -contains “[ZTDId]”))).The DPP group must use Assigned membership.
FAILGroup: SG-Autopilot-Devices-LegacyIntune Provisioning Client ownerExpected SP (objectId 7c1e4b2a-93d5-4f61-b0a8-2e5d9c3f1a74) is not an owner. Owners returned: Endpoint Admins Svc [user] 2a4c6e8f-1b3d-4f5a-8c7e-9d0b1a2c3e4fEntra > Groups > [group] > Owners > Add: “Intune Provisioning Client” (AppId f1346770-5b25-470b-88bd-d5744ab7952c).
INFOGroup: SG-Autopilot-Devices-LegacyMembers187 member(s)
PASSDPP appsCompany Portal [winGetApp]Required on SG-DPP-Devices-Corp
PASSDPP appsMicrosoft 365 Apps for enterprise [officeSuiteApp]Required on SG-DPP-Devices-Corp, SG-DPP-Devices-Pilot
FAILDPP appsContoso GlobalProtect VPN 6.2 [win32LobApp]No Required assignment to the device group. Current: Included: SG-DPP-Users-Corp | Excluded: noneAssign the app as Required to the DPP device group (not to the user group).
WARNDPP apps7-Zip 24.08 [win32LobApp]Install context: user.During OOBE, prefer the System context.
PASSDPP apps7-Zip 24.08 [win32LobApp]Required on SG-DPP-Devices-Corp
WARNDPP appsContoso Branding Pack [win32LobApp]publishingState = processingContent not published (upload in progress or failed): wait or upload again.
PASSDPP appsContoso Branding Pack [win32LobApp]Required on SG-DPP-Devices-Corp
FAILDPP appsApp 4f7a9c2e-8b1d-4e3f-a6c5-2d9e0b7f1a38Not found or not accessible (Response status code does not indicate success: NotFound (Not Found).). Referenced by: DPP-UserDriven-CorpApp deleted? Remove it and select it again in the policy.
PASSDPP appsMicrosoft Edge for Business [windowsMicrosoftEdgeApp]Required on SG-DPP-Devices-Pilot
PASSDPP scriptsSet-ContosoTimeZoneAssigned to the device group
WARNDPP scriptsRename-DeviceFromSerialRuns in the user context.During OOBE, prefer the System context.
FAILDPP scriptsRename-DeviceFromSerialNot assigned to the device group. Current: Included: SG-Autopilot-Devices-Legacy | Excluded: noneAssign the script to the DPP device group.
FAILDeviceAutopilot v1 registrationRegistered in v1 (groupTag ‘FIN-LAPTOP’, profile: assignedUnkownSyncState). The v1 profile takes precedence over device preparation.Delete the registration (Devices > Windows > Enrollment > Devices) if the device must go through DPP.
FAILDeviceCorporate identifierPersonal enrollment is blocked and no corporate identifier exists for this serial number: enrollment will be refused.Intune > Devices > Enrollment > Corporate device identifiers: import “Manufacturer,Model,SerialNumber”.
INFODeviceIntune objectCTS-FIN-5CG1234XYZ | enrolled 2026-11-06T13:07:44Z | last sync 2026-11-09T08:12:31Z | UPN jdoe@contoso.org
INFODeviceEnrollmenttype windowsAzureADJoin | join azureADJoined | ownership company | compliance compliant
PASSDeviceWindows version10.0.26100.4946
PASSDeviceEntra join typeMicrosoft Entra joined
FAILDeviceDevice groupThe device was not added to any DPP device group: apps and scripts will not install during OOBE.Typical causes: Intune Provisioning Client not owner of the group, group not selected in the policy, or DPP policy not applied (v1 profile took precedence).
WARNEventsEnrollment failure2026-11-06T12:58:19Z | enrollmentRestriction | DeviceNotCorporate: personal Windows enrollment is blocked | OS 10.0.26100.4946Correlate with client-side logs (MDMDiagnosticsTool, Event Viewer).
WARNEventsEnrollment failure2026-11-06T12:41:02Z | authorization | ConditionalAccessBlocked: device must be compliant | OS 10.0.26100.4946Correlate with client-side logs (MDMDiagnosticsTool, Event Viewer).

Thanks

Aymen EL JAZIRI (Microsoft MVP)
Aymen EL JAZIRI (Microsoft MVP)

Hi, I’m Aymen El Jaziri , a passionate System Administrator and Microsoft MVP, with years of hands-on experience in managing and securing modern IT infrastructures.
This blog is where I share technical guides, automation scripts, product reviews, and real-world solutions that help IT professionals simplify their day-to-day work and stay ahead in a fast-evolving cloud ecosystem.
Whether you’re here to troubleshoot an issue, improve your automation game, or learn new best practices , welcome in my blog !
Let’s build a stronger, smarter IT community together.
Feel free to connect with me on LinkedIn for more content, discussions, or collaboration opportunities.

Thanks

Aymen

Articles: 158