Remediate MDM Enrollment Issues Safely with PowerShell · CloudEngineerHub
Detection & Remediation10 min read5 views
How to Remediate MDM Enrollment Issues Safely with PowerShell
Build a conservative PowerShell detection and remediation pair for partial MDM enrollment state: missing sync tasks, OMADM accounts, or client certificates, with an honest path to re-enrollment.
C
CloudEngineerHub Team
Published: September 18, 2026· Last Updated: September 28, 2026·10 min read
A device that half-enrolled into Intune is one of the most expensive support calls an EUC team can draw. The registry says the device is enrolled, the admin center might even list it, but sync never quite completes, Win32 apps stay queued, and compliance sits at unknown. The root of the problem is usually a partial or stale MDM enrollment: the enrollment key exists, but the artifacts that make enrollment actually work, such as the sync scheduled tasks and the MDM client certificate, are missing or expired. Nothing crashes. The device just quietly stops behaving like a managed endpoint.
Visual Walkthrough
Every reliable detection script follows this exact structure — copy it.
Decision TreeDetection Script Anatomy — The Exit-Code Contract5/5
Decision gate
Is the state healthy?
One question, one exit code — keep detection dumb and honest.
Healthy → exit 0
1
Test the condition
Single cmdlet or property read; no side effects, no output noise.
2
Exit 0, no output
Silence is the success contract — Intune treats it as compliant.
Unhealthy → exit 1
1
Emit one evidence line
Write the observed value — your future self reads the report.
2
Exit 1
Signals "needs remediation"; the paired fix script may now run.
3
Remediate idempotently
Fix script is safe to run repeatedly; no reboots without consent.
4
Exit 0 after fix
Next detection run proves remediation worked.
Detection Script Anatomy — The Exit-Code Contract. Gate: Is the state healthy? — Healthy → exit 0: Test the condition — Healthy → exit 0: Exit 0, no output — Unhealthy → exit 1: Emit one evidence line — Unhealthy → exit 1: Exit 1 — Unhealthy → exit 1: Remediate idempotently — Unhealthy → exit 1: Exit 0 after fix
C
CloudEngineerHub Team
Author
The CloudEngineerHub editorial team — Microsoft endpoint management and cloud engineers writing hands-on guides on Intune, Azure, Entra ID, Autopilot, Defender and PowerShell. Every article is reviewed against current Microsoft documentation.
This article gives you a detection and remediation script pair you can deploy through Intune Scripts and remediations. Detection reports exactly which enrollment artifacts are present and which are missing, per enrollment GUID. Remediation is deliberately conservative: it re-triggers the EnterpriseMgmt sync scheduled task, which is the supported local lever, and it refuses to guess at anything bigger. Cases that require certificate re-issuance or a full re-enrollment are reported as such, because those are admin-side actions, and pretending otherwise is how one broken device becomes three broken devices.
Everything assumes the environment your scripts really run in: 64-bit Windows PowerShell 5.1 as SYSTEM, structured logging to C:\ProgramData\Company\Logs\, and exit codes that follow the Intune remediation convention.
Symptoms
The pattern shows up as "this device is kind of managed" complaints:
The device appears in the Intune admin center but last check-in is old, or sync from the portal succeeds while the device clearly did not process anything new.
Required apps and policies report as pending or not applicable even though the user sees the company portal.
Company Portal shows the device as out of compliance for no visible reason.
On the device, HKLM:\SOFTWARE\Microsoft\Enrollments contains GUID subkeys, but \Microsoft\Windows\EnterpriseMgmt\<GUID>\ has no scheduled task folder, or the machine Personal certificate store has no valid certificate issued by the Intune MDM Device CA.
More than one enrollment GUID key exists from repeated re-enrollment attempts, and none of them has a complete artifact set.
Possible Causes
Enrollment state degrades in a handful of recognizable ways:
Interrupted first enrollment
The enrollment handshake writes the Enrollments key early and the certificate, OMADM account, and sync tasks later. A crash, network drop, or power loss in the middle leaves keys without artifacts. The device then looks enrolled to scripts that only check the registry.
Cleanup tooling deleted enrollment support files
Agent cleanup scripts, "debloat" packages, and aggressive disk cleaners sometimes delete the EnterpriseMgmt task folder or prune machine certificates. The registry keys survive, so detection based on registry alone reports healthy while the actual client is gone.
Certificate expiry or revocation
MDM client certificates have a finite lifetime. If the device cannot renew (long offline period, clock skew, broken trust), the certificate expires while the enrollment key and tasks remain, and every MDM call fails authentication.
Stale enrollments after re-imaging or retirement
Devices rebuilt from images or re-enrolled after a retire sometimes carry old GUID keys forward. Multiple EnrollmentType 6 keys are not automatically a problem, but when the newest enrollment is incomplete, the leftovers make diagnosis harder.
Admin-side device record problems
A device whose Intune device record was deleted, whose user lost their license, or whose Entra device object was disabled can still hold complete-looking local state. Local repair cannot fix this; the enrollment must be rebuilt from the service side.
Detection Script
The script below is read-only and completes in a few seconds. It runs in 64-bit SYSTEM context and evaluates, in order: enrollment keys, the EnterpriseMgmt task folder and newest sync run per GUID, the OMADM account, and the validity of the MDM client certificate.
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#Requires -RunAsAdministrator
[CmdletBinding()]
param()
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
<#
.SYNOPSIS
Detection script: identifies partial or stale Intune MDM enrollment state.
.DESCRIPTION
A complete device-managed MDM enrollment leaves three local artifacts:
1. A GUID subkey under HKLM:\SOFTWARE\Microsoft\Enrollments with
EnrollmentType 6.
2. A scheduled task folder \Microsoft\Windows\EnterpriseMgmt\<GUID>\
holding the enrollment's sync tasks.
3. An OMADM account key under HKLM:\SOFTWARE\Microsoft\Provisioning\
OMADM\Accounts\<GUID> and a valid MDM client certificate issued by
the "Microsoft Intune MDM Device CA"in the LocalMachine\My store.
When keys exist but certificates or tasks are missing, the device is in a
partial enrollment state: it looks enrolled to some tooling, but sync,
certificate renewal, and policy application fail in confusing ways.
.NOTES
Intended for Intune Scripts and Remediations, 64-bit SYSTEM context.
This script NEVER changes the system. Exit 0 = enrollment artifacts
complete, 1 = partial or stale enrollment state, 2 = no device-managed
MDM enrollment found, 3 = unexpected error.
#>$logDir = 'C:\ProgramData\Company\Logs'$logFile = Join-Path $logDir'MdmEnrollmentDetection.log'$enrollmentsPath = 'HKLM:\SOFTWARE\Microsoft\Enrollments'$omadmAccountsPath = 'HKLM:\SOFTWARE\Microsoft\Provisioning\OMADM\Accounts'$enterpriseTaskRoot = '\Microsoft\Windows\EnterpriseMgmt'function Write-DetectionLog {
param([Parameter(Mandatory)][string] $Level, [Parameter(Mandatory)][string] $Message)
if (-not (Test-Path $logDir)) { New-Item -Path$logDir -ItemType Directory -Force | Out-Null }
"$([DateTime]::UtcNow.ToString('o')) [$Level] $Message" | Out-File -FilePath$logFile -Append -Encoding utf8
}
function Get-MdmEnrollmentGuid {
# Returns the PSChildName of every EnrollmentType 6 (device-managed MDM) # enrollment key. Stale keys from previous enrollments are included on # purpose: they are exactly what this check is hunting for.$found = @()
foreach ($keyin (Get-ChildItem -Path$enrollmentsPath -ErrorAction SilentlyContinue)) {
if ($key.PSChildName -notmatch'^[0-9a-fA-F]{32}$') { continue }
$prop = Get-ItemProperty -Path$key.PSPath -Name EnrollmentType -ErrorAction SilentlyContinue
if ($null -ne$prop -and$prop.EnrollmentType -eq6) { $found += $key.PSChildName }
}
return , $found
}
function Get-NewestSyncTaskRun {
param([Parameter(Mandatory)][string] $EnrollmentGuid)
$newest = [DateTime]::MinValue
$tasks = Get-ScheduledTask -TaskPath"$enterpriseTaskRoot\$EnrollmentGuid\" -ErrorAction SilentlyContinue
foreach ($taskin @($tasks)) {
$info = Get-ScheduledTaskInfo -TaskName$task.TaskName -TaskPath$task.TaskPath -ErrorAction SilentlyContinue
if ($null -ne$info -and$info.LastRunTime -gt$newest) { $newest = $info.LastRunTime }
}
return$newest
}
function Test-MdmClientCertificate {
# The enrollment client certificate is issued by the Intune MDM device CA. # The script validates presence and validity device-wide; it does not try # to correlate a specific certificate thumbprint to a specific GUID key, # because Windows does not expose that mapping in a stable way.$validCerts = @(Get-ChildItem -Path Cert:\LocalMachine\My -ErrorAction SilentlyContinue |
Where-Object { $_.Issuer -like'*Microsoft Intune MDM Device CA*' -and$_.NotAfter -gt (Get-Date) })
return$validCerts
}
try {
Write-DetectionLog 'INFO''MDM enrollment health detection started.'$enrollmentGuids = @(Get-MdmEnrollmentGuid)
Write-DetectionLog 'INFO'"Found $($enrollmentGuids.Count) EnrollmentType 6 enrollment key(s)."if ($enrollmentGuids.Count -eq0) {
Write-DetectionLog 'ERROR''No device-managed MDM enrollment key exists. This device needs enrollment repaired from the Intune/Entra side, not a local fix.'
exit 2
}
$validCerts = @(Test-MdmClientCertificate)
if ($validCerts.Count -eq0) {
Write-DetectionLog 'ERROR''No valid MDM client certificate issued by the Intune MDM Device CA found in LocalMachine\My.'
}
else {
$newestExpiry = ($validCerts | Measure-Object -Property NotAfter -Maximum).Maximum
Write-DetectionLog 'INFO'"Valid MDM client certificate present. Newest expiry: $newestExpiry"
}
$completeEnrollmentFound = $falseforeach ($guidin$enrollmentGuids) {
$taskFolderExists = $false$tasks = Get-ScheduledTask -TaskPath"$enterpriseTaskRoot\$guid\" -ErrorAction SilentlyContinue
if (@($tasks).Count -gt0) { $taskFolderExists = $true }
$omadmPath = Join-Path $omadmAccountsPath$guid$omadmAccountExists = Test-Path -Path$omadmPath$newestRun = [DateTime]::MinValue
if ($taskFolderExists) { $newestRun = Get-NewestSyncTaskRun -EnrollmentGuid$guid }
Write-DetectionLog 'INFO'"Enrollment $guid : TaskFolder=$taskFolderExists OmadmAccount=$omadmAccountExists NewestSyncRun=$newestRun"if ($taskFolderExists -and$omadmAccountExists) { $completeEnrollmentFound = $true }
}
if ($completeEnrollmentFound -and$validCerts.Count -gt0) {
Write-DetectionLog 'INFO''MDM enrollment artifacts are complete. Enrollment state is healthy.'
exit 0
}
Write-DetectionLog 'ERROR''Partial or stale MDM enrollment state detected: enrollment keys exist but scheduled tasks, OMADM account, or the client certificate are missing. Local sync can be re-triggered; certificate or key repair requires re-enrollment.'
exit 1
}
catch {
Write-DetectionLog 'ERROR'"Unexpected failure: $($_.Exception.Message)"
exit 3
}
finally {
Write-DetectionLog 'INFO''MDM enrollment health detection finished.'
}
Detection Logic
The detection walks the enrollment artifacts in the order Windows creates them.
Enrollment keys. It enumerates HKLM:\SOFTWARE\Microsoft\Enrollments and collects GUID subkeys whose EnrollmentType value is 6, which identifies device-managed MDM enrollment. Keys that are not 32-hex GUIDs are skipped. Zero such keys means the device is not MDM enrolled at all, which is exit code 2: the fix is enrollment or join repair from the Intune/Entra side.
Sync task folder. For each GUID it checks \Microsoft\Windows\EnterpriseMgmt\<GUID>\ with Get-ScheduledTask. A healthy enrollment always has a task folder there; its absence means the enrollment's runtime plumbing was removed or never created.
Newest sync run. Where the folder exists, the script reads Get-ScheduledTaskInfo across the tasks and logs the newest LastRunTime. This is activity evidence, not a verdict: a recently run task with missing certificates still means a broken enrollment.
OMADM account. It checks HKLM:\SOFTWARE\Microsoft\Provisioning\OMADM\Accounts\<GUID>, the OMA-DM account registration created during enrollment.
Client certificate. It scans Cert:\LocalMachine\My for certificates issued by the Intune MDM Device CA that are not expired. The script validates certificate presence device-wide rather than trying to map a thumbprint to a specific GUID, because Windows does not expose that mapping in a stable, documented way.
A device is healthy only when at least one enrollment GUID has both its task folder and OMADM account, and a valid client certificate exists. Anything less is exit code 1 with a log line naming the missing pieces.
Remediation Script
The remediation does exactly two things and reports the rest. It re-triggers the Schedule* sync task under the enrollment's EnterpriseMgmt folder, waiting up to 60 seconds for the task to confirm it started, and it re-checks the certificate store. It does not delete enrollment keys, does not remove certificates, does not touch scheduled tasks, and does not invoke enrollment binaries by hand. Windows ships deviceenroller.exe in System32, but it is driven by the enrollment infrastructure itself; running enrollment executables manually against a half-dead enrollment is a reliable way to turn a recoverable state into an unrecoverable one. When the certificate is missing or the artifacts are incomplete, the script exits with the code that points you at re-enrollment instead.
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#Requires -RunAsAdministrator
[CmdletBinding()]
param()
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
<#
.SYNOPSIS
Remediation script: applies the safe local repair for partial Intune MDM
enrollment state.
.DESCRIPTION
Scope of this script (deliberately conservative):
- Re-evaluates the enrollment artifacts that detection reported.
- Triggers the EnterpriseMgmt sync scheduled task for the enrollment
GUID when the task folder exists. The sync runs deviceenroller.exe
and the MDM client through their own supported path, which resumes
stalled sync work without touching enrollment data.
- Reports (but never attempts) certificate and key repair: certificate
re-issuance and enrollment key rebuild only happen during a real
re-enrollment, which is an admin-side action.
This script NEVER deletes enrollment keys, certificates, scheduled task
folders, OMADM accounts, or device records. Deleting enrollment state to
"force" a re-enroll leaves the device worse off and is the single most
common cause of permanently broken enrollment this author has seen.
#>$logDir = 'C:\ProgramData\Company\Logs'$logFile = Join-Path $logDir'MdmEnrollmentRemediation.log'$enrollmentsPath = 'HKLM:\SOFTWARE\Microsoft\Enrollments'$omadmAccountsPath = 'HKLM:\SOFTWARE\Microsoft\Provisioning\OMADM\Accounts'$enterpriseTaskRoot = '\Microsoft\Windows\EnterpriseMgmt'function Write-RemediationLog {
param([Parameter(Mandatory)][string] $Level, [Parameter(Mandatory)][string] $Message)
if (-not (Test-Path $logDir)) { New-Item -Path$logDir -ItemType Directory -Force | Out-Null }
"$([DateTime]::UtcNow.ToString('o')) [$Level] $Message" | Out-File -FilePath$logFile -Append -Encoding utf8
}
function Get-MdmEnrollmentGuid {
$found = @()
foreach ($keyin (Get-ChildItem -Path$enrollmentsPath -ErrorAction SilentlyContinue)) {
if ($key.PSChildName -notmatch'^[0-9a-fA-F]{32}$') { continue }
$prop = Get-ItemProperty -Path$key.PSPath -Name EnrollmentType -ErrorAction SilentlyContinue
if ($null -ne$prop -and$prop.EnrollmentType -eq6) { $found += $key.PSChildName }
}
return , $found
}
function Test-MdmClientCertificate {
$validCerts = @(Get-ChildItem -Path Cert:\LocalMachine\My -ErrorAction SilentlyContinue |
Where-Object { $_.Issuer -like'*Microsoft Intune MDM Device CA*' -and$_.NotAfter -gt (Get-Date) })
return$validCerts
}
try {
Write-RemediationLog 'INFO''MDM enrollment remediation run started.'$changed = $false$enrollmentGuids = @(Get-MdmEnrollmentGuid)
if ($enrollmentGuids.Count -eq0) {
Write-RemediationLog 'WARN''No EnrollmentType 6 enrollment key exists. Enrollment must be rebuilt from the Intune/Entra side (join repair or user-driven enrollment). No local change is safe here.'
exit 2
}
# ---- Re-trigger the EnterpriseMgmt sync task for each enrollment GUID ----foreach ($guidin$enrollmentGuids) {
$tasks = Get-ScheduledTask -TaskPath"$enterpriseTaskRoot\$guid\" -ErrorAction SilentlyContinue
if (@($tasks).Count -eq0) {
Write-RemediationLog 'WARN'"Enrollment $guid has no scheduled task folder - enrollment artifacts are missing and only re-enrollment rebuilds them."continue
}
$syncTasks = @($tasks | Where-Object { $_.TaskName -like'Schedule*' -and$_.State -ne'Running' })
if ($syncTasks.Count -eq0) {
Write-RemediationLog 'INFO'"Enrollment $guid : sync task already running or not present in a triggerable state."continue
}
$task = $syncTasks[0]
$beforeInfo = Get-ScheduledTaskInfo -TaskName$task.TaskName -TaskPath$task.TaskPath -ErrorAction SilentlyContinue
$beforeRun = [DateTime]::MinValue
if ($null -ne$beforeInfo) { $beforeRun = $beforeInfo.LastRunTime }
Write-RemediationLog 'INFO'"Triggering sync task '$($task.TaskName)' for enrollment $guid."
Start-ScheduledTask -TaskName$task.TaskName -TaskPath$task.TaskPath -ErrorAction Stop
$changed = $true # Confirm the task actually accepted the trigger within 60 seconds.$confirmed = $false$deadline = (Get-Date).AddSeconds(60)
while ((Get-Date) -lt$deadline) {
Start-Sleep -Seconds5$afterTask = Get-ScheduledTask -TaskName$task.TaskName -TaskPath$task.TaskPath -ErrorAction SilentlyContinue
$afterInfo = Get-ScheduledTaskInfo -TaskName$task.TaskName -TaskPath$task.TaskPath -ErrorAction SilentlyContinue
if ($null -ne$afterTask -and$afterTask.State -eq'Running') { $confirmed = $true; break }
if ($null -ne$afterInfo -and$afterInfo.LastRunTime -gt$beforeRun) { $confirmed = $true; break }
}
if ($confirmed) { Write-RemediationLog 'INFO''Sync task accepted the trigger and is executing.' }
else { Write-RemediationLog 'WARN''Sync task did not confirm the trigger within 60 seconds. Check the task state manually.' }
}
# ---- Client certificate: report only ----$validCerts = @(Test-MdmClientCertificate)
if ($validCerts.Count -eq0) {
Write-RemediationLog 'ERROR''No valid MDM client certificate found. Certificates are issued during enrollment; the supported fix is a re-enrollment performed by an admin with the device user, not a local script action.'
exit 1
}
if ($changed) { Write-RemediationLog 'INFO''MDM enrollment remediation applied.' }
else { Write-RemediationLog 'INFO''Device already compliant - no changes made.' }
exit 0
}
catch {
Write-RemediationLog 'ERROR'"Remediation failed: $($_.Exception.Message)"
exit 3
}
finally {
Write-RemediationLog 'INFO''MDM enrollment remediation run finished.'
}
Be explicit with yourself about what "re-enrollment" means, because it is an admin action, not a script action. A full re-enroll requires either the signed-in user (disconnecting and reconnecting the work or school account in Settings → Accounts → Access work or school, after an admin has cleaned up the device record in Intune) or, for hybrid joined fleets, letting the Automatic-Device-Join task under \Microsoft\Windows\Workplace Join\ re-run with a healthy Entra object. SYSTEM context scripts have no user token and no way to authenticate a new enrollment, which is why this package stops at the sync trigger and reports.
Visual Walkthrough
The exact wire-level path a device takes into Intune management.
Interactive FlowMDM Enrollment — From Discovery to Fully Managed6/6
1
Enrollment discovery
Device resolves enrollment endpoints via DNS and the discovery service.
auth
2
Entra authentication
User or device credential validates; license and enrollment restrictions check.
enroll
3
MDM enrollment URI
Entra issues the MDM enrollment URL; device opens the enrollment session.
4
Certificate issuance
MS DMG provisioning cert (and later SCEP/NDES identities) lands in the store.
registered
5
Intune object created
Device record appears; primary user, ownership and groups attach.
6
Policies stream in
Compliance and configuration profiles apply on first sync.
MDM Enrollment — From Discovery to Fully Managed. 1. Enrollment discovery: Device resolves enrollment endpoints via DNS and the discovery service. — 2. Entra authentication: User or device credential validates; license and enrollment restrictions check. — 3. MDM enrollment URI: Entra issues the MDM enrollment URL; device opens the enrollment session. — 4. Certificate issuance: MS DMG provisioning cert (and later SCEP/NDES identities) lands in the store. — 5. Intune object created: Device record appears; primary user, ownership and groups attach. — 6. Policies stream in: Compliance and configuration profiles apply on first sync.
Deploying Through Intune
In the Microsoft Intune admin center, go to Devices → Scripts and remediations and select + Add on the Windows 10/11 tab.
On Basics, name it something honest such as Remediate - MDM partial enrollment state, and describe the blast radius: "triggers the EnterpriseMgmt sync task; never deletes enrollment data".
On Detection script, upload detect.ps1. Set Run script in 64-bit PowerShell: Yes and Run this script using signed-on credentials: No, so it runs as SYSTEM.
On Remediation script, upload remediate.ps1 with the same context settings. Leave Enforce script signature check: No unless your organization signs internal scripts and has the certificates deployed.
On Schedule, pick Daily while you are stabilizing a rollout or a migration wave, then move to Weekly. Remediations run the remediation script only when the detection script returns a non-zero exit code.
On Assignments, start with a test device group. Do not assign this to groups that contain devices you expect to be unenrolled or retired; their exit code 2 results will pollute your reports.
Review and create, then check Device status after the first run window.
Post-specific notes:
Devices that report exit code 2 are not enrolled. Work them through join and enrollment repair flows instead of re-running this package.
If you are preparing for an Autopilot or migration program, run this package detection-only for a week first to size the problem.
The sync trigger is safe on active devices: it starts a task that already exists and runs regularly.
Exit Codes
Intune runs the detection script and treats any non-zero result as "remediation needed", which schedules the remediation script. The convention used here:
Code
Meaning
0
Enrollment artifacts complete (detection), or the sync trigger succeeded / device already compliant (remediation)
1
Partial or stale enrollment state: task folder, OMADM account, or client certificate missing or expired
2
No device-managed MDM enrollment exists; needs join/enrollment repair from the Intune or Entra side
3
Unexpected script error; inspect the log
Logging
Detection writes to C:\ProgramData\Company\Logs\MdmEnrollmentDetection.log and remediation to C:\ProgramData\Company\Logs\MdmEnrollmentRemediation.log. Each line carries a UTC timestamp, a level (INFO, WARN, ERROR), and a message that names the enrollment GUID where relevant. The directory is created on first use and the files grow by a handful of lines per run, so retention is rarely a concern; rotate monthly if your standards require it. For the service's own view of the same problem, cross-reference the DeviceManagement-Enterprise-Diagnostics-Provider Admin event log and, where the IME is installed, C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\.
Troubleshooting the Script
Exit code 2 on a device you know is enrolled. Check that the script ran in 64-bit PowerShell; registry view redirection does not affect HKLM:\SOFTWARE\Microsoft\Enrollments on x64, but a 32-bit session can still surprise other checks. Then confirm the Enrollments key contents manually.
No log file at all. The script never ran. Verify assignment, last check-in, and that the device is Windows, since Scripts and remediations are Windows-only.
"Sync task did not confirm the trigger" warnings. Look at the task in taskschd.msc under \Microsoft\Windows\EnterpriseMgmt\<GUID>\ and note its state and last result. A disabled task points at cleanup tooling; a task that starts and immediately exits with a failure deserves a look at the DeviceManagement-Enterprise-Diagnostics-Provider Admin log.
Certificate check fails but the device works. Some third-party MDMs use different CA names. This script assumes the Microsoft Intune MDM Device CA issuer string; adjust the filter if your tenant enrolls through a different certificate authority.
Antivirus flags the script. Unsigned remediation content can trip AMSI or tamper rules. Sign internal scripts or agree documented exclusions with your security team before broad rollout.
How to Validate the Fix
On a flagged device, run detect.ps1 manually in an elevated 64-bit PowerShell console. Expect exit code 1 and log lines naming the missing artifact.
Run remediate.ps1 manually. Expect exit code 0 and a log line confirming the sync task accepted the trigger.
Re-run detection. If only the sync trigger was needed, expect 0. If the certificate is missing, expect 1 again, because that genuinely requires re-enrollment.
Trigger a sync from the device or the portal and confirm policies and apps begin processing.
In the admin center, confirm the device moves to "Remediated" or "Compliant" in the package's device status view.
Production Considerations
Execution context. Both scripts run as SYSTEM in 64-bit Windows PowerShell. No user profile paths are touched, and the certificate store read is machine-scoped.
Idempotency. Detection changes nothing. Remediation's only mutation is starting an existing scheduled task; re-running it on a healthy device makes no changes and exits cleanly.
Side effects. Triggering the sync task causes a check-in, which can kick off pending policy application. That is the point, but do not assign this to devices where a burst of sync activity would be disruptive during critical hours.
Security. No credentials or secrets appear in the scripts, and the scripts deliberately implement no capability to delete enrollment state. Have your PowerShell automation SME and security team review them and validate in a test ring before broad production rollout.
Scope control. Assign through a device group you can shrink instantly. Removing the assignment stops future runs without touching any device.
Can the script just delete the enrollment GUID key so the device re-enrolls?
No, and that is intentional. Deleting enrollment state does not trigger re-enrollment by itself; it usually leaves the device with neither a working enrollment nor a clean path to one. Re-enrollment requires either the user's credentials or an admin-side device record cleanup first, so the script reports the condition instead.
Why does detection check the certificate store instead of just the registry?
Because the registry is exactly what lies during a partial enrollment. The Enrollments key is written before the certificate, tasks, and OMADM account exist, so registry-only checks report healthy on devices where every MDM transaction will fail. The certificate is the artifact that proves the enrollment actually finished.
The device has two enrollment GUID keys. Is that a problem?
Not automatically. Leftover keys from previous enrollments are common after re-imaging. Detection treats the device as healthy if any one enrollment has its complete artifact set and a valid certificate exists, and it logs details for every GUID so you can see which one is stale.
Comments
0No comments yet — be the first to share your thoughts.