Windows Autopilot Behind The Scenes Secrets – Admin Side – Part 2

0
Autopilot Architecture Diagram

In my previous post (Autopilot FAQs), I tried to clarify the general misconceptions and give a clear overview of what is Windows Autopilot. This post is a part of a series and continuation to that, where I want to talk about Windows Autopilot Behind the Scenes from the Admin end configuration perspective. Let’s get started.

Related Posts

Extracting the Hardware Hash from end device

It all starts with extracting the device hash from a device using the Get-WindowsAutopilotInfo script available in GitHub.The CSV file as generated by running this script is uploaded in Intune (or MSfB) to register the device to Autopilot services.

Subscribe to this Blog via eMail

Join 15,879 other subscribers

What Information does Autopilot CSV Contains?

If you check the CSV contents, the thing that will catch your attention is the extreme large HEX value. To see the contents of this HEX value, you would need to decode it. This can be done using the oa3tool.exe, which is a part of the Windows ADK.

Related PostWindows Autopilot FAQ Clarifying the General Misconceptions Part 1

oa3tool.exe - part of Windows ADK -  Windows Autopilot Behind the Scenes
oa3tool.exe – part of Windows ADK – Windows Autopilot Behind the Scenes

How to Decode Autopilot CSV?

As I mentioned above, you can decode Autopilot CSV file using oa3tool.exe. The decrypted hardware hash looks similar to the below XML representation.

<?xml version="1.0"?>
 <HardwareReport>
         <HardwareInventory>
                 <p n="ToolVersion" v="3" />
                 <p n="HardwareInventoryVersion" v="131" />
                 <p n="ToolBuild" v="10.0.17763.1" />
                 <p n="OSType" v="FullOS" />
                 <p n="OsCpuArchitecture" v="x64" />
                 <p n="OsBuild" v="10.0.17763.1" />
                 <p n="OsSystemTime" v="2019-03-05T12:25:49Z" />
                 <p n="OsLocalTime" v="2019-03-06T18:25:49+30:00" />
                 <p n="ProcessorModel" v="Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz" />
                 <p n="ProcessorPackages" v="1" />
                 <p n="ProcessorThreads" v="1" />
                 <p n="ProcessorCores" v="1" />
                 <p n="ProcessorHyperThreading" v="false" />
                 <p n="SmbiosRamArrayCount" v="1" />
                 <p n="SmbiosRamSlots" v="1" />
                 <p n="SmbiosRamErrorCorrection" v="None" />
                 <p n="SmbiosRamMaximumCapacity" v="2048" />
                 <p n="TotalPhysicalRAM" v="2" />
                 <p n="SmbiosFirmwareVendor" v="Lenovo" />
                 <p n="SmbiosSystemManufacturer" v="Lenovo" />
                 <p n="SmbiosSystemProductName" v="Lenovo" />
                 <p n="SmbiosSystemSerialNumber" v="PC0QX40X" />
                 <p n="SmbiosUuid" v="1b0b2241-6194-4d64-9bab-173000ed6541" />
                 <p n="SmbiosSkuNumber" v="None" />
                 <p n="SmbiosSystemFamily" v="" />
                 <p n="SmbiosSystemVersion" v="" />
                 <p n="SmbiosBoardManufacturer" v="Intel" />
                 <p n="SmbiosBoardProduct" v="" />
                 <p n="SmbiosBoardVersion" v="" />
                 <p n="ChassisType" v="0x0#" />
                 <p n="InternalDiskCount" v="1" />
                 <p n="DeviceNumber" v="0" />
                 <p n="PrimaryDiskTotalCapacity" v="42" />
                 <p n="PrimaryDiskType" v="HDD" />
                 <p n="DiskSerialNumber" v=" 2b0b2241-6194-4d64-9bab-173000ed6541 " />
                 <p n="OpticalDiskDriveType" v="true" />
                 <p n="PhysicalMedium" v="Unspecified" />
                 <p n="MacAddress" v="00:15:5D:BA:AE:00" />
                 <p n="DisplayResolutionHorizontal" v="1024" />
                 <p n="DisplayResolutionVertical" v="768" />
                 <p n="DisplaySizePhysicalH" v="0" />
                 <p n="DisplaySizePhysicalY " v="0" />
                 <p n="DigitizerSupportID" v="IntegratedTouch, IntegratedPen, MultiInput" />
                 <p n="PowerPlatformRole" v="Mobile" />
                 <p n="TPMVersion" v="TPM-Version:2.0 -Level:0-Revision:1.16-VendorID:'MSFT'-Firmware:538247443.1394722" />
                 <p n="TPM EkPub" v="s7+hJsgnlFQ+Jf4O7WZEh9AcZcJ9EXIBGeUSkzRXDkrSt2UBJ0P1FmA8V8PTp/TbY3dmn5IG1Z2spHlrGmu1AshGHlZyIMFPUeMN91/+mM3lqWsHOrOMHjGvZrdMCJxi3sXAqs16bo5BFoNWXHXZyCwWQ3204chGlOzm309hKV+l90t7ciqzfpaA2D7UcyYy8xHm0qbuI1pNaHYkP5mmdyKn5eoHtpNTY0zjVf+ZtZIJ6N2/VydcZ5olmSG2BRe5xxZhbYILkprzyit5ayPXmUlTYm5MV6zbuZYMeU0hu4HetDAL6G0XZQz+UH/ufuvEBCe44Q/uz2UdXlgQ0cfpTQ==" />
                 <p n="Status" v="0x00000000" />
                 <p n="OfflineDeviceIdType" v="TPM_EK" />
                 <p n="OfflineDeviceId" v="2Q5jpb/RDYGngUglOzNZHh0bcv+oK08MpoOAFRtTYr8=" />
                 <p n="DiskSSNKernel" v=" " />
         </HardwareInventory>
 </HardwareReport> 

