Uploading Autopilot Hardware hashes using Azure Automation


Intune/Endpoint Manager has been one of the best device management tools for a few years now and a lot of businesses has already migrated to or started to make us of it. But there are still plenty of businesses that are using others tools and is planning a move to Intune and Azure AD Joined devices and would like to upload all their devices to Autopilot before reinstalling their clients and are looking for a easy way to get all of their devices into Autopilot.


As with a lot of things there are multiple ways to go about solving an issue and and I’m by no way saying this is the best way of accomplishing an autopilot import but today we are focusing on doing this as automatically as possible for as many devices as we need to. Nicolaj over at ConfigMgr amongst others has different ways of achieving this as well and has inspired this solution.

So the goal is to collect the hardware hashes for each device using a script and then get it imported to Autopilot with the ultimate goal of Autopilot creating a better deployment to Intune for Azure AD Joined devices when we reinstall them.

To explain how we are going to get there we’re going to utilize MS Graph & an Azure Automation Account and some way to run a script on the devices(GPO, RMM or otherwise). The script will collect the hardware hash and using a webhook in it will push the information to the Automation Account and then using MS Graph it will import it into Autopilot.

Since my last lackluster Visio Sketch was such a hit I will provide a new lackluster sketch to visualize this:

Script runs on the device through some method and it collects the Hardware Hash and uploads it to the Automation Account, authenticate using the Enterprise Application and query Windows Autopilot via MS Graph

Note: As a reader pointed out this solution is focused on getting existing clients into Autopilot, for new devices it’s recommended to purchase that service from an OEM or Microsoft Autopilot partner

What we need

  • An Enterprise Application
    • We need to be able to import & sync our devices to Autopilot
  • An Azure Automation Account
    • Here we receive the Hardware hash from the devices through a webhook and then using MS Graph import it into Autopilot
  • A Script to run on the device
    • The script will run on the device to collect the hardware hash and post it to the Automation Account. Modify the variables for different group tags / order id’s you want to use in Autopilot
  • Some way of executing the script on the device

Enterprise Application

Firstly we need the Enterprise application, this will be used to authenticate against MS Graph in order to import a device into & sync Autopilot.

  1. Open Azure AD
  2. Navigate to App registrations
  3. Select New registration
  4. Select Accounts in this organizational directory only
  5. Select a fitting Name for your application, I chose “WindowsAutopilotImport” but it doesn’t matter
  6. Register

When the Application is finished creating we need to make Note of the Application ID and the Tenant ID visible on the Overview tab

Application ID and Tenant ID on the Overview tab

Now we need to assign the permissions we need for the Application to be able to import a device into Autopilot & then trigger an Autopilot sync.
Navigate to the API permissions tab

  1. Select Add a permission
  2. Chose Microsoft Graph
  3. Chose Application permissions
  4. Search DeviceManagementServiceConfig.ReadWrite.All
  5. Mark the box for DeviceManagementServiceConfig.ReadWrite.All under DeviceManagementServiceConfig
  6. Add permissions
  7. Review that the correct permissions have been granted then Select Grant admin consent for “Tenant”

Now we just need to create a way for us to authenticate against the Application, navigate to the Certificates & secrets tab

  1. Make sure you have Client secrets highlighted
  2. Select New client secret
  3. Type a descriptive name for the secret and select an expiration, I chose 12 months and entered “WindowsAutopilotImport” in the description but it doesn’t matter
  4. Add
  5. Make note of the Value, Secret ID, Description & Expiration date
    1. This will be the only time the Value is visible, after leaving this tab the secret is gone forever
    2. Enter the information in e.g a Password manager solution for safe keeping

Automation Account

Onwards to the next part in our solution, the Automation Account. The Automation Account will add Azure capacity and therefore cost, however, Automation includes 500 minutes of free processing time and we will be able to use those to not add cost. If you want to know more about costs in Azure feel free to check it out using Azure Calculator.

First we’re going to start by creating our Automation Account that will house our script. If you already have an Automation Account feel free to use that and skip this bit.

Creating the Automation Account

  1. Start off by searching for Automation Account in Azure
  2. Select Create
  3. Chose a fitting Subscription, Resource Group, and Region
  4. Select a fitting Name for your Automation Account, I chose “IntuneAutomation” but it doesn’t matter
  5. For Managed Identities’ we can uncheck both boxes
  6. Under Networking you can chose whatever supports your infrastructure, recommended to have Private Access but for this instance I chose “Public Access”
  7. Go through the rest of the tabs at your own preference and then Create

When the Automation Account is finished creating we can now head into it to Upload our Script & Create our Variables

