Back to All Cheatsheet Libraries cheatsheets

Jamf Pro

Smart groups, policies, scripting and extension attributes — the Apple enterprise management standard, end to end.

Jamf's model in one sentence

Smart Groups define who; Policies and Profiles define what. Almost every Jamf problem is really a scoping problem — something is applying to the wrong set of Macs, or to none. Learn Smart Groups properly and the rest of the product becomes straightforward.

Showing results
Area Object What it is Notes
ScopingSmart GroupA device or user group whose membership is defined by criteria and recalculated automatically.The single most important object in Jamf. Scope everything to these, never to static groups.
ScopingStatic GroupA manually curated list of specific devices.Justified for a genuine pilot cohort. If you find yourself maintaining one by hand long-term, it should have been a Smart Group.
ScopingScope / Limitations / ExclusionsThree separate tiers on every policy and profile: who it targets, what narrows it, and what overrides it.Exclusions always win. A device in both Scope and Exclusions is excluded — the usual answer to "why isn't this applying?"
DeliveryConfiguration ProfileA signed settings payload delivered over MDM — Wi-Fi, VPN, certificates, restrictions, FileVault, kernel/system extensions.Declarative and reversible: remove the profile and the setting reverts. Prefer profiles over scripts whenever a payload exists.
DeliveryPolicyAn action run by the Jamf binary on the Mac: install a package, run a script, bind, update inventory, cache a file.Agent-based, unlike profiles. Needs a trigger and an execution frequency — the two fields most often set wrong.
DeliveryTriggerWhat causes a policy to run: enrollment complete, startup, login, network state change, recurring check-in, or a custom event name.Custom triggers are invoked with jamf policy -event <name> — the backbone of chained provisioning workflows.
DeliveryExecution FrequencyOnce per computer, once per user, once per user per computer, once per day/week/month, or ongoing."Ongoing" runs at every check-in (roughly every 15 minutes). Setting a heavy install to Ongoing by accident is a classic self-inflicted outage.
DeliverySelf ServiceAn on-device app catalogue where users run policies themselves — installs, printer setup, password reset, VPN config.The highest-leverage thing Jamf offers. Every policy that could be user-initiated should be, to cut ticket volume.
InventoryExtension AttributeA custom inventory field populated by a script, a pop-up menu, or text entry.Lets you build Smart Groups on facts Jamf doesn't natively collect — Activation Lock state, a config file's contents, a specific app's version.
InventoryInventory Update (recon)The device reporting its full state back to Jamf. Run via jamf recon.Smart Group membership only changes after a recon. This is why a policy "doesn't apply" immediately after a change — see the Gotchas tab.
DeploymentPreStage EnrollmentThe ADE configuration: which Setup Assistant panes to skip, account type, whether enrollment is mandatory and non-removable.Devices must be assigned to Jamf in Apple Business Manager first. Changes only affect devices that haven't yet enrolled.
DeploymentPackage (.pkg)Software uploaded to a distribution point and installed by policy.Signed installer packages only — dragging a .app into a .pkg without correct ownership is a common failure. Build with pkgbuild or Composer.
DeploymentPatch ManagementJamf's title-based version tracking with automated update policies for common third-party apps.Good for mainstream titles; anything niche still needs AutoPkg or a manual package.

Smart Groups are the whole game

A well-designed Smart Group means a Mac automatically receives the right software the moment it qualifies, and automatically stops when it doesn't. A badly-designed one means someone manually adding devices forever.

1

Understand AND vs OR, and the parentheses

Criteria rows combine with And/Or, and Jamf gives you real parentheses. Without them, mixing And and Or produces results that look arbitrary. Always parenthesise explicitly rather than trusting evaluation order.

( Department is Design OR Department is Marketing ) AND Operating System like 15.
2

Learn the operators that matter

is / is not for exact matches. like / not like for substring matching — this is what you want for OS versions, since "like 15." catches every 15.x release. member of nests one Smart Group inside another, which is how you compose logic cleanly.

3

Build the four groups every environment needs

Not on latest OS (patch compliance), FileVault not enabled (security compliance), Has not checked in for 30 days (lost/stale devices), and App X not installed (deployment targeting). These four cover most of day-to-day fleet management.

4

Use "app not installed" for self-healing deployment

Scope an install policy to a Smart Group of Macs lacking the app, at Ongoing frequency. A Mac installs it, next recon removes it from the group, the policy stops targeting it. If someone uninstalls the app it rejoins the group and gets it back — self-healing with no manual intervention.

5

Remember membership is only as fresh as the last recon

