You have a serial number. You need to know if that device is registered in Windows Autopilot, which deployment profile is assigned to it, and whether it has ever checked in. Hunting through the Intune portal one device at a time works for one device. It does not work for ten.
The Microsoft Graph PowerShell cmdlet Get-MgDeviceManagementWindowsAutopilotDeviceIdentity with the -Filter parameter solves this in one line. This post covers the exact syntax, what the output fields mean, and how to run bulk serial number lookups from a CSV.
- Checking whether a device is registered in Autopilot before deployment
- Verifying a Group Tag is set correctly before the device reaches the user
- Auditing which devices in a shipment are and are not registered
- Troubleshooting OOBE failures — confirming the hardware hash was actually uploaded
- Bulk checking a procurement list against your Autopilot registrations
Why the Intune Portal Falls Short for This
In the Intune admin center, you can browse to Devices > Enrollment > Windows > Windows Autopilot devices. You can search by serial number — one at a time — using the search box. There is no bulk search, no export-and-filter workflow, and no way to query by serial number from a list.
The Graph API gives you the full filtered list. One command. Any number of serial numbers.
Step 1 — Install the Module and Connect
The cmdlet is in the Microsoft.Graph.DeviceManagement.Enrollment module. If you have the full Microsoft.Graph module installed, you already have it. If not, install just the sub-module:
# Install if not already present (run as admin)
Install-Module -Name "Microsoft.Graph.DeviceManagement.Enrollment" -Scope CurrentUser
# Connect with read-only Autopilot permission
Connect-MgGraph -Scopes "DeviceManagementServiceConfig.Read.All"
After running Connect-MgGraph, a browser window opens asking you to sign in with your Entra ID admin account. Once authenticated, the shell confirms the connection:
DeviceManagementServiceConfig.Read.All is sufficient for read operations. If you need to update Group Tags or reassign profiles programmatically, use DeviceManagementServiceConfig.ReadWrite.All. Do not use a higher-privilege scope than you need.
Step 2 — Look Up a Single Device by Serial Number
The -Filter parameter takes an OData v4 filter expression. For an exact serial number match, the syntax is serialNumber eq 'VALUE'. The property name is camelCase and the value is in single quotes:
# Exact serial number lookup (OData eq operator)
$serial = "ABC123XYZ456"
$device = Get-MgDeviceManagementWindowsAutopilotDeviceIdentity -Filter "serialNumber eq '$serial'"
# Show the key fields
$device | Select-Object SerialNumber, GroupTag, EnrollmentState, Manufacturer, Model, ManagedDeviceId, DisplayName
If the device is registered, you will see output like this:
If the command returns nothing (no output, no error), the serial number is not registered in your Autopilot tenant. That is the most common result when troubleshooting an OOBE failure — the hardware hash was never uploaded.
If you get no results but you can see the device in the Intune portal, check the case of the serial number. Autopilot serial numbers are stored as-uploaded. A serial number uploaded as abc123 will not match a filter of serialNumber eq 'ABC123'. Use the exact case shown in the portal, or use tolower(serialNumber) eq 'abc123' for a case-insensitive match.
Understanding the Response Fields
| Field | What It Means | Key Values to Know |
|---|---|---|
| serialNumber | The hardware serial number as uploaded | Stored exactly as-uploaded. Case matters for filtering. |
| groupTag | The Autopilot Group Tag assigned to this device | Used for dynamic Entra ID group membership and profile assignment. Empty if no tag set. |
| enrollmentState | Whether the device has been enrolled via Autopilot | unknown / enrolled / pendingReset / failed / notContacted |
| managedDeviceId | Links to the Intune managed device object | Empty if the device has not yet completed Autopilot enrollment. Use with Get-MgDeviceManagementManagedDevice. |
| azureActiveDirectoryDeviceId | The Entra ID device object ID | Empty until the device completes OOBE and joins Entra ID. |
| lastContactedDateTime | Last time the device contacted Intune | Null/empty if the device has never completed Autopilot. Shows notContacted enrollment state. |
| displayName | The device name set during Autopilot provisioning | Empty until the device name template runs during OOBE. |
Step 3 — Bulk Lookup from a CSV
The real time-saver is running a list of serial numbers from procurement or a helpdesk ticket. Create a CSV with a column called SerialNumber, then run this loop:
# Import serial numbers from CSV (must have a 'SerialNumber' column)
$serials = Import-Csv -Path "C:\Temp\device-serials.csv"
$results = @()
$serials | ForEach-Object {
$sn = $_.SerialNumber.Trim()
$device = Get-MgDeviceManagementWindowsAutopilotDeviceIdentity -Filter "serialNumber eq '$sn'"
$results += [PSCustomObject]@{
SerialNumber = $sn
Registered = $null -ne $device
GroupTag = $device?.GroupTag
EnrollmentState = $device?.EnrollmentState
Model = $device?.Model
ManagedDeviceId = $device?.ManagedDeviceId
}
Write-Host "$sn — $($null -ne $device ? 'FOUND' : 'NOT REGISTERED')"
}
# Export results
$results | Export-Csv -Path "C:\Temp\autopilot-check-$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation
Write-Host "Results exported. Registered: $($results | Where-Object Registered).Count) / $($results.Count)"
The output CSV will have one row per serial number with a Registered column (True/False), Group Tag, enrollment state, and model. You can send this directly to procurement as confirmation of what is and is not in your Autopilot tenant.
By default, Get-MgDeviceManagementWindowsAutopilotDeviceIdentity returns a maximum of 1,000 devices per page. If you want to retrieve all Autopilot devices to check against (rather than filtering by serial number), add the -All switch: Get-MgDeviceManagementWindowsAutopilotDeviceIdentity -All. Do not use -All in the per-serial loop above — the filter handles scoping.
Step 4 — Updating a Group Tag via Graph
If the lookup reveals the wrong Group Tag is set (or no Group Tag at all), you can update it without going into the portal. You need the device's Autopilot identity ID first:
# Reconnect with write permission
Connect-MgGraph -Scopes "DeviceManagementServiceConfig.ReadWrite.All"
# Get the device identity ID
$device = Get-MgDeviceManagementWindowsAutopilotDeviceIdentity -Filter "serialNumber eq 'ABC123XYZ456'"
# Update the Group Tag
Update-MgDeviceManagementWindowsAutopilotDeviceIdentityDeviceProperty `
-WindowsAutopilotDeviceIdentityId $device.Id `
-GroupTag "Corp-Win11-Finance"
Write-Host "Group Tag updated. Allow 5-10 minutes for Entra ID dynamic group membership to recalculate."
Changing a Group Tag updates the Autopilot device record immediately, but Entra ID dynamic group membership recalculates asynchronously. This typically takes 2–5 minutes but can take up to 24 hours on large tenants. If the device is mid-OOBE when the tag changes, the profile assignment that was in effect at OOBE start will apply — not the new one. Change Group Tags before the device reaches OOBE.
Group Policy — What Applies Here (and What Does Not)
Autopilot device registration, profile assignment, and Group Tag management are cloud-only operations. They live entirely in the Intune/Graph layer and have no corresponding Computer Configuration or User Configuration Group Policy path. If your organisation uses hybrid Entra joined devices with GPO, those GPOs apply after Autopilot provisioning is complete — not during it. There is no GPO that controls Autopilot profile assignment or serial number lookup.
What GPO can affect post-Autopilot:
- Device naming conventions — enforced via Autopilot device name template in the deployment profile (Intune), not GPO
- Windows Update for Business deferral — can be set via GPO at
Computer Configuration > Administrative Templates > Windows Components > Windows Update > Windows Update for Business, but Intune Update Rings take precedence on Entra joined devices - Scripts run post-enrollment — Intune PowerShell scripts (System context) apply during/after OOBE; GPO startup scripts apply only after the device is domain-joined (hybrid only)
Verifying the Device Appears in Autopilot Diagnostics
On the device itself, you can confirm Autopilot registration by checking the MDM diagnostics. Open PowerShell as Administrator and run:
# Export MDM diagnostics including Autopilot data
MdmDiagnosticsTool.exe -area DeviceEnrollment;Autopilot -zip C:\Temp\AutopilotDiag.zip
Inside the ZIP, open AutopilotDDSZTDFile.json. The ZtdDeviceIdentifier value is the hardware hash identifier. If this file is present and populated, the device has a valid hash. If it is empty or missing, the hash was never captured — which means re-running the hardware hash capture script is the fix.
References
- Get-MgDeviceManagementWindowsAutopilotDeviceIdentity — Microsoft Learn
- List windowsAutopilotDeviceIdentities (Graph API) — Microsoft Learn
- Windows Autopilot overview — Microsoft Learn
- Troubleshoot Windows Autopilot device enrollment — Microsoft Learn
- Use the $filter query parameter — Microsoft Graph — Microsoft Learn
- Get started with the Microsoft Graph PowerShell SDK — Microsoft Learn