All this information is used for the registration of the device to the Windows Autopilot service (also known as Device Directory Service – DDS – internally).

NOTE: This is the exact info collected during normal provisioning process as well. Replacing the system board changes the hardware hash for that particular device. A device, post motherboard replacement, is subjected to fresh enrollment even if devices records are present in Azure AD and Intune. The reason being WPJ (Work Place Join) re-evaluation as performed by Azure DRS fails for the fact that the device info as stored in the Azure AD device object does not matches with the present device.

Get-WindowsAutopilotInfo Script

More information: This is the rough functioning of the Get-WindowsAutopilotInfo script.

$hh=(Get-CimInstance -ClassName MDM_DevDetail_Ext01 -Namespace root\cimv2\mdm\dmmap).DeviceHardwareData
 $serialnumber=(Get-WmiObject -Class win32_bios ).serialnumber
 $mm=(Get-WmiObject -class win32_computersystem)
 $details= New-Object psobject -Property @{
 Hardwarehash=$hh
 SerialNumber=$serialnumber
 Manufacturer=$mm.Manufacturer
 Model=$mm.Model
 }
 $details | Out-GridView 

As the hardware hash is collected, let’s move to the next part.

Autopilot Device Registration Part – Windows Autopilot Behind the Scenes

This is where an IT Admin will start registering the device to the Windows Autopilot service by uploading the device hash to Intune.

NOTE 1 – At this point, I need to clarify that the Intune service and the Autopilot service are mostly not the same. This is a misconception I hear from many admins to date. Windows Autopilot is an entirely different independent service which is separate from the Intune service. 

NOTE 2Intune provides the UI which allows Admins to register devices as Autopilot devices. The same is also possible from Microsoft Store for Business (MSfB). Thus we can say that Intune and MSfB provides a mechanism to register devices to Windows Autopilot service, but they are not the Autopilot service in itself.

Add Windows Autopilot Devices

To understand this better, let’s have a look into what happens in the back end (Windows Autopilot Behind the Scenes) when an Admin uploads a device hash into Intune.

Windows Autopilot - upload device hash - Windows Autopilot Behind the Scenes
Windows Autopilot – upload device hash – Windows Autopilot Behind the Scenes

Graph Query

The graph query that gets generated in the backend is:

