Menu Close

SYM-Lite (1.5.1)

SYM-Lite is a lean, purpose-built script for executing MDM-agnostic Installomator labels and Homebrew casks / formulas, as well as Jamf Pro-specific policy triggers, all through a unified swiftDialog selection and reporting interface.

Slideshow

Key Features

  • Unified execution support — Installomator labels, Homebrew casks / formulas, and / or Jamf Pro policies in a single session
  • Interactive selection UI — Checkbox dialog with per-item icons; selectable items start checked and previously installed items are automatically disabled
  • Focused selection lists — Optionally limit the interactive dialog to specific items via Parameter 5, so one script can back several Self Service policies
  • Alphabetical sorting — All Installomator, Homebrew and Jamf Pro policy items are sorted together by display name
  • Early Installomator validation — Labels are verified against your active Installomator file, which must pass root ownership and permission checks
  • Homebrew support — Casks and formulas run in the logged-in user context (with ~/Applications for non-admin users) and never hang on a sudo prompt
  • Inspect Mode — Real-time progress monitoring in a moveable, minimizable window
  • Silent mode — CSV-based automation support
  • Path-based validation & cache monitoring
  • Completion report — Per-item results with optional restart prompt
  • Hardened runtime — Root-owned hand-off files and binary paths; exits non-zero when any item fails so Jamf Pro reports failed runs
  • Graceful interruption — Clean shutdown on SIGINT/SIGTERM

Quick Start Guide

The latest version of SYM-Lite.zsh is always available on GitHub.

1. (Optional) Add Installomator Labels

Edit the installomatorLabels array near the top of SYM-Lite.zsh:

installomatorLabels=(
    "label | Display Name | Validation Path | Icon URL"
)

Example:

# Installomator Labels
# Format: "label | Display Name | Validation Path | Icon URL"
installomatorLabels=(
    "androidstudio | Android Studio | /Applications/Android Studio.app | https://use2.ics.services.jamfcloud.com/icon/hash_f7021d808263d18f52ba2535ec66d35f8bb24b08ab9bff6aee22ecb319159904"
    "awsvpnclient | AWS VPN Client | /Applications/AWS VPN Client/AWS VPN Client.app | https://usw2.ics.services.jamfcloud.com/icon/hash_1d1bef5523d9f7eca5a45f2db9a63732e85edb5f914220807ca740ba7c4881b9"
    "bruno | Bruno | /Applications/Bruno.app | https://usw2.ics.services.jamfcloud.com/icon/hash_48501630ad2f5dd5de3e055d6acdda07682895440cad366ee7befac71cab1399"
    "charles | Charles Proxy | /Applications/Charles.app | https://use2.ics.services.jamfcloud.com/icon/hash_59b395ca81889a6d83deda8e6babc5ae4bc5931d36a72b738fe30b84d027593d"
    "codex | OpenAI ChatGPT Codex | /Applications/ChatGPT.localized/ChatGPT.app | https://usw2.ics.services.jamfcloud.com/icon/hash_be9d2917e81980484f875d9056e5e4aa45d59dffa7b03c20f8dbb5137e96ee26"
    "docker | Docker | /Applications/Docker.app | https://usw2.ics.services.jamfcloud.com/icon/hash_a344dca5fdc0e86822e8f21ec91088e6591b1e292bdcebdee1281fbd794c2724"
    "firefoxesr | Firefox ESR | /Applications/Firefox.app | https://appinstallers-packages.services.jamfcloud.com/icons/0B3.png"
    "homebrew | Homebrew | ${homebrewPrefix}/bin/brew | https://usw2.ics.services.jamfcloud.com/icon/hash_9edff3eb98482a1aaf17f8560488f7b500cc7dc64955b8a9027b3801cab0fd82"
    "jetbrainsintellijidea | IntelliJ IDEA | /Applications/IntelliJ IDEA.app | https://usw2.ics.services.jamfcloud.com/icon/hash_f669d73acc06297e1fc2f65245cfbdace03263f81aebf95444a8360a101b239d"
    "nova | Nova | /Applications/Nova.app | https://use1.ics.services.jamfcloud.com/icon/hash_2386d11c960c252a4db75f49b5e82e5ba7adc1394a446e6ce11a91227d842c37"
    "otter | Otter AI | /Applications/Otter.app | https://use1.ics.services.jamfcloud.com/icon/hash_c53dfc2bc61084eec32f9825e57f836b181c2d9fb85ba5a9693ab11bc6f9ec31"
    "pique | Pique | /Applications/Pique.app | https://usw2.ics.services.jamfcloud.com/icon/hash_7d2539860cca6ec5ea5a71cba2aee7d93b9534e4267c16f73c7035f3dc025b9c"
    "visualstudiocode | Visual Studio Code | /Applications/Visual Studio Code.app | https://appinstallers-packages.services.jamfcloud.com/icons/0AF.png"
)

