imPC@ndo IT

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

  1. Entra → App registrations → New registration → name it Autopilot-HashUpload, single tenant, no redirect URI.
  2. Note the Application (client) ID and the Directory (tenant) ID.
  3. API permissions → Add → Microsoft Graph → Application permissions — not Delegated — → DeviceManagementServiceConfig.ReadWrite.AllGrant admin consent.
  4. 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.

RiskDetail
The permission is broadDeviceManagementServiceConfig.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 AccessAn 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 historyEverything typed at a PowerShell prompt is written in clear text to %APPDATA%\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
It expires quietlyWhen 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 applicationsAutopilot-HashUpload → Properties → Enabled for users to sign-inNo — 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 .ps1 file 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

SymptomCause
PowerShell returns to the prompt with no outputWAM broker in the defaultuser0 OOBE context → use -UseDeviceAuthentication
AADSTS530035 after a successful MFASecurity Defaults block the device code flow — a flow block, not an identity one
serialNumber is null · 0 devices importedVM 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 EntraNormal — Autopilot placeholder, enables itself at join