RequestURL:https://graph.microsoft.com/beta/deviceManagement/importedWindowsAutopilotDeviceIdentities/import  
HTTP Version:HTTP/1.1
Request method: POST
Type:
application/json
Raw Content:
{"importedWindowsAutopilotDeviceIdentities": [{
"serialNumber": "#######",
"productKey": "",
"hardwareIdentifier": "#######"
}]}  

Post call to Register to Windows Autopilot Service

This is the POST call made by Intune to register the device to Windows Autopilot service (also known as DDSDevice Directory Service). The response as to this POST call is:

{
"@odata.context": "https://graph.microsoft.com/beta/$metadata#Collection(importedWindowsAutopilotDeviceIdentity)",
"value": [{
"@odata.type": "#microsoft.graph.importedWindowsAutopilotDeviceIdentity",
"id": "4419d710-489d-4d36-bb1f-a3d0a4941727",
"orderIdentifier": "",
"groupTag": "",
"serialNumber": "8645-5788-4128-6899-2408-1523-89",
"productKey": "",
"importId": "adaf2068-abf1-4309-906a-c9b4ef250670",
"hardwareIdentifier": "",
"assignedUserPrincipalName": "",
"state": {
"deviceImportStatus": "unknown/pending/partial/complete/error",
"deviceRegistrationId": "",
"deviceErrorCode": 0,
"deviceErrorName": ""
}}]} 

Get Call to Query Import Status

The GUID as referred by “id” is the object identifier in the importedAutopilotDeviceIdentity collection namespace but what is more important is the “imported” GUID with which Intune creates a GET call to query the import status.

 RequestURL: https://graph.microsoft.com/beta/deviceManagement/importedWindowsAutopilotDeviceIdentities 
 Query arguments:
 $filter ImportId eq 'adaf2068-abf1-4309-906a-c9b4ef250670'
 $select id,state
 HTTP Version: HTTP/1.1
 Request method: GE
 GET Response Content:
 {
 "@odata.context": "https://graph.microsoft.com/beta/$metadata#deviceManagement/importedWindowsAutopilotDeviceIdentities", "value": [{
 "@odata.type": "#microsoft.graph.importedWindowsAutopilotDeviceIdentity",
 "id": "4419d710-489d-4d36-bb1f-a3d0a4941727",
 "orderIdentifier": "",
 "groupTag": "",
 "serialNumber": "8645-5788-4128-6899-2408-1523-89",
 "productKey": "",
 "importId": "adaf2068-abf1-4309-906a-c9b4ef250670",
 "hardwareIdentifier": "",
 "assignedUserPrincipalName": ""
 "state": {
 "deviceImportStatus": "complete",
 "deviceRegistrationId": "f233b7c8-82bc-4839-8aed-6bbd98d7066f",
 "deviceErrorCode": 0,
 "deviceErrorName": "None"
 }}]} 

Autopilot Registration Completed?

This registration process can take any time up to 15 minutes. So what is happening here in the back end?

  • The POST call initiates the device registration to the Windows Autopilot service (DDS – Device Directory Service) using the hardware hash.
  • DDS generates a unique ID known as ZTDID (Zero Touch Device Id, ZTD is the codename for Windows Autopilot in MS) against the registration which is returned to Intune (via the GET call to query the status, in the form of the “deviceRegistrationId” GUID)

At this point, we see the device entry appearing under the Microsoft Intune > Device enrollment > Windows enrollment > Windows Autopilot devices.

Autopilot Device details -  Windows Autopilot Behind the Scenes
Autopilot Device details – Windows Autopilot Behind the Scenes

Completed? Not Completed?Azure AD Windows Autopilot Behind the Scenes

But the story doesn’t end here. Noticed the Associated Azure AD device object in the Autopilot device properties. The device is yet to start the provisioning process, and there is an Azure AD object created already?

Azure AD device object -  Windows Autopilot Behind the Scenes
Azure AD device object – Windows Autopilot Behind the Scenes

Autopilot & Azure AD Device Registration Service (DRS)

With the Autopilot device object created, the Azure AD Device Registration Service (DRS) pre-creates an Azure AD device object stamping the ZTDID on it.

Audit log showing the Azure DRS action Add Device -  Windows Autopilot Behind the Scenes
Audit log showing the Azure DRS action Add Device – Windows Autopilot Behind the Scenes

