IntuneTroubleshooting

macOS shell scripts and custom attributes not running in Intune: agent logs and fixes

Why Intune shell scripts and custom attributes don't run on Macs: the agent's 8-hour cycle, user vs root context, shebangs, exit codes and proxies, plus agent logs and Collect logs.

Shell scripts and custom attributes are how Intune does on a Mac what configuration profiles can't. When they don't run, the report often tells you very little: no status, a bare Failed, or an empty result. In this post I'll explain how the Intune management agent delivers scripts, list the requirements that silently stop them, and show where to look on the Mac and how to prove a fix.

Errors this guide fixes

  • bad interpreterTerminal (manual test run)
  • command not foundTerminal (manual test run)
  • Operation not permittedTerminal (manual test run)
  • 2016214831 The provided log file path must exist.Collect logs (macOS script)
  • 2016214828 The number of log files exceeded the allowed limit of 25 files.Collect logs (macOS script)
  • 2016214834 Log file size cannot exceed 60 MB.Collect logs (macOS script)
How this guide is organised: Symptoms → Why it happens → How to fix it → Verify the fix → Prevent it next timeFlow diagram of the article's sections in reading order: 1. Symptoms. 2. Why it happens (3 parts: Scripts travel through the agent, not MDM; Requirements that stop scripts; How run status is reported). 3. How to fix it. 4. Verify the fix. 5. Prevent it next time. Toolbox: 0x87D300D1, date--time.log, a.log, IntuneMdmAgent, #!/bin/sh.1Symptoms2Why it happens3How to fix it4Verify the fix5Prevent it nexttimeScripts travel throughthe agent, not MDMRequirements that stopscriptsHow run status isreportedTOOLBOX0x87D300D1date--time.loga.logIntuneMdmAgent#!/bin/shHow this guide is organised: Symptoms → Why it happens → How to fix it → Verify the fix → Prevent it next timeFlow diagram of the article's sections in reading order: 1. Symptoms. 2. Why it happens (3 parts: Scripts travel through the agent, not MDM; Requirements that stop scripts; How run status is reported). 3. How to fix it. 4. Verify the fix. 5. Prevent it next time. Toolbox: 0x87D300D1, date--time.log, a.log, IntuneMdmAgent, #!/bin/sh.1Symptoms2Why it happensScripts travel through the agent, not MDMRequirements that stop scriptsHow run status is reported3How to fix it4Verify the fix5Prevent it next timeTOOLBOX0x87D300D1date--time.loga.logIntuneMdmAgent#!/bin/sh
At a glance: how this guide is organised · 3 fix steps · 5 key tools

Symptoms#

  • The script's Device status or User status stays empty for a Mac, or shows Failed.
  • A custom attribute's Result column is empty, out of date or shows an error.
  • The script works when you paste it into Terminal, but not from Intune; or a test run prints a bad interpreter error, command not found or Operation not permitted.
  • Collect logs fails with one of these:
Text
2016214831 The provided log file path must exist.
2016214828 The number of log files exceeded the allowed limit of 25 files.
2016214834 Log file size cannot exceed 60 MB.

Match these on the decimal code and the message: Microsoft's table gives the same hex code, 0x87D300D1, for both 2016214831 and 2016214834.

Why it happens#

Scripts travel through the agent, not MDM#

Intune silently installs the Microsoft Intune management agent at /Library/Intune/Microsoft Intune Agent.app when a Mac gets its first shell script; it shows as IntuneMdmAgent in Activity Monitor. The agent checks for new or changed scripts about every 8 hours, independently of the MDM check-in, and Sync in the admin center starts only an MDM check-in. A script you assigned ten minutes ago may simply not have arrived yet.

Requirements that stop scripts#

Requirement (Microsoft Learn)What you see when it's missed
macOS 12.0 or later, managed by IntuneNo agent, no status
Direct internet connection; a proxy isn't supportedAgent can't check in; nothing arrives
Script starts with a valid shebang such as #!/bin/sh or #!/usr/bin/env zshFailed (malformed script)
Script file smaller than 1 MBUpload rejected
Run script as signed-in user = Yes needs someone signed in; it then runs for every signed-in user. No (default) runs as rootNo run until a user signs in; permission errors in user context
Exit code 0 means successFailed for any non-zero exit code; no rerun unless Max number of times to retry if script fails is set
Run time under 60 minutesStopped and reported as failed

Scripts also run in parallel as separate processes, so never rely on one script finishing before another. A script with Script frequency left at Not configured runs once; scheduled scripts also run after a restart, and Microsoft notes they can run more often than scheduled in conditions such as a full disk or a deleted local cache.

How run status is reported#

Run status is sent only when it changes from the last report; if it doesn't change, Intune refreshes the timestamp every 7 days. So Last updated is not "last ran". If a Mac goes offline after receiving a script but before reporting, it never reports that run at all, which Microsoft lists as a known issue.

