IntuneBrew - MacOS Application Management for Intune
IntuneBrew LogoIntuneBrew

Packaging and Deploying Custom macOS Shell Scripts via Microsoft Intune

Learn how to package and deploy custom shell scripts for macOS using Microsoft Intune. This detailed step-by-step guide covers creating and packaging .sh scripts, deploying them via Intune, real-world examples (installing apps like Zoom/Chrome, enforcing settings like disabling guest accounts or setting time zone, automating maintenance tasks), best practices for reliable script deployment, and troubleshooting common issues (execution failures, permissions, policy misconfigurations). Ideal for IT administrators managing macOS deployments with Intune.

Packaging and Deploying Custom macOS Shell Scripts via Microsoft Intune

Introduction

Managing macOS devices with Microsoft Intune can be extended with custom shell scripts to accomplish tasks beyond built-in policies. Intune's macOS shell script deployment feature allows IT admins to run Bash/Zsh scripts on enrolled Macs, enabling automation of software installs, configurations, and maintenance. For example, you might deploy a script to install Zoom or Google Chrome, enforce security settings like disabling the Guest account, or run periodic cleanup and update tasks on all Macs. This blog post provides a step-by-step guide to creating, packaging, and deploying shell scripts via Intune, with real-world examples, best practices, and troubleshooting tips. By following this guide, IT generalists can reliably deploy custom .sh scripts to macOS devices at scale using Intune.