This blank device object comes up under the Azure AD devices with the Serial Number of the device as Name and at the moment is in Disabled state.

Pre-created Azure AD device object properties -  Windows Autopilot Behind the Scenes
Pre-created Azure AD device object properties – Windows Autopilot Behind the Scenes

What makes the Windows Autopilot device to become member of the dynamic device group created against query of ZTDID?

If you have any prior knowledge of the Windows enrollment flows, in case of both Azure AD join and Azure AD registration, you would know that the Azure AD device object is created by Azure DRS after the user initiates the join/registration activity on the device.

But, Windows Autopilot is an exception where the Azure AD device object is pre-created. It is because of this Azure AD device object; the device becomes a member of the dynamic device group for Autopilot devices you create in Azure with the query (device.devicePhysicalIDs -any _ -contains “[ZTDId]”).

Move Autopilot Device Registered to One Tenant to Another Tenant?

The DDS registration Id (ZTDID) is universally unique being based on hardware hash. What will happen when you have a device registered to Autopilot from one tenant and plan to move it to another tenant?

You would need to delete the device entry from Autopilot devices of that first tenant which will trigger a deregistration call from Intune clearing the ZTDID from DDS. This will help the same device registration with another tenant. So that it can be added from another tenant. Failing to do so will always result in the below error.

Autopilot Error Code 808 – ZtdDeviceAssignedToOtherTenant. CSV line numbers affected

Error code 808 -  Windows Autopilot Behind the Scenes
Error code 808 – Windows Autopilot Behind the Scenes

With the device becoming a member of the Autopilot device AAD group, we can continue to the next part.

Profile Configuration and Assignment

This is where you as an IT Admin, will create the Autopilot deployment profile from under Microsoft Intune > Device enrollment > Windows enrollment > Windows Autopilot deployment profiles to configure the OOBE as per the deployment requirements.

Windows Autopilot Profile Configuration -  Windows Autopilot Behind the Scenes
Windows Autopilot Profile Configuration – Windows Autopilot Behind the Scenes

Graph Post Call with Profile ID

The Graph call that works behind the scenes

RequestURL: https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeploymentProfiles
 HTTP Version: HTTP/1.1
 Request method: POST
 Type: application/json
 Raw Content:
 {
 "@odata.type": "#microsoft.graph.azureADWindowsAutopilotDeploymentProfile",
 "displayName": "WhiteGlove",
 "description": "Test",
 "deviceNameTemplate": "JOY-%RAND:5%",
 "language": "",
 "enableWhiteGlove": true,
 "extractHardwareHash": false,
 "roleScopeTagIds": [],
 "outOfBoxExperienceSettings": {
 "deviceUsageType": "singleUser",
 "hideEscapeLink": true,
 "hidePrivacySettings": true,
 "hideEULA": true,
 "userType": "administrator",
 "skipKeyboardSelectionPage": false
 }
 } 

If everything is fine, the response to this POST call returns as 201 created, the content has the profile Id.

{
 "@odata.context": "https://graph.microsoft.com/beta/$metadata#deviceManagement/windowsAutopilotDeploymentProfiles/$entity",
 "@odata.type": "#microsoft.graph.azureADWindowsAutopilotDeploymentProfile",
 "id": "3e2b0a25-a332-4deb-83fb-60a0dc42e95e",
 "displayName": "WhiteGlove",
 "description": "Test",
 "language": "os-default",
 "createdDateTime": "2019-09-02T09:34:38.9238427Z",
 "lastModifiedDateTime": "2019-09-02T09:34:38.9238427Z",
 "enrollmentStatusScreenSettings": null,
 "extractHardwareHash": false,
 "deviceNameTemplate": "JOY-%RAND:5%",
 "deviceType": "windowsPc",
 "enableWhiteGlove": true,
 "roleScopeTagIds": [
 "0"
 ],
 "outOfBoxExperienceSettings": {
 "hidePrivacySettings": true,
 "hideEULA": true,
 "userType": "administrator",
 "deviceUsageType": "singleUser",
 "skipKeyboardSelectionPage": false,
 "hideEscapeLink": true
 }
 } 

