Cleaning House in Jamf Pro: A Friendly Auditor Script for Real-World Hygiene
There’s a tipping point in every Jamf Pro environment where the policy list begins to feel like a junk drawer. Everyone means well. Nobody deletes anything. And then, months later, you’re trying to answer simple questions like: Which policies are actually scoped? What’s no longer referenced? Why are there five versions of the same script? This post covers a small, practical script I wrote to help you see what’s stale, explain why it’s stale, and (optionally) park it safely out of the way—without deleting a thing.
If you want to jump straight to the code, the repo lives here:
- Script & folder: Jamf Maintenance (Auditor)
What the Jamf Pro “Cleanup Auditor” does
In plain terms: it inventories your Jamf Pro objects via the Modern API and runs a few hygiene checks that mirror how humans actually review environments:
- Unscoped policies and macOS configuration profiles—objects that never target anything.
- Unused scripts, packages, and computer groups—things referenced by nothing.
- “Dead” policies—no triggers and not in Self Service (they’ll never run).
- Exposed policies—active and in Self Service (useful when you’re auditing what’s user-visible).
By default it’s read-only and prints tidy tables you can review in a few minutes. If you want to take action, there’s an opt-in switch to move flagged items into an archive category (e.g., z_Archive). That’s reversible and keeps your history intact.
Why this matters in the real world
This isn’t about shaming old work; it’s about shrinking the surface area of future mistakes. Stale objects create accidental scope, duplicate logic, and mystery behaviors months later. When your list is clean, every next change gets easier: fewer collisions, clearer review, and faster incident response. If auditors ever ask about process, being able to show a simple, recurring hygiene pass goes a long way.
Requirements (one time)
You’ll run the script with MacAdmins Python so the interpreter and libraries are consistent across admin hosts.
-
Jamf Pro role with read rights to policies, profiles, scripts, packages, groups.
If you want to park items in an archive category, that role also needs write permission to update categories.
The script prefers OAuth client credentials. It will fall back to username/password if OAuth isn’t enabled on your tenant.
Install MacAdmins Python (once)
Follow these steps on your admin Mac (or wherever you run Jamf tooling):
- Download the latest MacAdmins Python pkg from the releases page.
- Install the package (double-click the
.pkgor useinstaller). - Confirm it’s available:
/usr/local/bin/managed_python3 --versionYou should see a Python 3.x version. From here on, we’ll use
/usr/local/bin/managed_python3to run the script.
Configure Jamf credentials
Use OAuth client credentials if possible; otherwise username/password works too. Export them in the shell before running the auditor:
OAuth (recommended)
export JAMF_URL="https://yourorg.jamfcloud.com"
export JAMF_CLIENT_ID="your_client_id"
export JAMF_CLIENT_SECRET="your_client_secret"
Username/Password (fallback)
export JAMF_URL="https://yourorg.jamfcloud.com"
export JAMF_USER="api_reader"
export JAMF_PASSWORD="••••••••"
The script will first try /api/oauth/token (and the older /oauth/token path), then gracefully fall back to /api/v1/auth/token with user/pass if needed. Tokens refresh automatically.
Quick start (read-only)
/usr/local/bin/managed_python3 "JAMF Auditor.py"
You’ll see sections like:
- Unscoped Policies
- Unscoped macOS Configuration Profiles
- Unused Scripts / Packages / Computer Groups
- Policies with NO Triggers AND NOT Self Service
- Active Policies with Self Service enabled
That should be enough to triage in a quick session.
JSON output (for tickets, CI, dashboards)
If you’d rather capture results for a ticket, Slack post, or dashboard:
/usr/local/bin/managed_python3 "JAMF Auditor.py" \
--format json --out audit.json
The JSON includes friendly “why” helpers so you can pick apart a single object when someone asks for detail:
/usr/local/bin/managed_python3 "JAMF Auditor.py" --why-policy 123
/usr/local/bin/managed_python3 "JAMF Auditor.py" --why-profile 456
Optional: move clutter to an archive category
When you’re ready to tidy without deleting:
/usr/local/bin/managed_python3 "JAMF Auditor.py" \
--move-to-archive --archive-category "z_Archive"
This only updates the category of flagged items, so it’s reversible and non-destructive.
Inline script (copy-ready)
If you prefer to fetch the exact current version straight from GitHub (no formatting surprises), this will drop JAMF_Auditor.py in your working directory:
curl -L \
https://raw.githubusercontent.com/jonbrown21/macOS-JAMF-Scripts/main/Scripts/JAMF/Maintenance/JAMF%20Auditor.py \
-o JAMF_Auditor.py
Or browse the repo page directly to read/inspect first:
A few operating notes
I run this in read-only mode as part of routine hygiene, and then use JSON mode when I want to capture a “before/after” diff in a ticket. Keeping an archive category creates a safe parking lot that you can revisit during change windows. If anything needs to come back, it’s one click away—and you’ve permanently removed noise from your daily view in the meantime.
If you’re starting with a very large environment, bump the timeout a bit (e.g., --timeout 45) and consider a scoped admin API role that only has what the script needs. That lowers risk and reduces the surface area for this service account.
References
- Script: Jamf Maintenance (Auditor) — repository directory
- MacAdmins Python — project · releases
- Jamf Pro API docs — Modern API authentication and endpoints
Ready to take your Apple IT skills and consulting career to the next level?
I’m opening up free mentorship slots to help you navigate certifications, real-world challenges, and starting your own independent consulting business.
Let’s connect and grow together — Sign up here
AI Usage Transparency Report
AI Era · Written during widespread use of AI tools
AI Signal Composition
Score: 0.32 · Moderate AI Influence
Summary
This script helps you see what's stale, explain why it's stale, and optionally park it safely out of the way—without deleting a thing.
Related Posts
Discovering Mole: A Command Line Utility for Mac Cleaning
Caches pile up, apps leave behind junk, and disk space slowly disappears. While there are plenty of GUI tools out there, most of them either lack transparency or feel overly bloated.
Scoring AI Influence in Jekyll Posts with Local LLMs
There’s a moment that kind of sneaks up on you when you’ve been writing for a while, especially if you’ve started using AI tools regularly. You stop asking whether AI was used at all, and instead start wondering how much it actually shaped what you’re reading. That shift is subtle, but once you notice it, you can’t really unsee it.
Automating JAMF Pro Email Notifications with SendGrid (Smart Group Driven Workflows)
Modern device management isn't just about enforcing policies—it's about communicating effectively with users at the right time. In JAMF Pro, Smart Groups give you powerful visibility into device state, but they don't natively solve the problem of proactive, automated user communication. Whether you're trying to prompt users to restart their machines, complete updates, or take action on compliance issues, bridging that gap requires a flexible and scalable notification system.
Turn Jamf Compliance Output into Real Audit Evidence
Most teams use Apple’s macOS Security Compliance Project (mSCP) baselines because they scale and they’re repeatable. Jamf’s tooling makes deployment straightforward and the Extension Attribute (EA) output is a convenient place to capture drift. What you don’t automatically get is the artifact an auditor will accept on a specific date—an actual document you can file that shows which endpoints are failing which items, plus a concise roll-up of failure counts you can act on. Smart Groups answer scope; they don’t produce evidence.
10 Things You Didn't Know You Could Do With Apple Configurator (That Save Mac Admins Hours)
Most of us treat Apple Configurator like a fire extinguisher: break glass, DFU, restore, move on. But it can do a lot more, and when you know the edges, you can turn a bricked morning into a ship-it afternoon. Below are ten things I regularly use (or wish I’d used sooner) that demonstrate its capabilities beyond just emergency recovery.
The Power of Scripting App Updates Without Deploying Packages
Keeping macOS environments up-to-date in a seamless, efficient, and low-maintenance way has always been a challenge for IT admins. Traditional package deployment workflows can be time-consuming, prone to versioning issues, and require extensive testing and repackaging. This can lead to frustration and wasted resources as IT teams struggle to keep pace with the latest updates and patches. But there's another way—a more elegant, nimble approach: scripting.
Detecting Invalid Characters and Long Paths in OneDrive on macOS
Microsoft OneDrive is widely used for syncing documents across devices, but on macOS, it can silently fail to sync certain files if they violate Windows filesystem rules — like overly long paths or invalid characters. This creates frustrating experiences for end users who don’t know why files aren’t syncing.
Using a script to Enable FileVault via JAMF: A Word of Caution
Enabling FileVault is a critical step in securing macOS devices, particularly in managed environments like schools, enterprises, and remote teams. For administrators using **Jamf Pro**, automating this process can simplify device onboarding and ensure compliance with disk encryption policies. This automation also helps reduce the administrative burden associated with manually configuring each device, allowing IT staff to focus on other tasks while maintaining a secure environment.
Automating Script Versioning, Releases, and ChatGPT Integration with GitHub Actions
Managing and maintaining a growing collection of scripts in a GitHub repository can quickly become cumbersome without automation. Whether you're writing bash scripts for JAMF deployments, maintenance tasks, or DevOps workflows, it's critical to keep things well-documented, consistently versioned, and easy to track over time. This includes ensuring that changes are properly recorded, dependencies are up-to-date, and the overall structure remains organized.