Because root executes Installomator, organizationInstallomatorFile must be an absolute path that is not a symlink, and the file and every parent directory up to / must be owned by root with no group or other write bit. (The default App Auto-Patch location meets this requirement.)

If the Installomator file is missing, fails this check, or cannot be parsed, SYM-Lite hides Installomator labels for that run while Homebrew and Jamf Pro items remain available.

2. (Optional) Add Homebrew Items

Edit the homebrewItems array (prefix with cask: or formula:):

homebrewItems=(
    "cask:token | Display Name | Validation Path | Icon URL"
    "formula:token | Display Name | Validation Path | Icon URL"
)

Example:

# Homebrew Items
# Format: "cask:token | Display Name | Validation Path | Icon URL"
homebrewItems=(
    "cask:1password-cli | 1Password CLI | ${homebrewPrefix}/bin/op | https://usw2.ics.services.jamfcloud.com/icon/hash_9456dcae0b68fa522a7b411e7ebd2f9062a1a60cb0681ab3cbad3dda64a410c6"
    "cask:claude-code | Claude CLI | ${homebrewPrefix}/bin/claude | https://appinstallers-packages.services.jamfcloud.com/icons/6DC.png"
    "cask:codex | codex-cli | ${homebrewPrefix}/bin/codex | https://usw2.ics.services.jamfcloud.com/icon/hash_9d2a1b6f204d2a0d6e99dfc7a411edc0d269c1ab748514dcdde46ea7b4277e51"
    "formula:direnv | direnv | ${homebrewPrefix}/bin/direnv | https://usw2.ics.services.jamfcloud.com/icon/hash_a9a7557b3142dd165372a1e66bca2533c783723956f1415861eac6fd5058b588"
    "cask:mem | Mem AI | /Applications/Mem.app | https://use1.ics.services.jamfcloud.com/icon/hash_62e0fba2609b56b27ddaafa0c4add4d0b2ce372094ad12f6b8a05f2bfe2cc236"
    "cask:soulver | Soulver AI | /Applications/Soulver 3.app | https://use1.ics.services.jamfcloud.com/icon/hash_d6c332f220193ed32f94839dde785921185b4ecc4de6687b5ef9d7a0add42dca"
    "cask:wpsoffice | WPS Office | /Applications/wpsoffice.app | https://use1.ics.services.jamfcloud.com/icon/hash_ed541f6a4ce8422f9230153519391cb9095744d2e459e1baa3453df4dab5db5b"
)

Notes:

  • ${homebrewPrefix} resolves to /opt/homebrew on Apple silicon and /usr/local on Intel
  • When the logged-in user is not a local administrator, casks install to ~/Applications (validation paths under /Applications/ also match ~/Applications/)
  • Homebrew runs with HOMEBREW_NO_SUDO=1; casks needing sudo fail fast and report “Requires administrator rights” instead of prompting for a password
  • homebrewAutoTrustItems="true" (default) runs brew trust for third-party tap items (e.g., formula:hashicorp/tap/terraform) before install
  • homebrewAutoRemoveQuarantine="true" (default false) removes com.apple.quarantine from a cask’s .app, only when Gatekeeper accepts the app
  • homebrewCreateCompletionDirectories="true" (default) pre-creates shell completion directories under the brew prefix so cask completions can install; if brew succeeds but reports permission errors, the item shows “Ready to use; Homebrew reported warnings”

To disable Homebrew entirely, set enableHomebrewItems="false".

3. (Optional) Add Jamf Pro Policy Triggers

Edit the jamfPolicyItems array:

jamfPolicyItems=(
    "trigger | Display Name | Validation Path | Icon URL"
)

Example (supports full icon URLs or SF Symbols):

# Jamf Pro Policies
# Format: "trigger | Display Name | Validation Path | Icon URL"
jamfPolicyItems=(
    "appleXcode | Xcode | /Applications/Xcode.app | https://usw2.ics.services.jamfcloud.com/icon/hash_583afb5af440479d642b3c35ec4ec3ad06c74ec814dba9af84e4e69202edf62a"
)

