An Intune remediation script is not licensed by your Intune plan. Microsoft Learn lists the requirement as Windows Enterprise E3 or E5, Windows Education A3 or A5, or Windows Virtual Desktop Access per user, and names no Intune plan anywhere in the prerequisites. The blade is visible to every tenant regardless, which is why the entitlement question usually surfaces only after somebody has written a script and deployed it. This post covers the licence gate, the exit code contract that decides whether anything gets fixed, the documented limits, and the failure modes. Every fact below was verified against Microsoft Learn on 18 September 2026.
Mechanically, these scripts are delivered and executed by the Intune Management Extension, the same agent that runs platform scripts and Win32 app installs, so its logs are where you look when nothing appears to have happened at all. What separates a remediation from an ordinary PowerShell script is the two part contract underneath it. A detection script decides whether a problem exists, and the remediation script runs only if the detection script says so, in one very specific way that almost everybody gets wrong at least once.
What an Intune remediation script requires before it will run
The Remediations article on Microsoft Learn is direct about this. Its wording is that remediations “require users of the devices to have one of the following licenses”, followed by a list of three:
| Entitlement | What Microsoft Learn states |
|---|---|
| Windows Enterprise E3 or E5 | Described as included in Microsoft 365 F3, E3 or E5 |
| Windows Education A3 or A5 | Described as included in Microsoft 365 A3 or A5 |
| Windows Virtual Desktop Access (VDA) per user | Listed on its own, per user |
Read that list again for what is absent from it. There is no Intune Plan 1, no Intune Plan 2, and no Intune Suite. The gate is a Windows client entitlement attached to the user, not an endpoint management entitlement attached to the tenant. Microsoft 365 Business Premium does not appear on the list either, and that is the single most expensive assumption in this feature, because Business Premium does carry Intune and the blade therefore looks exactly as available as it does in an E3 tenant.
The supporting evidence is on a second page. The Intune advanced capabilities page enumerates what Plan 2 and the Intune Suite add: Firmware Over-the-Air updates, specialty device management, Microsoft Tunnel for MAM, Advanced Analytics, Remote Help, Microsoft Cloud PKI, Endpoint Privilege Management and Enterprise Application Management. Remediations is not on that list. So buying up the Intune stack does not get you this feature, which is the opposite of how the Endpoint Privilege Management entitlement behaves, and worth knowing before a renewal conversation. The Intune licensing page defines the plans themselves and confirms they are a separate axis.
The feature also has an old name. Microsoft Learn states plainly that Proactive Remediations was renamed to Remediations, and notes that the old term “might still appear in some blogs and other articles”. It appears in a great many of them, which is worth remembering when a guide you are following shows a portal path that no longer exists. The current path is Devices, then Manage devices, then Scripts and remediations.
The exit code contract, which is where most of the time goes
This is the part that is documented in one sentence and misunderstood constantly. Microsoft Learn: “The detection script must use exit code exit 1 if the target issue is detected. If there’s any other exit code, the remediation script won’t run.”
So the semantics are inverted relative to almost every other exit code convention in Windows. Exit 0 does not mean success in the sense you are used to. It means “no problem here, stand down”. Exit 1, which everywhere else in scripting means failure, is the signal that fires the remediation. A detection script that ends by falling off the bottom without an explicit exit, or that traps an error and exits 0, reports a healthy device and the remediation never runs. The reporting then shows the package as having run without incident, which is the worst possible outcome because it is indistinguishable from a fleet that is genuinely compliant.
A detection script that behaves correctly looks like this.
# Detection. Exit 1 means the condition needs fixing, exit 0 means it does not.
# Anything else, including an unhandled error, suppresses the remediation.
try {
$svc = Get-Service -Name "W32Time" -ErrorAction Stop
if ($svc.StartType -ne "Automatic") {
Write-Output "W32Time start type is $($svc.StartType)"
exit 1
}
Write-Output "W32Time compliant"
exit 0
}
catch {
# Service missing or unreadable. Treat as a detection, not as a script failure.
Write-Output "W32Time could not be read: $($_.Exception.Message)"
exit 1
}
Two deliberate choices there. The try block uses -ErrorAction Stop, because PowerShell’s default of continuing on a non terminating error is what produces the silent exit 0. And the catch exits 1 rather than exiting with an error code, because from the platform’s point of view an unreadable service is a condition to remediate, not a script that failed. If you would rather a broken detection stayed visible as broken, exit with something other than 0 or 1 and read it in the error column, but be clear with yourself which of the two you have chosen.
The documented limits
All of these are stated on the Remediations article and all of them bite in practice.
| Limit | Value |
|---|---|
| Script packages per tenant | 200 |
| Maximum output size | 2,048 characters |
| Schedule options | Once, Hourly, Daily |
| Hourly interval | Must be less than 24 hours |
| On demand runs | One Run remediation action at a time for the same device |
| Default architecture | Run script in 64-bit PowerShell is set to No |
The 2,048 character output cap is the one that quietly ruins reporting. Pre remediation and post remediation output is how you find out what happened on a device you cannot reach, and an Intune remediation script that writes a verbose object dump will have that output truncated. Write one line. Anything you would want to grep for later belongs in that line and nowhere else. This is the same discipline that Intune Device Query’s documented result limits force on you, and for the same reason: the transport was never designed to carry a log file.
The 64-bit default deserves its own sentence. Microsoft Learn shows the recommended setting for “Run script in 64-bit PowerShell” as No. That means the script runs in the 32-bit host by default, and on a 64-bit machine the registry is silently redirected under WOW6432Node. A detection script that reads a 64-bit registry key will report the key as missing, exit 1 forever, and the remediation will write the value into the 32-bit view where nothing will ever read it. The device is then permanently non compliant against a fix that appears to succeed every time.
The failure modes
- Detection exits 0 when it meant to fail. The most common one by a wide margin. The remediation never runs, the package reports clean, and the fleet looks healthy. Check the detection script’s exit paths before you check anything else.
- The licence is missing and nothing says so. There is no banner that reads “you are not entitled to this”. The blade renders, the package saves, the assignment sticks. This is why the Microsoft Q&A threads about remediations not running keep arriving from tenants that turn out to be on a bundle without a Windows Enterprise entitlement.
- Registry redirection under 32-bit PowerShell. Described above. Set the 64-bit option explicitly rather than leaving it at the default, whichever way you need it.
- Execution policy blocks the script. Microsoft Learn is specific here. With “Enforce script signature check” enabled, the script runs under the device’s own execution policy, which defaults to Restricted on Windows client and RemoteSigned on Windows Server. Without the signature check, scripts use Bypass. An unsigned script plus an enforced signature check on a client is a script that cannot run at all.
- Encoding. The documentation asks for UTF-8, and specifically not UTF-8 BOM where the signature check is enforced. A file saved from the wrong editor fails for a reason that is invisible in the portal.
- Output truncated at 2,048 characters. The report looks like it is missing data. It is not missing, it is cut.
- On demand runs that never arrive. Learn states the device will not receive the Run remediation action if it is offline or cannot reach Intune or the Windows Push Notification Service. It does not queue. A scheduled run is different and does catch up: a missed schedule runs when the device is next online, as soon as possible.
- Hourly schedules set to 24 hours. The value must be less than 24. Use the daily schedule for a daily job.
Worth stating plainly: I have not run this against a production fleet. My tenant is a lab with no enrolled devices, so the failure modes above are drawn from the documentation as it reads today and from where the documented behaviour predicts trouble, not from a measured rollout. Where I have written “most common”, that is a judgement about the shape of the contract rather than a count I can evidence.
What I would do differently
I would check entitlement before writing a line of PowerShell. The licence question takes two minutes and it invalidates the whole exercise, which puts it first, ahead of the interesting work. Anyone who has debugged an assignment that turned out to be a licensing problem will recognise the pattern from policy conflicts, where the visible symptom and the actual cause sit in different parts of the console.
I would also treat the detection script as the product and the remediation as an afterthought. A detection script that is correct and cheap can be deployed on its own, with no remediation attached, purely as a reporting mechanism, and it tells you the size of the problem before you commit to a fix. That is a much better use of the first week than writing a remediation that runs hourly against a condition you have not measured.
Last, I would keep remediations and app installs apart. Remediations are for drift: a setting that keeps coming back wrong. Installing software through one is technically possible and consistently regretted, because the retry semantics, the reporting and the detection model are all built for a different job. Win32 app deployment has its own detection rules and its own failure surface, and mixing the two gives you the weaknesses of both.
Last verified: 18 September 2026