Prerequisites: Ensure your Macs are Intune-enrolled (managed by Intune) and running a supported macOS version (Intune currently supports macOS 12.0 or later for shell scripts). The devices must have internet access without a proxy (proxies aren't supported for Intune script delivery). Intune will automatically install its management agent (Management Extension) on any Mac targeted with a script, which is required to execute the script on the device. Also, prepare your script with a proper shebang line (#!) at the top (e.g. #!/bin/bash or #!/usr/bin/env zsh) so the system knows how to interpret it. With these in place, you're ready to package and deploy your custom script via Intune.

Step-by-Step Guide: Creating and Deploying a Shell Script in Intune

Deploying a shell script through Intune involves writing the script, testing it, uploading it to Intune, and assigning it to target machines. Follow these steps:

  1. Create and Prepare the Shell Script: Start by writing your shell script (.sh) on a macOS device or a text editor. Include the proper shebang (for example, #!/bin/bash for Bash scripts) at the first line. Develop the script to perform the desired actions – for instance, installing an application or configuring a setting. Make sure the script is non-interactive (it should not prompt for user input) and can run silently. Keep the script size under Intune's limit (Intune supports script files up to 1 MB in size). After writing the script, save it with a .sh extension (e.g. install_zoom.sh).

  2. Test the Script Locally: Before deploying via Intune, always test the script on a macOS test machine. Run it manually (e.g. sudo sh install_zoom.sh) to verify it performs as expected. Ensure it exits with code 0 on success (and non-zero on failure) because Intune uses the exit code to determine if the script ran successfully. Check that all commands execute correctly and no permission issues or errors occur. Testing helps catch issues early – remember, as Microsoft's Intune team advises, "Always test!" scripts in your environment before wide deployment. If the script needs elevated privileges to modify the system, test it with sudo (since Intune can run scripts as root by default). Make any necessary adjustments to ensure the script is robust (for example, add error handling or logging).

  3. Upload (Package) the Script in Intune: Now, log in to the Microsoft Intune admin center. Navigate to Devices > macOS > Shell scripts (or Scripts under Devices) and click Add to create a new shell script policy. In the Basics section, enter a Name (e.g. "Install Zoom Script") and an optional Description for the script policy, then click Next. Upload your .sh file in the Script Settings section by browsing and selecting the script you created – Intune will display an upload confirmation. (Figure: Uploading a shell script in Intune – the script file "Enable Screen Sharing.sh" is selected and uploaded, with its contents displayed). After uploading, configure the following settings:

    • Run script as signed-in user: Choose No to run the script with root privileges (administrator context), or Yes to run in the context of the currently signed-in user. Use No/root for scripts that change system-wide settings or install software (since those need admin rights), and Yes for scripts that need to modify user-specific settings (like items in the user's home folder or Dock). (Note: if run as user, a user must be logged in on the Mac for the script to execute, and it will run for each logged-in user account.)
    • Hide script notifications on devices: Optionally set this to Hide to prevent the end-user from seeing the "Intune is configuring your computer" notification when the script runs. Hiding notifications can make the deployment silent, but leaving it default (Not configured) will show a brief macOS notification indicating the script is running.
    • Script frequency: Decide how often Intune should run the script. By default this is Not configured (runs once per device). You can set it to run daily, weekly, or at every login depending on your needs. For one-time setup actions (like initial software install or a one-off configuration), leave it to run only once. For enforcement or maintenance tasks (like ensuring a setting stays enabled or regular clean-up), you might schedule it to run periodically. Intune will attempt to run the script on the schedule; note that if the device is offline, it will run on next check-in.
    • Max retries if script fails: Optionally specify how many times Intune should retry if the script returns a failure (non-zero exit code). The default Not Configured means no retries. You can set, for example, 3 retries – Intune will then try to run the script up to 3 more times if it fails, which can be useful for scripts that might fail due to transient issues (like a momentary network error during a download).

    After configuring these, click Next.

  4. Assign the Script to Macs: In the Assignments step, choose the target devices or user groups that should receive this script. Typically, you would create an Azure AD group containing the macOS devices (or users) you want the script deployed to. Click Select groups to include, pick the appropriate group(s) (e.g. a group "All Corporate Macs" or "Marketing Dept Macs"), and assign the script to those devices. You can include multiple groups if needed. (You may also exclude certain groups if necessary for testing or rollout, though note Intune doesn't allow mixing user/device group types in include vs exclude.) Once the assignments are set, proceed to Review + add.

  5. Review and Deploy: In the Review + add (Create) page, double-check the script name, settings, and assignment summary. If everything looks correct, click Add (or Create). Intune will save the policy and start deploying it to the selected devices. You should see a confirmation notification in the portal that the shell script policy was created successfully. The script now appears in the list of Intune macOS scripts. Intune will push the script to targeted Macs shortly (devices check in with Intune regularly; a newly assigned script is usually picked up on the next check-in, or you can prompt a check-in by syncing Intune policies on the client). When the device receives the policy, the Intune management agent will download the script and execute it as per the configured settings.

  6. Monitor the Deployment: After deployment, you can monitor the script's execution status in Intune. In the Intune admin center, navigate to Devices > macOS > Shell scripts, and select your script policy. You can view the Device status and User status reports to see per-device results. Each device will report a status like Success or Failed after the script runs. A status of Success means the script finished with exit code 0, while Failed indicates a non-zero exit code or a script error. (Be aware that Intune only records the first run status by design – if the script is set to run repeatedly, subsequent runs won't update the status in the portal unless the script content changes.) If some devices show failures, you can begin troubleshooting (see the Troubleshooting section below for common issues). For ongoing policies (with frequency), you may periodically re-check this status or use Intune's log collection feature for deeper investigation.

By following these steps, you have packaged (uploaded) and deployed a custom shell script via Intune. Intune handles distributing and running the script on all targeted macOS devices, allowing you to automate tasks across your fleet.

Real-World Examples of Shell Script Use Cases

One of the strengths of Intune shell scripts is flexibility. Here are some common real-world use cases and examples of what you can achieve with custom scripts on macOS:

1. Installing and Configuring Applications (e.g. Zoom, Chrome, VPN Clients)

Software installation is a frequent need—especially for apps not available in the Mac App Store or via VPP. With Intune, you could deploy these as Line-of-Business (LOB) apps by uploading a package, but a shell script offers an alternative for apps that auto-update or where you want custom post-install steps. For example, you can write a script that downloads the latest installer from the vendor's website and installs it silently:

  • Install Zoom via script: Zoom provides a direct download URL for its Mac installer. A script can use curl to download the Zoom package and then install it. For instance:

    #!/bin/bash
    # Download Zoom installer
    curl -L -o /tmp/ZoomInstaller.pkg https://zoom.us/client/latest/ZoomInstallerIT.pkg
    # Install the package
    sudo installer -pkg /tmp/ZoomInstaller.pkg -target /

    This script fetches the Zoom client's PKG and uses the macOS installer command to install it to the system. After installation, you might include configuration commands (for example, copying a preconfigured plist or setting Zoom preferences via defaults). Always end the script with exit 0 if installation succeeds, so Intune reports success.

  • Install Google Chrome via script: Google Chrome's Mac download is a DMG. A script can download the DMG, mount it, copy the Chrome app to /Applications, then unmount. For example:

    #!/bin/bash
    # Download Chrome disk image
    curl -o /tmp/Chrome.dmg https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg
    # Mount the DMG
    hdiutil attach /tmp/Chrome.dmg -nobrowse -quiet
    # Copy Chrome to Applications
    cp -R "/Volumes/Google Chrome/Google Chrome.app" /Applications/
    # Unmount and clean up
    hdiutil detach "/Volumes/Google Chrome" -quiet

    This would install Chrome. (Make sure to adjust version URLs or use Chrome's latest link as done above. Also, such a script should check if Chrome is already installed to avoid duplicative work—see best practices below.)

  • Install a VPN client or other utilities: If your organization uses a VPN client that isn't in the App Store, you can deploy it via script similarly. For instance, a Palo Alto GlobalProtect or Cisco AnyConnect VPN installer (if provided as a PKG or script) can be downloaded from an internal server or vendor site and installed. You might also push configuration files post-install (e.g. a predefined VPN profile). Intune's scripting can also be used to configure an installed app. For example, after installing, you could use the defaults command to set certain app preferences or run the app's command-line configuration tool if it has one.

Why use scripts for app installs? Sometimes software vendors update their apps frequently or provide install scripts. Using Intune script deployment means you can always fetch the latest version at deployment time rather than repackaging the app for Intune every time. It's especially handy for apps not easily packaged or where you want to combine multiple actions (install + configure settings). Microsoft even provides an example in their Intune Shell Script GitHub repository for downloading and installing a Mac app (the GIMP image editor) using this method. Always ensure the download source is reliable and consider code-signing your script for integrity if needed.

2. Enforcing System Settings and Configurations (e.g. Disable Guest User, Set Time Zone, Modify Dock)

Shell scripts can enforce or configure system settings that might not have a built-in Intune policy. Examples include security settings, UI preferences, and other macOS configurations:

  • Disabling the Guest account: macOS by default can allow a guest user login. To ensure this is turned off for security, a script can run a command to disable the guest account. For instance:

    #!/bin/bash
    # Disable macOS Guest Account login
    sudo defaults write /Library/Preferences/com.apple.loginwindow GuestEnabled -bool false

    This command updates the system loginwindow preferences to turn off guest access. (Alternatively, one could use sudo sysadminctl -guestAccount off for newer macOS versions.) Run as root, this change ensures no one can log in as a guest on the Mac.

  • Setting a specific time zone: If your organization has computers in various regions, you might want to ensure each Mac is set to the correct time zone (or a fixed one if required). You can use the built-in systemsetup command:

    #!/bin/bash
    # Set time zone to Europe/Berlin
    sudo systemsetup -settimezone "Europe/Berlin"
    sudo systemsetup -setusingnetworktime on

    This sets the Mac's time zone and ensures it uses network time (so it syncs with time servers). Adjust the time zone string as needed (it should match an official timezone name like "America/Los_Angeles" or "Asia/Tokyo"). Running as root is required for this command.

  • Modifying Dock items: Organizations often want to set a standard Dock layout (e.g., remove default icons like Music, add corporate apps or browser). While Intune doesn't have a native Dock policy, a script can do this. For example, to remove all current Dock apps and add two specific apps:

    #!/bin/bash
    # Remove all dock icons
    defaults write com.apple.dock persistent-apps -array ""
    # Add specific apps to Dock (by their bundle identifier or using dockutil if available)
    # Example uses 'dockutil' if installed for more control:
    # /usr/local/bin/dockutil --add "/Applications/Microsoft Word.app"
    # /usr/local/bin/dockutil --add "/Applications/Safari.app"
    # Restart Dock to apply changes
    killall Dock

    This would reset the Dock to empty, then (if dockutil tool is present) add Word and Safari. Without dockutil, another approach is to craft the persistent-apps array with the desired apps' paths using defaults commands or deploy a preconfigured plist. In any case, a script can enforce a Dock layout at login or once.

  • Other settings enforcement: Shell scripts can manage a range of settings: disabling USB storage (by unloading kexts or creating a configuration file), enabling firewall or FileVault (though Intune has built-ins for those), forcing screen saver password settings, adjusting Finder or Safari preferences, and so on. If macOS has a command-line or plist for it, you can script it. For example, to ensure the screensaver asks for password immediately: defaults write com.apple.screensaver askForPassword -int 1 && defaults write com.apple.screensaver askForPasswordDelay -int 0. Running that via Intune script would enforce the setting on all targeted Macs.

The key for settings scripts is idempotence – the script should set the desired state regardless of current state. Typically these scripts can be scheduled to run periodically (say daily) to remediate drift (if a user changes a setting back, the script will revert it on next run). Using Intune's frequency option to run daily or weekly can thus keep systems in compliance.

3. Automating Maintenance Tasks (e.g. Clearing Cache, Updating Software, System Checks)

Maintenance and routine housekeeping can also be automated. Intune shell scripts allow you to schedule such tasks off-hours or regularly:

  • Clearing system or application caches: Over time, caches can consume disk space or cause issues. You might deploy a script to clean certain cache directories. For example:

    #!/bin/bash
    # Clear system cache and user cache for all users
    rm -rf /Library/Caches/*
    for u in /Users/*; do
        rm -rf "$u/Library/Caches/"*
    done

    This removes files in the system /Library/Caches and each user's Library/Caches. (Be cautious with such broad deletion; ensure no critical data is in those caches. Testing is crucial.) This could be run monthly to free space. Running as root is needed to affect all users.

  • Force macOS software updates: While Intune can manage OS updates through dedicated policies, a shell script can be used as an alternative or for specific control. For instance:

    #!/bin/bash
    # Run macOS software update
    sudo softwareupdate -i -a

    This will trigger macOS to install all available updates (-i -a = install all). You could schedule this script to run weekly. Combine it with a check for power or user activity if you want to avoid disrupting the user unexpectedly (macOS updates may reboot the system). For example, only run if the machine has been idle or at a certain time.

  • Running system checks or maintenance utilities: You might want to periodically run a script to check system health and report back (possibly via a custom attribute in Intune or by sending logs to a server). For example, a script could verify that critical services are running (and start them if not), or check disk usage and purge temporary files if a threshold is exceeded, or even run a security scan. One common maintenance script could flush the DNS cache (dscacheutil -flushcache) or reset a printer spool if users encounter printing issues. Another example: check if a process (say an antivirus agent) is running, and if not, trigger it to launch or notify IT.

  • Custom inventory or reporting: Although Intune has device inventory, you might use a script to gather additional info and report it via Intune's custom attributes feature. For instance, a script could echo the versions of certain installed apps or the last backup date. Intune can collect that output if set up as a custom attribute script. (This is a slightly different use-case: the script returns information to Intune instead of making a change.)

Using Intune, these maintenance scripts can be set with a recurring schedule (daily/weekly) to automate upkeep without manual intervention. Always ensure such scripts are well-tested to avoid unintended side effects, since they run on every targeted machine.

Best Practices for Writing Effective Intune Shell Scripts

Writing a shell script for deployment via Intune requires some additional care to ensure it runs reliably on all target Macs. Keep these best practices in mind:

  • Use Proper Shebang and Shell: Always start your script with the appropriate shebang (e.g. #!/bin/sh, #!/bin/bash, or #!/usr/bin/env zsh). Intune will honor this and use the specified shell. Keep in mind modern macOS default user shell is zsh, but /bin/sh (which points to bash) is also available. If your script uses Bash-specific features, use #!/bin/bash; for broader compatibility or zsh-specific features, use #!/usr/bin/env zsh. Also ensure the Mac has the shell interpreter (stock macOS has sh, bash, zsh by default).

  • Run in Correct Context (User vs Root): Decide if the script should run as the logged-in user or with root privileges, and set the Intune option accordingly. By default, Intune runs scripts as root (administrator) unless you choose otherwise. Running as root is necessary for tasks that modify system directories, install software to /Applications or change system settings. If your script needs to modify something in a user's profile (e.g. their Dock, files in ~/Library), you may need it to run as that user – in which case set "run as signed-in user: Yes" in Intune. In user context, remember multiple users: if two users are logged in (fast user switching), the script runs for each. Also note that if no user is logged in at the time, a user-context script will not run until someone logs in. For most configuration tasks, running as root is the safer bet.

  • Ensure Idempotence: Write your script so that if it runs multiple times, it won't break or re-do work unnecessarily. Intune might run the script again (especially if you configure a frequency or retry on failure). For example, if your script creates a file or user account, add checks so it doesn't attempt to create it again if it already exists. If installing software, check if the software is already installed (perhaps by checking the app bundle in /Applications or a version) to skip downloading again. Idempotent scripts prevent unwanted side effects on repeated runs.

  • No User Interaction or GUI Dependencies: Intune scripts run in the background, non-interactively. Do not include commands that prompt the user or require a GUI. For instance, avoid osascript that might show dialogs, or commands that open apps expecting user input. If a command requires a user prompt (for password, etc.), find a way to pre-supply it (like passing credentials in the script securely, or better, redesign the approach). Any script that hangs waiting for input will eventually be killed by Intune (after ~60 minutes) and marked failed. Keep it silent and automated.

  • Use Full Paths in Scripts: When writing the script, don't assume any PATH environment. It's safest to call executables with their full path (e.g. use /usr/bin/defaults instead of just defaults, /bin/rm instead of rm). The environment that Intune's agent runs in may not have the same PATH as your user. Explicit paths ensure the correct binaries are executed. Also specify file paths explicitly; for example, prefer absolute paths like /Applications/Google Chrome.app instead of relative paths.

  • Add Logging for Debugging: It's helpful to include some logging in your script so you can troubleshoot later. You can use the logger command to write to the system log, or redirect output to a file (e.g. /var/log/intune_scripts/myScript.log). Intune's management agent also logs script activity in files under /Library/Logs/Microsoft/Intune/ on the Mac. By echoing or logging key steps (especially in complex scripts), you make it easier to see what happened if something goes wrong. Just be mindful of not logging sensitive information (like passwords).

  • Test Thoroughly in a Controlled Environment: As emphasized earlier, always validate your script on a test Mac (or a small pilot group) before broad deployment. Test with different scenarios if possible (for example, different OS versions, with no user logged in vs. user logged in, etc., depending on context). This helps ensure your script works universally. Remember that Microsoft supports the Intune infrastructure but not the content of your custom scripts, so the onus is on IT to vet the script logic. A careful testing regimen will prevent most surprises.

  • Mind the Execution Time: Intune will terminate a script that runs longer than 60 minutes. So, design your scripts to finish in a reasonable time. If you have a very long task (say a huge download or intensive computation), consider breaking it into smaller tasks or ensure it can complete under an hour. If a script consistently takes too long, Intune will mark it as failed.

  • Avoid Overly Frequent Scripts for Heavy Tasks: While Intune allows scheduling scripts (e.g. every hour, daily), be cautious scheduling resource-intensive scripts too frequently as this can impact user experience or network. For example, clearing caches daily or running a heavy update check too often might not be necessary. Match the frequency to the need (e.g., run maintenance scripts weekly or monthly if that's sufficient). Also avoid scheduling reboots or anything disruptive via script without informing users; if you must, use notifications or only do so during maintenance windows.

  • Keep Scripts Secure: Treat your script like code – don't hardcode sensitive credentials unless absolutely necessary. If the script requires a password or key (for example, to join a Wi-Fi or install something), see if Intune can deploy those via other means (like a certificate profile or keychain item) rather than putting secrets in plaintext. If you must include something sensitive, ensure the Intune policy is well-protected (only admins can view the script content in Intune). Intune does obscure the script content at rest and in the portal after upload (it shows script content only to authorized admins), but always follow least privilege with access.

  • Use Intune's Script Samples and Community Knowledge: Microsoft provides a repository of sample shell scripts for Intune on GitHub which includes many common scenarios. Before writing from scratch, check if a script for your task already exists in the community – these can offer a starting point or best practice approach (though again, test any sample in your environment). Additionally, the Mac admin community (on forums like Reddit's r/macsysadmin or Microsoft Tech Community) often shares tips on Intune script techniques for macOS. Leverage those resources to improve your scripts.

By following these best practices, you'll craft shell scripts that deploy reliably via Intune, with minimal errors and predictable behavior. Well-written scripts combined with Intune's delivery mechanism can save IT admins significant time in macOS management.

Troubleshooting Intune Shell Script Deployments on macOS

Sometimes a script might not run as expected on some devices. Here are common issues and troubleshooting tips:

  • Script shows "Failed" in Intune: If Intune reports a script deployment as failed, it means the script returned a non-zero exit code or didn't complete properly. First, check if the script actually executed anything on the Mac. On the target Mac, examine the Intune logs: the Intune management agent logs are in /Library/Logs/Microsoft/Intune/ (look for files like IntuneMDMDaemon*.log and IntuneMDMAgent*.log). These logs can show script output or errors. A common reason for "failed" is forgetting to exit 0 — if your script ends without an explicit exit, the last command's status might have been non-zero. Always end with exit 0 on success. If a specific command in the script failed (exit code 1, for example), you'll need to adjust the script to handle that. Intune's reporting doesn't give detailed error messages from the script, so adding your own logging (echo statements or writing to a file) around critical commands helps pinpoint the failure.

  • Script not executing at all on device: If it seems the script never ran on a Mac (no changes made, nothing in logs), verify a few things:

    • Intune Management Extension (IME) installed: The Intune agent (IME) is required to run scripts. It should auto-install when a script is assigned. On a Mac, you can check /Applications/Microsoft Intune Agent.app or the presence of /Library/Logs/Microsoft/Intune/IntuneMDMDaemon.log. If it's missing, ensure the device is correctly enrolled as corporate (Intune doesn't run custom scripts on user-enrolled devices). You might try re-syncing the device (via Company Portal or terminal sudo profiles -U -type enrollment to trigger an MDM sync). In Intune portal, confirm the device is listed as compliant/active. If IME isn't installing, it could be a connectivity issue or an enrollment type issue.
    • Policy assignment: Double-check that the device is indeed in the Azure AD group targeted by the script policy. It's easy to accidentally target a user group while your device is only in a device group, or vice versa. Also, Intune won't deliver the script if the assignment doesn't reach the device. In the Intune portal, under the script's Device status, see if the device is listed at all. If not, the assignment might not include that device or the device hasn't checked in yet.
    • Proxy or network issues: If the Mac is behind a firewall or proxy that blocks Intune services, the agent might not receive the script. Intune for macOS requires direct internet access (no proxy). Ensure the device can reach Intune's endpoints. Also ensure the date/time on the Mac is correct (incorrect time can sometimes affect TLS connections).
  • Permission denied / Operation not permitted errors: If the script ran but certain commands failed with permission errors, it might be due to macOS privacy protections (TCC) or running in wrong context. For example, if your script (running as root) tries to modify something in a user's ~/Library that is protected by macOS (like ~/Library/Application Support for an app, which might require the user's consent if accessed by an app), you could hit "Operation not permitted" due to TCC. Running as the logged-in user might solve it, or you may need to deploy a Privacy Preferences Policy (PPPC) via Intune to grant the Intune agent Full Disk Access if you are doing something like accessing Calendar, Contacts, etc. If running as user and seeing permission issues, maybe the script needed root. Determine the correct context (user vs root) and adjust the Intune setting for the script. Also ensure any file operations in the script have proper sudo if needed. If you see "permission denied", it could also be the script file itself wasn't marked executable — Intune usually handles this when delivering the script, but as a sanity check, your uploaded .sh file should have appropriate permissions. Usually uploading through the portal is fine; if you created the file on Windows and it has CRLF line endings, that could confuse the shell. Ensure the script file uses Unix line endings (LF). Re-edit on a Mac or a proper code editor if necessary.

  • Script succeeds in Intune but desired outcome not seen: Intune reports success (exit 0), but the change didn't actually happen on the Mac. This could mean the script logic didn't actually do what you intended. It might exit 0 prematurely or the commands didn't target the correct items. For example, if you meant to modify a user setting but ran as root, the script might have run and done "something" (exit 0) but in root's context or a system context where it had no effect on the user. In such cases, review the script: perhaps it needed run as user = Yes. Another scenario: your script installed an app successfully (exit 0), but maybe the app wasn't actually installed due to a path issue. Re-check paths and conditions in the script. Use logging in the script to verify each step. You can also test by running the same commands manually on a Mac to see if the effect is visible. Sometimes timing can be an issue: e.g., a configuration script that runs at login might need a delay if it tries to do something before the system is fully ready. Intune doesn't provide a built-in delay, but you can script a short sleep if absolutely needed (not usually necessary).

  • Intune says script pending or long delay: Intune's reporting might not update if the device hasn't checked in. If you just assigned a script and don't see any status after a while, try manually triggering a check-in on the Mac. You can open Company Portal app and sync, or run sudo IntuneMDMAgent & (if that binary is accessible) or simply reboot (as the Intune agent usually checks in at startup and then roughly every 8 hours). If a script is set to "run once", after it runs the first time, Intune won't show subsequent attempts. For debugging, you could temporarily change it to run daily to force another run for testing (remember to set it back or remove assignment afterward).

  • Collecting logs for troubleshooting: If an issue is widespread or hard to diagnose, Intune has a log collection feature for macOS shell scripts. Via the Intune portal, you can initiate log collection on a device which will gather the Intune agent logs and any specified log file paths you provide. The next time the device checks in, it will upload these logs, which you can download from the Intune portal. This can be very handy to get on-device information without physical access. Use this to retrieve your script's logs (if you output to a file) or the agent's logs for analysis. Remember the device must be online and Intune-connected for this to work, and there are size limits (max 60 MB and 25 files).

  • Script runs but effect reverses or doesn't persist: If you find that a setting change made by script gets overwritten, consider that some other profile or policy might be conflicting. For example, if you use a script to set a preference that is also managed by a configuration profile (either Intune or another MDM), the profile might re-assert its value. Generally, Intune's custom configuration profiles or compliance policies could conflict with script actions. It's best to manage a particular setting via one method to avoid a "fight" between a script and a profile. If you must use a script to counteract something, ensure no other policy is undoing it. Similarly, some apps might overwrite settings on launch (e.g., if you script a change to an app config but then the app updates and changes it back). In such cases, a recurring script (enforcement) might be needed, or a different approach.

In summary, troubleshooting Intune-deployed scripts often comes down to verifying the script's execution and context on the Mac. Leverage Intune's reporting and logs on the device. Most issues can be resolved by adjusting the script or Intune settings (for example, correcting paths, adding necessary permissions, or changing run context). With careful logging and step-by-step analysis, even tricky deployment problems can be identified and fixed.

Conclusion

Deploying custom shell scripts via Microsoft Intune unlocks powerful management capabilities for macOS beyond native MDM profiles. By following the steps to create, test, and upload scripts properly, and using the provided examples as inspiration, IT administrators can automate software installations (Zoom, Chrome, VPN clients, etc.), enforce important settings (security configurations like disabling guest accounts, standardizing time zones or Dock layouts), and schedule maintenance routines – all from the cloud with Intune. Remember to apply best practices when writing scripts (proper shebang, idempotent logic, correct privileges, error handling) to ensure smooth execution on every Mac. Intune's scheduling and retry options, combined with thorough testing, will help your scripts deploy reliably across the fleet.

With the included troubleshooting tips, you'll be equipped to diagnose and resolve any issues that arise, from script syntax errors to permission woes. Over time, you can build a library of proven shell scripts tailored to your organization's needs, greatly reducing manual effort for Mac management. Intune's ability to package and deploy these custom scripts at scale means even complex tasks can be handled consistently and automatically on all your macOS devices. Embrace this capability to streamline your Mac administration, and enjoy the benefits of a well-managed, up-to-date, and compliant Mac environment using the power of Intune and shell scripting. Happy scripting!