There are many ways to enrol Windows devices into Intune, each works slightly differently and some work better than others depending on your situation. This post aims to run through each, how to use them and when to use them. We all know how often the Entra and Intune portals change so if you are hitting this page and things have moved, drop a message below and I’ll update!
- Pre-Reqs
- GPO
- Autopilot v1
- Autopilot Device prep
- Provisioning Package
- PowerShell Script
- Work or School
- Company Portal
- M365 Apps
- JSON Injection
Pre-Reqs
Let’s start with the pre-requisites before attempting any enrollments:
User licensing
Your users need to have an Intune license which can be found in (amongst others):
EMS E3, Business Premium, M365 E3, E5, A3, A5, F3, F5. This is a valuable resource for licensing: https://m365maps.com/
MDM Enrollment scopes
Within Entra, click “Show More”, Expand Settings and click Mobility:
Click on Microsoft.Intune
Make sure the MDM scope it set to either All, or Some and the group selected contains the users enrolling devices. If the boxes below are blank, click the restore text
You can also do this via Graph:
##Get policies
$policiesuri = "https://graph.microsoft.com/beta/policies/mobileDeviceManagementPolicies"
$policies = getallpagination -url $policiesuri
#$policies = (Invoke-RestMethod -Method GET -Uri $policiesuri -UseBasicParsing -Headers @{Authorization = "Bearer $($Tokenresponse.access_token)"}).value
##If only one, convert to array
if ($policies -isnot [System.Collections.ArrayList]) {
$policies = @($policies)
}
foreach ($policy in $policies) {
$policyid = $policy.Id
$json = @"
{
"appliesTo": "all"
}
"@
$uri = "https://graph.microsoft.com/beta/policies/mobileDeviceManagementPolicies/$policyid"
Invoke-MgGraphRequest -Method PATCH -Uri $uri -Body $json -ContentType "application/json"
}
MDM is set to Intune
This is more for really old tenants, but worth checking. Sometimes the MDM is set to O365 so will block device enrollment. It’s an easy fix, but needs digging into Graph:
After connecting to Graph, this script will check the MDM provider and fix if needed:
write-output "Getting Organisation ID"
$OrgId = (Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/organization" -Method Get -OutputType PSObject).value.id
write-output "Org ID is $orgid"
#Check if Intune already is MDM Authority
write-output "Checking if Intune is MDM"
$mdmAuth = (Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/beta/organization('$OrgId')?`$select=mobiledevicemanagementauthority" -Method Get -OutputType PSObject).mobileDeviceManagementAuthority
#Sets Intune as MDM Authority if not already set
write-output "MDMAuth is $mdmAuth"
if($mdmAuth -notlike "intune")
{
write-output "Setting MDM org to Intune"
Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/organization/$OrgID/setMobileDeviceManagementAuthority" -Method POST
write-output "MDM set"
}
Enrollment Restrictions
Within Intune, just check Corporate devices are allowed (and ideally block personal devices although that will break some options below):
Devices – Enrollment – Device Platform Restriction.
Edit the default All Users policy
Or via Graph:
Write-Output "Getting Device Restrictions Policy ID"
$policyid = (((Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/beta/deviceManagement/deviceEnrollmentConfigurations?`$filter=priority eq 0" -OutputType PSObject).value) | where-object '@odata.type' -eq "#microsoft.graph.deviceEnrollmentPlatformRestrictionsConfiguration").id
Write-Output "Policy ID: $policyid"
##Set URL
$url = "https://graph.microsoft.com/beta/deviceManagement/deviceEnrollmentConfigurations/$policyid"
##Populate JSON
$json = @"
{
"@odata.type": "#microsoft.graph.deviceEnrollmentPlatformRestrictionsConfiguration",
"androidForWorkRestriction": {
"blockedManufacturers": [],
"osMaximumVersion": "",
"osMinimumVersion": "",
"personalDeviceEnrollmentBlocked": true,
"platformBlocked": false
},
"androidRestriction": {
"blockedManufacturers": [],
"osMaximumVersion": "",
"osMinimumVersion": "",
"personalDeviceEnrollmentBlocked": false,
"platformBlocked": true
},
"macOSRestriction": {
"blockedManufacturers": [],
"osMaximumVersion": null,
"osMinimumVersion": null,
"personalDeviceEnrollmentBlocked": true,
"platformBlocked": false
},
"windowsHomeSkuRestriction": {
"blockedManufacturers": [],
"osMaximumVersion": null,
"osMinimumVersion": null,
"personalDeviceEnrollmentBlocked": true,
"platformBlocked": false
},
"windowsRestriction": {
"blockedManufacturers": [],
"osMaximumVersion": "",
"osMinimumVersion": "",
"personalDeviceEnrollmentBlocked": true,
"platformBlocked": false
}
}
"@
##Update Policy
write-output "Updating Device Restrictions Policy"
Invoke-MgGraphRequest -Uri $url -Method PATCH -Body $json -ContentType "application/json"
Write-Output "Device Restrictions Policy updated"
Now we can start looking at enrollment
GPO
If your devices are currently domain joined, this is the easiest way to get them into Intune (and Autopilot)
Simply create a new GPO and set this:
Computer Configuration > Administrative Templates > Windows Components > MDM > Enable automatic MDM enrollment using default Microsoft Entra credentials.
Convert Existing Devices
If you also want these devices to show in Autopilot Devices, in your Autopilot Profile, assign to all devices and set “Convert all targeted devices to Autopilot” to Yes:
This method adds devices to Intune and Autopilot but doesn’t give them admin rights or anything unusual. I usually suggest creating an OU with Inheritence Disabled to avoid any clashes between GPOs and Intune Policies.
More importantly, no device wipe is needed.
Further info: https://learn.microsoft.com/en-us/windows/client-management/enroll-a-windows-10-device-automatically-using-group-policy
Autopilot – Online and CSV
This is probably the most used approach to enrol devices into Intune via Autopilot during OOBE and is done by enrolling the device hash into the Autopilot service. Then when the device is wiped, during OOBE, it checks in and applies Intune policies etc. as per your ESP.
Starting with the quicker online method, this can be run either interactively, or if your enrolling staff do not have permissions, can be used with an Entra App reg:
set-executionpolicy Unrestricted
install-script get-windowsautopilotinfocommunity
get-windowsautopilotinfocommunity.ps1 -online -tenantID xxx -AppID xxx -AppSecret xxx
Optionally you can add “-assign” to wait for assignment to complete and “-sysprep” to kick off a sysprep and re-enrol when complete (amongst other option)
Alternatively, you can run the script to extract the hash into CSV format to then add manually into Autopilot:
set-executionpolicy Unrestricted
install-script get-windowsautopilotinfocommunity
get-windowsautopilotinfocommunity.ps1 -outputfile c:\temp\autopilot.csv
In Intune, navigate to Devices – Enrollment – Autopilot Devices
Click Import
Upload the CSV file
This is an excellent way to add new devices, or rebuild existing devices to cloud native Entra Joined. You have full control over the device and it follows your profile and ESP.
If you want an Entra group to target Autopilot enrolled devices, use this device query:
(device.devicePhysicalIDs -any (_ -startswith "[ZTDid]"))
Further information:
https://learn.microsoft.com/en-us/autopilot/add-devices
Autopilot Device Prep
Known in the community as Autopilot v2, it makes the enrollment easier for the user, but is a little more tricky to configure.
NOTE: If a device is enrolled into Autopilot with device hash (or convert existing devices), this will win over Device Prep so you’ll need to remove the device from Autopilot Devices first.
The first thing we need to do is create an Entra group with a specific application set as the owner. This is what Autopilot users to populate devices into the group (no more ztid dynamic group needed)
Create a new static assigned group with whatever name you choose:
Click Owners
Search for this ID: “f1346770-5b25-470b-88bd-d5744ab7952c” which should find “Intune Autopilot ConfidentialClient”:
If it doesn’t, run this script:
$spid = "f1346770-5b25-470b-88bd-d5744ab7952c"
write-output "Checking if Enterprise App exists"
$lookforsp = get-mgserviceprincipal -filter "AppID eq '$spid'"
if (!$lookforsp) {
write-output "Enterprise App does not exist, creating"
$ServicePrincipalId = @{
"AppId" = "$spid"
}
$appregid = New-MgServicePrincipal -BodyParameter $ServicePrincipalId
write-output "Enterprise App created"
}
We also need a second User group which allows users to enrol devices. This can be static or dynamic and called anything as long as it is a user group as it’s pre-device.
Now in Intune click Devices – Enrollment – Device Preparation Policies
Create a new profile and after filling in the basic details, select the device group we created earlier (with the owner)
The Configuration Settings are the new ESP, set which scripts and apps MUST be available before a user logs in and any other required settings (please don’t make them admins)
When you reach assignments, select the user group created which holds the users allowed to enrol.
Technically this is all you need BUT you will need to allow Personal Device enrollment which is always risky. Therefore, we can add device details so Autopilot knows it’s a corporate device, similar to the hash, but simpler.
We can grab the details with a one-liner and output to a CSV (source)
(Get-CimInstance Win32_ComputerSystem).Manufacturer+','+(Get-CimInstance Win32_ComputerSystem).Model+','+(Get-CimInstance Win32_BIOS).SerialNumber
Or you can use the same script as for v1 and either add directly online, or export to csv:
set-executionpolicy Unrestricted
install-script get-windowsautopilotinfocommunity
get-windowsautopilotinfocommunity.ps1 -online -identifier
Offline:
set-executionpolicy Unrestricted
install-script get-windowsautopilotinfocommunity
get-windowsautopilotinfocommunity.ps1 -identifier -outputfile c:\temp\device.csv
Then in the Intune portal, navigate to Devices – Enrollment and click the Corporate Device Identifiers tab:
Click Add – Upload CSV file and in the drop-down select “Manufacturer, Model and Serial number (windows only)”
That’s it, now simply enrol via OOBE and away you go.
There are currently some limitations though to device prep:
- Windows 11 only
- Entra ID join only (not a bad thing)
- No pre-provisioning
- No kiosk style self-deployment
- No grouptags
More info:
https://learn.microsoft.com/en-us/autopilot/device-preparation/overview
Provisioning Package
What about a non-domain joined device where you don’t want to wipe and reload? There are some options for that, they aren’t quite as fluid, but they are still an option.
The first is to deploy a provisioning package to devices. For this you will need Windows Configuration Designer from the ADK to create a package.
Rather than re-write the whole process, there is an end-to-end process here:
It’s worth noting that an administrator will need to run the package on each machine so it will need some effort on the IT side and if they had admin rights before, they will still have them afterwards (you can remove with an Intune policy). You’re obviously also inheriting any of the previous rubbish left on the device. It works in a pinch, but isn’t ideal.
As with GPO, you will probably then want to convert these to Autopilot devices so you don’t have to do this again.
PS Script
If you have RMM access to these devices, you can deploy a PowerShell script to enrol them into Intune.
Fortunately Rudy has saved me a job here and written a selection of scripts which you can find here:
Running this script in the system context will sort the enrollment:
# Set MDM Enrollment URL's
$key = 'SYSTEM\CurrentControlSet\Control\CloudDomainJoin\TenantInfo\*'
try{
$keyinfo = Get-Item "HKLM:\$key"
}
catch{
Write-Host "Tenant ID is not found!"
exit 1001
}
$url = $keyinfo.name
$url = $url.Split("\")[-1]
$path = "HKLM:\SYSTEM\CurrentControlSet\Control\CloudDomainJoin\TenantInfo\$url"
if(!(Test-Path $path)){
Write-Host "KEY $path not found!"
exit 1001
}else{
try{
Get-ItemProperty $path -Name MdmEnrollmentUrl
}
catch{
Write_Host "MDM Enrollment registry keys not found. Registering now..."
New-ItemProperty -LiteralPath $path -Name 'MdmEnrollmentUrl' -Value 'https://enrollment.manage.microsoft.com/enrollmentserver/discovery.svc' -PropertyType String -Force -ea SilentlyContinue;
New-ItemProperty -LiteralPath $path -Name 'MdmTermsOfUseUrl' -Value 'https://portal.manage.microsoft.com/TermsofUse.aspx' -PropertyType String -Force -ea SilentlyContinue;
New-ItemProperty -LiteralPath $path -Name 'MdmComplianceUrl' -Value 'https://portal.manage.microsoft.com/?portalAction=Compliance' -PropertyType String -Force -ea SilentlyContinue;
}
finally{
# Trigger AutoEnroll with the deviceenroller
try{
C:\Windows\system32\deviceenroller.exe /c /AutoEnrollMDM
Write-Host "Device is performing the MDM enrollment!"
exit 0
}
catch{
Write-Host "Something went wrong (C:\Windows\system32\deviceenroller.exe)"
exit 1001
}
}
}
exit 0
The same catches apply as with the provisioning package, it isn’t a clean build and you need to watch for any lingering admin rights. The devices will also need to already be listed in Entra, but that usually happens when they sign into M365 apps.
Work or School
Users can navigate to Settings – Accounts – Access Work or School – Connect
It technically works, but devices will be registered as personal and if you have that blocked your users will get this error:
Not to mention expecting your users to fill in the settings properly…
Probably best avoided
Company Portal
For this you’ll need to somehow deploy the Company Portal MS Store app, tell the users to sign in and make sure this box is ticked:
As with the method above, you will need Personal Devices enabled and they will enrol as personal and not corporate so you’ll need to change them within Intune. They’ll also retain admin settings and anything else on the device.
When signing into M365 apps
When signing into M365 apps, your users could tick the box to Allow my organisation to manage my device (the same as when installing company portal), but the same applies, you’ll need to unblock personal device enrollment which means they could sign in to these apps from any device and enrol into the tenant.
I’ve looked at these options here:
JSON
This used to be an excellent approach for use with MDT or SCCM. You could create a JSON containing the Autopilot details and inject during the task sequence which would add the device for you automatically.
Sadly it was discovered that anyone could easily create the JSON and enrol non-managed devices into a tenant so to avoid this issue, to use JSON injection you need to allow Personal Devices to be enrolled. It isn’t ideal, but it does still work.
To generate the JSON use this command:
$graphApiVersion = "beta"
$Resource = "deviceManagement/windowsAutopilotDeploymentProfiles"
$uri = "https://graph.microsoft.com/$graphApiVersion/$Resource"
$response = Invoke-MGGraphRequest -Uri $uri -Method Get -OutputType PSObject
$profiles = $response.value
$profilesNextLink = $response."@odata.nextLink"
while ($null -ne $profilesNextLink) {
$profilesResponse = (Invoke-MGGraphRequest -Uri $profilesNextLink -Method Get -outputType PSObject)
$profilesNextLink = $profilesResponse."@odata.nextLink"
$profiles += $profilesResponse.value
}
$selectedprofile = $profiles | out-gridview -passthru -title "Select a profile"
Make a note of the ID and export it with this:
$graphApiVersion = "beta"
$Resource = "deviceManagement/windowsAutopilotDeploymentProfiles"
$uri = "https://graph.microsoft.com/$graphApiVersion/$Resource/$id"
$approfile = Invoke-MGGraphRequest -Uri $uri -Method Get -OutputType PSObject
I have a tool here to automatically create an ISO with the JSON injected:
You can also use the excellent OSDCloud for this:
More information:
https://learn.microsoft.com/en-us/autopilot/existing-devices
Conclusion
There is no “best” approach, it is whatever suits your environment. Ideally a fresh start with Autopilot (v1 or 2), but if that isn’t an option, GPO or PS Script depending on domain join status are perfectly acceptable options.
Hopefully this has been useful, if I’ve missed anything, add it in the comments below
GPO with co-management. Should this be user or device credential?
You want user credentials for those if they are standard one user per device
What is the pros of Autopilot v2?
The main one is you don’t need to harvest the hash so users could go and grab any machine and just tell you the serial etc. which are normally printed on the boxes themselves
I second this. During the OOBE the user just presses cntrl + shift + D and the serial Number, manufacturer and model is all presented for them to pass to the IT manager to update Intune corporate identifiers. Just performed this process today, for an employee and it worked.
Unfortunately, I had to also add the steps of upgrading to win 11 pro and updating via the CMD line before it could work. but should be less of an issue as device prep becomes more mainstream and assuming they buy laptops already set to win 11 pro or above.