Guides / intune
intune-from-zero · Chapter 3 of 11
Importing the Autopilot hardware hash: the errors nobody documents
PowerShell that exits with no output, AADSTS530035, and a VM with no serial number. Three real failures importing the hash, and how to make it non-interactive.
Every Windows device has a hardware hash — a fingerprint built from the motherboard, the TPM and other components. Autopilot uses it to recognise a machine before that machine has any identity: no name, no account, no enrolment. Just a device that has been switched on.
Getting that hash into Intune is documented as a one-liner. In practice it failed three times in a row, each with an error that pointed somewhere other than the cause.
The interactive method
Run these on the device to be registered, in PowerShell as Administrator — or during OOBE with Shift+F10:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned
Install-Script Get-WindowsAutopilotInfo -Force
Connect-MgGraph -UseDeviceAuthentication
Get-WindowsAutopilotInfo -Online
This uploads the hash straight into your tenant. No CSV file to move around, no import step in the portal.
Failure 1 — PowerShell exits with no output
The login completed. MFA completed. Then the window returned to the prompt with nothing printed. No error, no hash, no confirmation.
Cause: the current version of Get-WindowsAutopilotInfo uses the Microsoft Graph SDK, and on Windows 11 the WAM broker handles authentication by default. In the OOBE context the session runs as defaultuser0, and the interactive WAM flow simply cannot complete there. It does not fail loudly — it returns nothing.
Fix: authenticate first, using device code instead of the broker:
Connect-MgGraph -UseDeviceAuthentication
This prints a code to enter at microsoft.com/devicelogin from another device. Once the session is established, Get-WindowsAutopilotInfo -Online reuses it.
Failure 2 — AADSTS530035
With device authentication in place, the code was entered, the password accepted, MFA satisfied — and then:
AADSTS530035: Access has been blocked by Conditional Access policies.
This is worth reading carefully, because the message invites the wrong conclusion. The authentication succeeded. The identity was proven. What was refused was the issuing of a token to that flow.
Cause: Security Defaults, which Microsoft enables on new tenants, block the device code flow outright. It does not matter how strong the authentication is: that entire flow is disallowed.
Confirmed in Entra → Sign-in logs, where the entry showed Policy: Security Defaults · Grant Controls: Block. That log is what turns a guess into a diagnosis, and it is the first place to look whenever an AADSTS code appears.
Fix: Entra → Properties → Manage security defaults → Disabled.
Failure 3 — serialNumber is null
Third attempt. Authentication clean, script ran, and:
0 devices imported successfully
serialNumber is null
Cause: the machine is a virtual one, and Proxmox VMs ship with no SMBIOS serial number. Autopilot requires one — the hash alone is not enough to register a device.
Fix: shut down the VM, then Proxmox → Options → SMBIOS settings (type1) → Serial, and set anything meaningful:
W11-AUTOPILOT-001
Restart and run the import again.
1 devices imported successfully
The device appears in Intune under Devices → Windows enrollment → Autopilot devices, joins the dynamic group, and the profile moves to Assigned.
Making it non-interactive
The interactive method costs six steps per machine: execution policy, install the script, device authentication, open a second device, enter the code with MFA, upload. Fine once. Tedious for ten machines.
An App Registration turns it into a single command.
Setup, once
- Entra → App registrations → New registration → name it
Autopilot-HashUpload, single tenant, no redirect URI. - Note the Application (client) ID and the Directory (tenant) ID.
- API permissions → Add → Microsoft Graph → Application permissions — not Delegated — →
DeviceManagementServiceConfig.ReadWrite.All→ Grant admin consent. - Certificates & secrets → New client secret → copy the Value.
Use
Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned
Install-Script Get-WindowsAutopilotInfo -Force
Get-WindowsAutopilotInfo -Online -TenantId "<tenant>" -AppId "<appid>" -AppSecret "<value>"
Expected output: “Connected to Intune tenant … using app-based authentication”. No login, no device code, no MFA.
What that convenience costs
This is worth stating plainly, because most guides present the App Registration as simply the better method. It trades security for automation, and the trade is real.
| Risk | Detail |
|---|---|
| The permission is broad | DeviceManagementServiceConfig.ReadWrite.All does not cover only hash upload. It allows read and write on the whole enrolment configuration: Autopilot devices, deployment profiles, the ESP, enrolment restrictions |
| It bypasses Conditional Access | An application token is not subject to CA policies or MFA. Applying CA to workload identities requires the separately licensed Entra Workload ID |
| The secret lands in your shell history | Everything typed at a PowerShell prompt is written in clear text to %APPDATA%\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt |
| It expires quietly | When the secret lapses, the command fails with an unhelpful authentication error, months later, with nothing to connect it to |
What to do about it
The most useful of these is the third, because the fix is counterintuitive.
The measures actually applied in the lab:
- The app is disabled between provisioning runs — Entra → Enterprise applications →
Autopilot-HashUpload→ Properties → Enabled for users to sign-in → No — and re-enabled only when needed. - The secret was revoked after use, with a placeholder left in the script file.
- Shell history cleared on every machine where the command was typed:
Remove-Item "$env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt" -Force - The command lives in a
.ps1file on a USB stick rather than being typed by hand.
Still open, and worth doing: a certificate instead of a secret — it cannot be copied out of a console because it never passes through one — and a short expiry with a diarised rotation.
Which method to use
Both, for different situations.
Device code for the occasional machine: nothing is stored, nothing can leak, and the six steps cost less than managing a credential.
App Registration when provisioning several machines in one session: enable the app, run, revoke, disable.
The errors, in short
| Symptom | Cause |
|---|---|
| PowerShell returns to the prompt with no output | WAM broker in the defaultuser0 OOBE context → use -UseDeviceAuthentication |
AADSTS530035 after a successful MFA | Security Defaults block the device code flow — a flow block, not an identity one |
serialNumber is null · 0 devices imported | VM with no SMBIOS serial → set one in Proxmox, type1 |
| “running scripts is disabled on this system” | Set-ExecutionPolicy -Scope Process only applied to the previous window |
Device shows Enabled: No in Entra | Normal — Autopilot placeholder, enables itself at join |