If you need to deploy local Hyper-V or VMWare VMs that are enrolling in Intune with native Entra join, we now have a nice modern method to do so by utilizing Autopilot device preparation. The only thing is, we need to create corporate device identifiers for all these VMs in Intune or otherwise our users need to be able to enroll personal devices, which I would not recommend if not required for other reasons.
How do we create these identifiers, if we don’t know anything about the VMs until they actactually boot up at the user? Well, we can write a small PowerShell script that runs during OOBE on these Machines. We can simply add it into the image before we sysprep it and ship it to our users. The user then simply goes through OOBE and enrolls the VM like a physical device.
Backend
Let’s start with the backend, which will add the corporate identifier to Intune via Graph API. We don’t want to directly upload them directly from the VMs, since this would require high valuable credentials stored on the Machines, which we definitely don’t want, so we will work with an Azure Runbook that will handle the interaction with the Graph API, and the only thing that remains on the Machine, is a URL with token, that only allows adding the identifiers, but nothing more.
Azure Automation Account
I will start with the creation of an Azure Automation Account in a fresh resource group, if you already have an Account that you want to use, you can skip this part and jump directly to the assignment of permissions and creating the Runbook.

First thing as usual, we need to go to the Azure Marketplace and search for our Azure Automation Account:

Give it a name:

Make sure to enable the system managed identity, as we will need it later to assign our permissions:

Review your settings and create the Automation Account:

Assign Permissions
To assign the needed graph api permissions, I uploaded a small PowerShell script to GitHub, that just needs the Object ID of the system managed identity:

Just copy the Object ID into the script from GitHub and let it add the permission for: “DeviceManagementServiceConfig.ReadWrite.All”

Runbook
Now that we have everything ready, we can create the Runbook itself:

Give it a name and select PowerShell as Runbook type:


Now we can simply copy the script from GitHub into the editor:

And save and then Publish the Runbook:

Webhook
Last but not least, we need to create the webhook that our client script will use to initiate the upload:


Give it a name and select how long it should be valid and make sure to copy the URL, as you can’t view it later:

No need to configure any additional parameters, we can finally create the webhook:

Client script
On the client / vm side, we just have to copy the client script from GitHub, and just add the webhook url that we created before:

We will save this script to C:\ProgramData\MikeMDM\Upload_Identifier.ps1:

Then we just have to import the TaskScheduler template, that will run the script at startup: template

After that, we can start sysprep generalize and ship the machine to your users:


As soon as the machine boots into oobe, the task is triggered and the upload to the Runbook starts:

If the triggering of the Runbook was successful (indicated by the returned jobid) the scheduled task gets disabled automatically, if it failed it will restart itself after 30s:

Intune
In Intune, we can see the created Corporate Identifier for our VM:


Now we can just create our Autopilot device preparation policy assigned to our users and we are good to go.

Give the policy a name

Assign a device group, which has the Service Principal “Intune Autopilot ConfidentialClient” assigned as owner


Configure the experience to what you need:

Assign the policy to a group of users:

Review the settings and create the profile:

User experience
Since the VM is now known to Intune, our users can simply enroll the VM like they would do on a physical device:





In Intune we then can see, the corporate identifier was used for this deployment:

Conclusion
Leveraging Autopilot device preparation for your local running VMs, eliminate the need of deploying Windows Configuration Designer packages to do the Entra join and allows the user to have the same experience that they are used to.
Leave a Reply