How to fix it#

  1. Confirm the agent and force a check-in. If the agent folder is missing, check the assignment: scripts assigned to user groups apply to any user who signs in to the Mac. An unhealthy agent tries to recover for 24 hours, then removes itself and reinstalls while scripts are still assigned.
    Bash
    ls -d "/Library/Intune/Microsoft Intune Agent.app"
    pgrep -l IntuneMdmAgent
    sudo killall IntuneMdmAgent    # the agent restarts and checks in immediately
    The user can do the same from Company Portal: select the Mac, then Check status.
  2. Read the agent logs. The system-level log is /Library/Logs/Microsoft/Intune/IntuneMDMDaemon date--time.log and the per-user log is ~/Library/Logs/Microsoft/Intune/IntuneMDMAgent date--time.log. Search both for the script's name; a broad first pass looks like this:
    Bash
    grep -i "script" /Library/Logs/Microsoft/Intune/IntuneMDMDaemon*.log | tail -n 40
    grep -i "script" ~/Library/Logs/Microsoft/Intune/IntuneMDMAgent*.log | tail -n 40
  3. Reproduce the context. Run the script as an executable so its shebang is used: chmod +x script.sh, then sudo ./script.sh; echo "exit: $?" for a root script, or ./script.sh as the user for a user script. Then check the usual suspects:
    • A bad interpreter error (under sudo, an "unable to execute" error): a wrong shebang path or Windows line endings. file script.sh reports "with CRLF line terminators"; fix it with tr -d '\r' < script.sh > fixed.sh.
    • command not found: don't rely on your Terminal's PATH; call tools by full path (/usr/bin/defaults, not defaults) and don't assume Homebrew exists.
    • Operation not permitted: even root can't touch privacy-protected locations without consent. Grant access with a Privacy Preferences Policy Control profile or avoid those paths.
    • An unexpected Failed: the last command decides the exit code, so a final grep with no match fails the whole script. End with an explicit exit code.
  4. Make scripts report on themselves. Intune shows only success or failure, so log to your own file (this example runs as root):
    Bash
    #!/bin/zsh
    LOG="/Library/Logs/Contoso/rename-check.log"
    /bin/mkdir -p "${LOG:h}"
    exec >> "$LOG" 2>&1
    echo "$(/bin/date -u +"%Y-%m-%dT%H:%M:%SZ") start"
    name=$(/usr/sbin/scutil --get ComputerName) || { echo "cannot read ComputerName"; exit 1; }
    echo "ComputerName is $name"
    exit 0
  5. Fix custom attributes. They live under Devices › By platform › macOS › Organize devices › Custom attributes for macOS and run every 8 hours. The script must echo one value matching the data type you chose (String, Integer or Date), the output must be 20 KB or less, and dates must be ISO-8601:
    Bash
    #!/bin/zsh
    # Integer: free space on the startup volume in GB
    /bin/df -g / | /usr/bin/awk 'NR==2 {print $4}'
  6. Collect logs remotely when you can't reach the Mac: Devices › Manage devices › Scripts and remediations › Platform scripts, select the script, then a device in Device status or User status, and Collect logs. Use full absolute paths separated only by semicolons (/Library/Logs/Contoso/a.log;/Users/Shared/b.zip), stay within 60 MB compressed or 25 files, and use allowed extensions (.log, .zip, .gz, .tar, .txt, .xml, .crash, .rtf). The upload happens at the next agent check-in, the agent logs are added automatically, and any missing file is listed in LogCollectionInfo.txt.

Verify the fix#

  • After a forced agent check-in, Device status shows Success (exit code 0) for the Mac.
  • Your script's own log shows the run with a timestamp, and the agent log shows no retry for it.
  • For custom attributes, the Result column shows the echoed value after the next 8-hour run.

Prevent it next time#

  • Test as root and as a standard user, save with LF line endings, use full paths and finish with an explicit exit code.
  • Set retries for scripts that can fail transiently, and a frequency only for idempotent scripts.
  • Keep run time far below 60 minutes, and plan around the 8-hour agent cycle rather than the Sync button.
  • The same agent installs DMG and unmanaged PKG apps; see macOS PKG and DMG apps failing in Intune. For Windows, see Intune PowerShell scripts not running.

References#

Revision history: Oct 2026 — re-checked against Microsoft Learn: details confirmed.

Written and checked against current Microsoft Learn documentation. Test changes with a pilot group before rolling them out to everyone, and if an admin center path has moved since, search for the setting name instead.

Spotted a mistake, or did this fix work differently for you? Email me or message me on LinkedIn — corrections are credited in the article.

Written by

Omer Eltayeb

Intune Subject Matter Expert in Cairo, Egypt, former Microsoft Cloud Solutions Architect, Microsoft Certified Trainer and Microsoft Innovative Educator Expert (2024–26) and Microsoft Elevate Educator Expert (2026–27). I share practical, step-by-step guides, study plans, scripts and toolkits for Microsoft Intune, Configuration Manager, Microsoft Entra ID, Microsoft Defender, Exchange and Microsoft 365 with the community.

Microsoft Certified Trainer (MCT) 2026Microsoft Innovative Educator Expert 2025–2026Microsoft Elevate Educator Expert 2026–2027ISC2 Certified Information Systems Security Professional (CISSP)Microsoft 365 Certified: Enterprise Administrator Expert (MS-102)