Smart Groups recalculate on inventory update, not continuously. A Mac that just installed something won't leave the "missing app" group until it next reports in. Policies that need immediate re-evaluation should end with jamf recon.

Useful Smart Group criteria

Goal Criteria Notes
Macs not on the current OSOperating System Version — not like — 15.The trailing dot matters; without it "15" also matches 10.15.
FileVault not enabledFileVault 2 Status — is not — Boot Partitions EncryptedThe core encryption-compliance group. Scope a Self Service remediation policy to it.
App missingApplication Title — does not have — Slack.appDrives self-healing installs (step 4 above).
App outdatedApplication Version — is not — 4.38.0 + Application Title is Slack.appNeeds both rows, or Macs without the app at all match too.
Stale / possibly lostLast Inventory Update — more than x days ago — 30Review monthly. Long gaps usually mean offboarded-but-not-wiped hardware.
Apple silicon onlyArchitecture Type — is — arm64Essential when scoping anything that ships separate Intel/ARM builds.
Low disk spaceBoot Drive Available MB — less than — 10000Catch Macs that will fail an OS upgrade before you attempt it fleet-wide.
Unsupervised / not ADEEnrollment Method — is not — PreStage enrollmentFinds manually-enrolled Macs that lack supervision-only capabilities.
Showing results
Command What it does When you'd use it
sudo jamf policyForces a check-in and runs any pending policies.The first thing to run when testing. Stop waiting for the 15-minute cycle.
sudo jamf policy -event <name>Runs only policies bound to that custom trigger.Chaining provisioning steps in a deterministic order from one script.
sudo jamf reconSubmits a full inventory update.After any change that should move a Mac between Smart Groups. End provisioning scripts with it.
sudo jamf manageRe-applies the management framework and MDM profile.Repairing a Mac that shows as enrolled but stopped responding to policies.
sudo jamf enroll -promptInteractively re-enrols the Mac.Last resort when the framework is broken beyond jamf manage.
sudo jamf removeFrameworkRemoves the Jamf binary and management framework entirely.Decommissioning or migrating to another MDM. Irreversible without re-enrolling.
jamf displayMessage -message "text"Shows a basic dialog to the user.Quick notifications. swiftDialog is far better for anything user-facing and polished.
sudo jamf logShows the Jamf log location and recent activity.Debugging. The real log lives at /var/log/jamf.log.
tail -f /var/log/jamf.logFollows policy execution live.Watching a policy actually run — the single most useful debugging move.
sudo jamf checkJSSConnectionTests connectivity to the Jamf server.Ruling out network/DNS before investigating policy logic.

Script parameters — the part that trips everyone up

Jamf scripts start at $4

Jamf passes three positional parameters automatically before yours: $1 mount point, $2 computer name, $3 username. Your first custom parameter is $4, and they run through $11. Writing a script that reads $1 for its own argument is the most common Jamf scripting mistake.

#!/bin/bash # Jamf reserves $1-$3. Custom parameters begin at $4. APP_NAME="$4" TARGET_VERSION="$5" # Scripts run as root. The console user must be derived, never assumed — # `whoami` returns root here, which is a classic source of silent bugs. CURRENT_USER=$(stat -f%Su /dev/console) USER_ID=$(id -u "$CURRENT_USER") if [ -z "$APP_NAME" ]; then echo "Parameter 4 (app name) is required" exit 1 fi # Run something as the logged-in user rather than root: launchctl asuser "$USER_ID" sudo -u "$CURRENT_USER" /usr/bin/defaults read com.example.app # Exit codes matter: non-zero marks the policy failed in Jamf's logs. exit 0

Extension Attribute example

An EA script must echo its value wrapped in <result> tags. This one reports Activation Lock status, which Jamf doesn't collect natively — then you can build a Smart Group on it.

#!/bin/bash # Extension Attribute: Activation Lock Status # Data type: String — then Smart Group on "is Enabled" STATUS=$(system_profiler SPHardwareDataType 2>/dev/null \ | awk -F': ' '/Activation Lock Status/{print $2}') [ -z "$STATUS" ] && STATUS="Unknown" echo "<result>$STATUS</result>"

Zero-touch provisioning with Jamf

1

Assign devices to Jamf in Apple Business Manager

ABM → Devices → select serials → Edit MDM Server → your Jamf instance. Nothing works until this is done; a Mac not assigned in ABM will never enrol automatically no matter what Jamf is configured to do.

2

Build the PreStage Enrollment

Skip the Setup Assistant panes you don't want (Siri, Screen Time, Apple ID, Analytics, TouchID). Set enrollment to mandatory and non-removable. Make the first account Standard, not Administrator, and create a hidden management account.

3

Chain the provisioning with custom triggers

