Intune remediation scripts fail before the fix even runs
The detection script controls whether remediation happens. Use a narrow state check, explicit exit codes, useful output, and repeatable tests.
The detection script is the control plane for an Intune remediation package. If detection reports the wrong state, the repair either never runs or runs on devices that were already compliant.
Microsoft’s Remediations documentation defines the key contract: the remediation script runs only when detection exits with code 1. Any other exit code does not trigger remediation.
Make detection answer one question
A detection script should decide whether the device currently satisfies the state owned by this package. Keep that check narrow, deterministic, and read-only.
$path = "HKLM:\SOFTWARE\Contoso\DeviceState"
try {
$propertyParams = @{
Path = $path
Name = "Configured"
ErrorAction = "Stop"
}
$value = Get-ItemPropertyValue @propertyParams
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Output "Not compliant: Configured value is missing"
exit 1
} catch {
Write-Error "Detection failed: $($_.Exception.Message)"
exit 2
}
if ($value -eq 1) {
Write-Output "Compliant: Configured=1"
exit 0
}
Write-Output "Not compliant: Configured=$value"
exit 1
This separates three outcomes:
0: the expected state exists; no repair is needed.1: the owned state is wrong or missing; run remediation.- another code: detection itself failed; do not disguise that failure as ordinary non-compliance.
The third outcome does not run remediation, so make its output useful for investigation.
Keep repair logic out of detection
Detection should not create registry values, restart services, install files, or otherwise repair the device. A script that fixes the state and then reports compliance hides the remediation path from reporting and makes failures difficult to reproduce.
The remediation script should make the smallest necessary change and remain safe to run again. After repair, the same detection check should return 0. That second-run behavior is the practical test for idempotence.
Treat output as operational data
Microsoft limits script output to 2,048 characters. Use that space for the state that was checked, the value found, and a concise failure reason. Avoid dumping large objects, transcripts, personal data, secrets, or unrelated diagnostics.
Scripts must be UTF-8 encoded. When signature enforcement is enabled, Microsoft specifies UTF-8 without a byte order mark. Signed scripts also run under the device’s PowerShell execution policy, so certificate trust and execution-policy behavior belong in the pilot plan.
Do not put reboot commands in detection or remediation scripts. If a change needs a restart, report that requirement and manage it through an appropriate device workflow.
Test the package as a state machine
Before broad assignment, exercise at least these paths:
- A compliant device returns
0and does not run remediation. - A non-compliant device returns
1, runs remediation, and returns0on the next check. - A detection exception is visible and does not look like compliance.
- A remediation failure leaves enough output to explain what was attempted.
- Running remediation twice does not cause damage or duplicate state.
- The script behaves correctly under the configured user context, PowerShell architecture, and signature setting.
Scheduling changes the blast radius
Assignments can run once, hourly, or daily. Missed scheduled runs execute when the device next comes online. Start with a small group and a schedule that leaves time to inspect output before repetition amplifies a bad detection rule.
This article was not lab-tested. Verify current licensing, prerequisites, script settings, schedule behavior, and reporting in your tenant before production deployment.
// source record
Sources
- Remediations Microsoft Learn · checked 12 June 2026