So first we’re gonna create our Variables for the script, one of the cool things about an Automation Account is you can create variables for your script Outside of the script and then import that variable into any script in your Automation Account. So that’s what we’re gonna start off doing with our Enterprise Application information.

  1. Select the blade Variables
  2. Select Add a variable
  3. Now we get to name our Variable, this name must reflect the name of the Variable we import in the script. You can chose differently from what I chose as long as you update those values in the Script.
    1. Enter the name TenantID and the type String and the Value we collected earlier
    2. Enter the name WindowsAutopilotImportApplicationID and the type String and the Value we collected earlier
    3. Enter the name WindowsAutopilotImportAppSecret and the type String and the Value we collected earlier, on this Variable chose EncryptedYes
    4. Enter the name AutopilotWebhookPassword and the type String and for Value generate a strong string / password some way and input it here, remember it because we need it for later, on this Variable chose EncryptedYes
Variables created in the Automation Account ready to be imported into any script we want

Now with our Variables done we can head onto uploading the script.

  1. Select the blade Runbooks
  2. Select Create a runbook
  3. Select a fitting Name for your Automation Account, I chose “CreateWindowsAutopilotDevice” but it doesn’t matter
  4. For Runbook type select Powershell and for Runtime version select 5.1 (As the time of writing this 7.1 is still in preview and untested by me but if you want to use 7.1 it will probably work just as well), Enter any description you want then select Create
  5. When faced with the blank canvas we can now paste in our script, we do not need to change anything since the variables that we normally would need to change will be imported from the Automation Account
  6. Save & Publish

Now we have the Script all done with the right permissions to complete the tasks we want it to, now we also need a way to trigger it.

  1. Enter the runbook you just created
  2. Select the blade Webhooks
  3. Select Add Webhook
  4. Select Create new webhook
  5. Select a fitting Name for your webhook, I chose “WindowsAutopilotImport” but it doesn’t matter
  6. Select how long you want it to be enabled for, I chose the same as my secret in the Enterprise Application, 12 months.
  7. Make note of the URL
    1. This will be the only time the URL is visible, after leaving this tab the URL is gone forever
    2. Enter the URL in e.g a Password manager solution for safe keeping
  8. Select OK
  9. Select Configure parameters and run settings
  10. Make sure its set to Run on Azure
  11. Select OK
  12. Select Create

Hardware hash uploading script

The final part of this solution is to construct the script that will run on the devices that will collect the hardware hashes and then post them to the Webhook we just created. The script is really simple, it collects the SerialNumber, DeviceHashData & ProductKey and then posts it.

The script needs to be run elevated, either as system or as an administrator then it just needs to be edited on a few lines in order to get it running

  • GroupTag (Line 18) should reflect whatever Group Tag you want for your device in Autopilot, if you want to leave it blank also comment out Line 60
  • WebHookUrl (Line 19) is the Webhook URL we saved earlier
  • WebhookPassword (Line 20) should be the WebhookPassword we generated earlier

Trying it out

Trying it out is really simple, just launch an elevated PowerShell console on any device you want to Import and run the Upload script. Once the script is ran you should be able to se the job created in the Automation Account.

Select the blade Jobs in your Automation Account and you should see it as Completed or Running, hopefully not failed. If you enter the Job you can view the logs and see what’s going on. Once you clicked on the Job you can select the All Logs tab and the table shows all the details

As you can see it takes a few minutes to verify the device has been imported successfully and then we get to see at the last row that it has. If there is anything that prevents it it should generate and error and you would be able to see the job has failed.

After the job has been ran we should now be able to find our device in Windows Autopilot!

Head over to Endpoint Manager & Autopilot and you should be able to find it there.

Device imported in Autopilot



As always I would love if anyone comes up with ways to improve this. There is a clear way to improve this with including a check in the device upload script to check if the device has already been imported to autopilot if you are running the script on the same device multiple times. I just didn’t include it in this post because I didn’t want to get unnecessarily long and complicated. If there is anyone who wants me to post that solution I can do an update to this. I would be ever so grateful for feedback, comments or ideas how to improve upon this further

Thanks for reading

This Post Has 6 Comments

  1. Saqibs

    Viktor, thank you for this solution, I’ve just implemented it in our einvornment and it’s importing well. I really like how your solutions does not require a service account with the Intune Admin role assigned, which is what I’ve seen in another solution. I’ve added a small menu to the user side script to allow our tech’s to select a group tag from a numbered menu. Will keep you posted if anything else pops up.

  2. Lamont Greene

    I have tried to get this to work, however I am not seeing the device in my AutoPilot. Has anyone run into this issue using this script?

  3. Saqibs

    Thanks Viktor this was really helpful. I used this method instead of another one posted online which requires used of an account with the Intune administrator account, which i wanted to avoid. I’ve added a small scripted menu to allow our tech team to select the group tag from a list before the running the script, it’s working great, thanks.

  4. Chris Bond

    Thanks very much for this Viktor

    Would very much appreciate it if you could amend this/add a post with the check to see if the device has already been uploaded into Autopilot if at all possible!

  5. Lubos

    Hello Viktor, thank you very much for sharing.
    Your article is the best starting point to webhooks and Azure Automation runbooks an IT guy can wish for.

  6. Habeeb

    This worked perfectly for me thanks

Leave a Reply