One "enrollment complete" policy runs a script that calls each subsequent stage by custom trigger, in order. This gives you deterministic sequencing, which scoping several independent enrollment-triggered policies does not.

jamf policy -event install-core-apps jamf policy -event configure-dock jamf policy -event enable-filevault jamf recon
4

Show progress with swiftDialog

A Mac that appears idle for twenty minutes gets rebooted by an impatient user, breaking provisioning. Drive a swiftDialog progress window from the orchestration script (or use Jamf's own Setup Manager) so each completed step is visible.

5

Finish with a recon

Always end provisioning with jamf recon so Smart Group membership reflects the newly-installed state immediately, rather than at the next scheduled check-in.

Self Service — the ticket-deflection layer

What belongs in Self Service
  • Optional software — anything not everyone needs. Users install on demand rather than raising a ticket.
  • Printer setup — one policy per printer/location, scoped by building. Removes an entire category of tickets.
  • Remediation actions — "Repair Jamf connection", "Re-run enrollment", "Enable FileVault". Users fix themselves, and it's safer than talking someone through Terminal.
  • Diagnostics — a policy that runs a script gathering logs and uploads them, so support requests arrive with data attached.
  • Give every item a real icon and a plain-English description. An unlabelled catalogue doesn't get used.
What doesn't
  • Anything mandatory — security baselines belong in profiles scoped to everyone, not an opt-in button.
  • Anything destructive without a confirmation dialog. Self Service has no undo.
  • Long-running installs with no progress indication — users will assume it hung and run it repeatedly.

Gotchas

"Why isn't my policy running?" — the checklist
  • Scope. Check Exclusions first — they override Scope entirely, and this is the most common cause.
  • Smart Group staleness. Membership only updates on recon. Run sudo jamf recon then sudo jamf policy.
  • Execution frequency. "Once per computer" means it already ran and won't run again — use Flush Policy Logs to reset it for testing.
  • Trigger mismatch. A policy set to "Recurring check-in" won't fire from jamf policy -event foo.
  • Policy disabled, or outside its Client Side Limitations date range.
  • Watch it live: tail -f /var/log/jamf.log while running sudo jamf policy.
PPPC / TCC is its own discipline
  • macOS blocks apps from Full Disk Access, Screen Recording, Accessibility, camera, and mic until explicitly allowed — user prompts can't be scripted away.
  • Use a PPPC (Privacy Preferences Policy Control) profile to pre-approve them. Only MDM-delivered profiles can do this; a script cannot.
  • PPPC requires the app's exact bundle ID and code requirement string. Get it with codesign -dr - /Applications/App.app.
  • PPPC Utility (from the Mac admin community) generates these profiles correctly — hand-writing the code requirement is error-prone.
FileVault and Secure Token on Apple silicon
  • A user needs a Secure Token to enable FileVault or install OS updates. Tokens are granted by an existing token holder, not by MDM alone.
  • The first account created on the Mac gets the token — which is why the PreStage account setup matters so much.
  • A management account created by script afterwards typically has no token and will fail at FileVault operations. Use a Bootstrap Token, escrowed to Jamf, to solve this properly.
  • Verify with sysadminctl -secureTokenStatus <user> and profiles status -type bootstraptoken.
Certificates expire and take the fleet with them
  • The APNs certificate expires annually. Let it lapse and every Mac silently stops responding to MDM commands.
  • Renew with the same Apple ID that created it. A different Apple ID means re-enrolling every device — use a shared team account, never a personal one.
  • The ADE/ABM token also expires yearly and needs re-uploading.
  • Diarise both. They're the most common self-inflicted Jamf outage by a wide margin.

Tips

Always scope to a test group first

Keep a Static Group of your own devices and scope every new policy there before widening. Jamf has no undo, and "Once per computer" at fleet scale is unforgiving.

Use the API for anything repetitive

Jamf Pro has a full REST API plus the newer Jamf Pro API. Bulk edits, reporting, and offboarding automation belong there rather than in the console.

Flush policy logs to re-test

A "once per computer" policy won't re-run on a machine that already has it logged. Policy → Logs → Flush resets that, which is essential during development.

Pair with AutoPkg

AutoPkg with JSSImporter or jamf-upload keeps third-party app packages current automatically, instead of manually downloading and repackaging each release.

swiftDialog over displayMessage

jamf displayMessage is a plain alert. swiftDialog gives branded dialogs, progress bars, and forms — a large upgrade for anything user-facing.

Jamf Nation and Mac Admins Slack

Almost every Jamf problem has been solved publicly already. Jamf Nation's forums and the #jamf channel on Mac Admins Slack are faster than support for most questions.

Resources