Another Post Call – Assignment

The profile as created now waits for assignment to the group (the Autopilot dynamic device group). As the assignment is made, this is the Graph call that works behind the scenes.

 RequestURL: https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeploymentProfiles/3e2b0a25-a332-4deb-83fb-60a0dc42e95e/assignments  
 HTTP Version: HTTP/1.1
 Request method: POST
 Post Data
 Type: application/json
 Raw Content:
 {
 "target": {
 "@odata.type": "#microsoft.graph.groupAssignmentTarget",
 "groupId": "6239fcb0-190e-431f-b618-b1510d71986a"
 }
 } 

Noticed the odata type in the Graph call – the profile namespace is azureADWindowsAutopilotDeploymentProfile and is not under deviceManagement which is Intune. Intune provides an UI to create the autopilot deployement profile but in itself is not the endpoint from where the device gets the profile.

Where does the device gets the profile from? Check this terrific blog from Michael Niehaus.

Profile Assignment Status – Not Assigned – Assigning – Assigned?

The response 201 Created states if the assignment is successful. Once the profile is assigned to the group, the Profile status of the Autopilot device object changes from “Not Assigned” to “Assigning.”

Profile Status - Assigning -  Windows Autopilot Behind the Scenes
Profile Status – Assigning – Windows Autopilot Behind the Scenes

to finally “Assigned“.

Profile Status - Assigned -  Windows Autopilot Behind the Scenes
Profile Status – Assigned – Windows Autopilot Behind the Scenes

It is possible that you won’t see this status change as it requires a continuous refresh of the page.

Autopilot Profile Assignment from MSfB (Microsoft Store for Business)

For profiles created in MSfB or profile assigned from MSfB, the Profile status of the Autopilot device object will show as “Externally Assigned.”

Why the Device will Skip Autopilot provisioning?

Deleting the pre-created Azure AD device object will result the device to skip/fail Autopilot provisioning.

Only the device object pre-created by Azure DRS during Autopilot (DDS) regsitration has the ZTDID stamped to it.

User-Driven

For user-driven mode, when the device starts OOBE setup and gets connected to network, it checks with Autopilot service for status and gets the profile downloaded accordingly.

Because of this you will still get the custom Azure sign-in page as pre-negotiated. But as you sign-in to perform the auth and device reaches out to Azure DRS endpoint to request the Join process, Azure DRS will fail to find a match for the corresponding Azure AD device object as provided in the request.

The provisioning, in this case, will not fail as Azure DRS will create a new device object, however it will not have the ZTDID stamping. The provisioning will fallback to the consumer OOBE flow which is the normal AAD join flow from OOBE.

More explanation regarding this is coming in the next post Part 3 of this Autopilot series, so stay tuned!

Self-Deploy

For self-deploy mode, it will fail at the ESP stage Device preparation on the AADEnroll task, since the service will fail to get the associated Azure device object. This is a security mechanism to stop rogue devices from joining Azure AD with no credentials.

WhiteGlove?

The same is true for WhiteGlove enabled user-driven deployment as well because the WhiteGlove process is essentially carried out in self-deploy mode process.

I will put more light on this in Part 4 of this series which is specifically for WhiteGlove.

Enable Auto-Enrollment?

The profile being assigned, last thing that is needed to be done is to enable Auto-enrollment.

Enable MDM scope to allow Auto Enrollment -  Windows Autopilot Behind the Scenes
Enable MDM scope to allow Auto Enrollment – Windows Autopilot Behind the Scenes

Windows Autopilot Architecture Schema

This completes the Admin-End configuration phase of Windows Autopilot. If you have read till this, you would be able to summarize the entire flow schematically as shown below.

Windows Autopilot Behind the Scenes
Windows Autopilot – Admin End HLD – Windows Autopilot Behind the Scenes

To be Continued….

In my next post, I will continue discussing Windows Autopilot with respect to the device end implementation. Till then, read something new every day, learn something new every day!

  • DDS – Device Directory Service
  • ZTDID – Zero Touch Device Id
  • DRS – Device Registration Service

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.