You upload a PowerShell script under Devices › Scripts and remediations › Platform scripts, assign it, and either the report says Failed or the device shows no sign the script ever ran. In this post I'll explain how the Intune Management Extension (IME) runs platform scripts, what the three settings on the script actually change on the device, how often a script runs and retries, and the root causes I check in order before I touch the script itself.
Symptoms#
- Under the script's Monitor › Device status or User status, devices show Failed, or stay Pending for days.
- The report says the script succeeded, but the change it was supposed to make isn't on the device.
- The script works when you run it by hand in an elevated PowerShell window, but not when Intune runs it.
- It ran fine on the first wave of devices and now doesn't run on new ones, or you need it to run again and can't make it.
Why it happens#
How the IME runs a platform script#
The IME installs itself on an enrolled, Microsoft Entra joined, hybrid joined or registered Windows device as soon as you assign a script, a Win32 app, a remediation or a few other IME-based features. It doesn't support Windows in S mode or Surface Hubs. The agent lives in %ProgramFiles(x86)%\Microsoft Intune Management Extension, runs as the IntuneManagementExtension service, and checks in with Intune every 8 hours and after every reboot. That check-in is separate from the MDM check-in, which is why a device can be syncing perfectly and still not have your script.
Microsoft documents the rules the IME applies to platform scripts, and most "it didn't run" cases are one of these working as designed:
- A script runs once. It runs again only if you change the script or the policy. Device-assigned scripts do run for every new user who signs in (except on multi-session SKUs).
- If it fails, the IME retries three times, once per consecutive IME check-in, then stops until the script or policy changes.
- A script is killed after 30 minutes, and the file must be under 200 KB.
- Scripts run before Win32 apps on the same check-in.
- Scripts can target user or device groups, but on Entra registered (workplace joined) devices only device groups work.
- If the device's clock is off by months or years, scripts don't run until the time is corrected.
What the three settings change#
| Setting | Yes | No | Typical failure |
|---|---|---|---|
| Run this script using the logged on credentials | Runs as the signed-in user, when a user is signed in | Runs as SYSTEM, no user needed | Script needs admin rights or runs before anyone signs in, but is set to user context; or it needs HKCU and is set to SYSTEM |
| Enforce script signature check | Script must be signed by a publisher the device trusts | Unsigned scripts allowed | Unsigned or self-signed script with the check left at Yes (the default) |
| Run script in 64-bit PowerShell host | 64-bit PowerShell on 64-bit Windows | 32-bit PowerShell (the default) | Registry writes land under WOW6432Node, System32 paths redirect to SysWOW64, 64-bit-only modules aren't found |
The 32-bit default surprises people most. The IME hands the script to the x86 PowerShell in C:\Windows\SysWOW64\WindowsPowerShell\v1.0, so anything that touches the 64-bit registry view, 64-bit binaries or modules installed only for 64-bit PowerShell behaves differently from your test window. Note Microsoft's caveat for existing policies: flipping an already-deployed script to 64-bit doesn't re-run it, it only opens in the 64-bit host and reports.
Other common root causes#
- Error stream equals failure. Anything written to the error stream, including an uncaught exception or a stray
Write-Error, marks the run as failed even if the work completed. The reverse also happens: an external command that fails without throwing lets the script exit 0 and report success. - Execution policy. If Group Policy or MDM enforces a restrictive execution policy on the device, the script can be blocked; Microsoft lists reviewing execution policy as a first isolation step.
- Context dependencies. Mapped drives, the user's profile, user-scoped modules and a user-only proxy don't exist for SYSTEM. If the proxy is configured only per user, the IME can't download anything until a user signs in, or until you set the machine-wide BITS proxy with
bitsadmin /util /setieproxy. - Antivirus sandboxing. If a script reports success but did nothing, Microsoft's guidance is to check whether your antivirus is sandboxing
AgentExecutor.exe. - IME service set to Manual. After a reboot the service may not start, so no check-in and no scripts.
How to fix it#
- Read the right report. Open the script, select Monitor, then Device status for device-targeted and User status for user-targeted assignments. Pending on every device points at targeting or the IME itself; Failed on every device points at the script.
- Confirm the IME is present and healthy. Check that
%ProgramFiles(x86)%\Microsoft Intune Management Extensionexists and that theIntuneManagementExtensionservice is running with startup type Automatic. If it isn't installed, go back to the prerequisites: the device must be Entra joined or hybrid joined, actually enrolled, not in S mode, and able to reach the IME endpoints for your tenant region. - Read the logs. In
C:\ProgramData\Microsoft\IntuneManagementExtension\Logs,IntuneManagementExtension.logshows the policy arriving and the result being reported, andAgentExecutor.logshows the actual execution, including the exit code and captured error output. Open them with CMTrace. - Reproduce in the same context. For a SYSTEM-context script, test with
psexec -i -s powershell.exe. For the 32-bit host, test inC:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe. If the behaviour differs from your normal console, you've found the problem; either fix the script or change the setting. - Make the script report honestly. Exit explicitly and keep the error stream clean on success:
PowerShell
try { # work goes here New-Item -Path 'HKLM:\SOFTWARE\Contoso' -Force | Out-Null Write-Output "Done" exit 0 } catch { Write-Error $_.Exception.Message exit 1 } - Fix signing or turn the check off. If Enforce script signature check is Yes, sign the script with a code-signing certificate the device trusts, and deploy that trust first. If you don't need signing, set it to No.
- Re-run it the supported way. Edit the script (even a comment change), re-upload it, or change the assignment; the device runs it at the next IME check-in. Restarting the
IntuneManagementExtensionservice or rebooting triggers a check-in immediately. The IME also stores each script's result underHKLM\SOFTWARE\Microsoft\IntuneManagementExtension\Policies, keyed by user and script policy GUID; deleting a script's key and restarting the service makes it run again on that device. That's a handy lab trick, not a documented or supported method, so don't build a process on it.
Tip: If you need a script to run on a schedule, run again when something drifts, or produce a readable output per device, you've outgrown platform scripts. Remediations give you a detection script, a remediation script, a recurring schedule and an on-demand run from the device page, and the output lands in the admin center.
Verify the fix#
- Device status shows Succeeded for the device, and
AgentExecutor.logshows exit code 0 with an empty error output. - The change is on the device in the place you expected, for example under the 64-bit registry view rather than
WOW6432Node. - A newly enrolled device in the same group gets the script on its first IME check-in without any manual help.
Key takeaways#
- Decide the context first: SYSTEM or user, 32-bit or 64-bit, signed or not. Most failures are a mismatch between what the script assumes and how the IME runs it.
- A platform script is a run-once tool with three retries. If you need recurrence or reporting, use Remediations.
- Treat the error stream as your status signal: clean on success, explicit on failure.
- Test with
psexec -sand theSysWOW64PowerShell before you assign to production groups.