If the Jamf binary is missing at jamfBinary (default: /usr/local/jamf/bin/jamf), SYM-Lite logs a warning and removes Jamf Pro policy items from that run.

Mac Admins using a non-Jamf MDM should set enableJamfPolicyItems="false".

4. Usage

Interactive Mode (Default)

sudo zsh /path/to/SYM-Lite.zsh
  1. Selection dialog appears with all configured and validated items (or only those listed in Parameter 5); selectable items start checked when selectionDialogDefaultChecked="true"
  2. Select items using checkboxes
  3. Inspect Mode shows real-time progress
  4. Completion report with per-item results
  5. Optional restart prompt

Limit the Interactive Selection Dialog

Parameter 5 is optional in interactive mode. When set, the selection dialog shows only the listed item IDs, so one copy of SYM-Lite can back several focused Self Service policies (e.g., “Developer Tools”):

sudo zsh /path/to/SYM-Lite.zsh "" "" "" interactive "homebrew,cask:1password-cli,cask:claude-code,cask:codex,formula:direnv"
  • An empty Parameter 5 shows all available items
  • Listed items are still sorted by display name; unknown or unavailable item IDs are logged and skipped
  • If Parameter 5 contains no valid item IDs, SYM-Lite shows a “No selectable items” dialog (it never falls back to the full list)
  • Homebrew items are hidden until brew is installed, so include the homebrew Installomator label in Homebrew-focused lists

Silent Mode

sudo zsh /path/to/SYM-Lite.zsh "" "" "" silent "androidstudio,appleXcode,cask:codex"

In Jamf Pro: Set Parameter 4 to silent and Parameter 5 to the comma-separated list of item IDs exactly as configured in the item arrays (e.g., homebrew, not jamf policy -event homebrew). The script exits non-zero when any item fails, so Jamf Pro reports the failed run.

Jamf Pro Configuration

  1. Add your customized SYM-Lite.zsh script to Jamf Pro
  2. Create a Policy and configure:
    • Parameter 4: silent, or interactive / blank for interactive
    • Parameter 5: comma-separated item IDs (silent: items to run; interactive: optional selection dialog allowlist)
  3. Test the policy
5. What’s New (1.3.0 – 1.5.1)

1.5.1

  • Homebrew installs that exit 0 but report child-process or permission errors now log a [WARNING] and show “Ready to use; Homebrew reported warnings” (Issue #24)
  • Before the first Homebrew install of each run, SYM-Lite creates shell completion directories under the brew prefix as the Homebrew user; disable with homebrewCreateCompletionDirectories="false" (Issue #24)

1.5.0

  • Interactive mode honors a non-empty Parameter 5 as a selection dialog allowlist; an empty value still shows all items (FR #23)
  • Interactive mode shows a “No selectable items” dialog when Parameter 5 contains no valid item IDs

1.4.0

  • New items: Claude CLI, Mem AI, Soulver AI and WPS Office (Homebrew); Firefox ESR, Nova and Otter AI (Installomator)
  • Homebrew: third-party tap auto-trust (homebrewAutoTrustItems), optional quarantine removal (homebrewAutoRemoveQuarantine), ~/Applications for non-admin users, and HOMEBREW_NO_SUDO=1 so admin-only steps fail fast instead of hanging
  • Homebrew user is pinned for the run; a mid-run console-user change fails the remaining Homebrew items
  • Installomator ownership check now covers every parent directory and re-runs right before each label executes
  • swiftDialog bootstrap requires Gatekeeper acceptance as a notarized Developer ID package
  • Jamf Pro policy items are removed from the run when the Jamf binary is missing
  • Pre-flight warns on duplicate item IDs and on Homebrew prefix mismatches
  • “Restart Now” restarts only via loginwindow as the logged-in user, so apps can prompt to save

1.3.0

  • Validated with Monocle; swiftDialog hand-off files moved to a root-owned per-run directory, and /usr/local/bin removed from PATH
  • Added Installomator ownership and permissions check before executing labels
  • Exits non-zero when any item fails so Jamf Pro reports failed runs
  • Architecture-aware Homebrew validation paths (Intel: /usr/local; Apple silicon: /opt/homebrew)
  • Inspect Mode window is now moveable and minimizable; restart prompt hides default keyboard actions (swiftDialog 3.1.1+)

See the full CHANGELOG on GitHub.

Support

Community-supplied, best-effort support is available on the Mac Admins Slack (free registration required) in the #setup-your-mac channel, or you can open an issue on GitHub.

Posted in Jamf Pro, Scripts, Setup Your Mac, swiftDialog

Related Posts

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.