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.
This script fills that gap. It reads computer inventory from Jamf Pro, pulls the EA your baseline emits, normalizes whatever format it finds, and writes two CSVs: one per-device view with the failing items for each machine, and one fleet-level summary of unique failing items with counts. The goal is boring on purpose. You run it, it writes files, you attach those files to a ticket or a GRC record, and you can reproduce the process tomorrow without reinventing the report.
The problem this solves
Compliance baselines are great at enforcing state. Where teams get stuck is at the reporting layer—turning console views and ad-hoc exports into a dated artifact that stands up in an audit. People copy lists, paste them into spreadsheets, and lose the thread the next time someone asks for “the same snapshot for last Tuesday.” Evidence should be reproducible, timestamped, and easy to compare over time. That’s what these two CSVs are meant to be.
There’s also the question of signal. When you’re chasing individual devices from a dashboard, it’s hard to tell which failures are actually driving risk at scale. A simple count by failing item puts that in focus immediately. The script’s fleet summary file gives you that lens so you can prioritize remediation tasks and prove progress with before/after runs instead of screenshots.
How it works
Under the hood, the script authenticates to the Jamf Pro Modern API and pages through computer inventory. It reads the EA you’ve designated for compliance output—commonly the one populated by your mSCP baseline—and then parses the content into a consistent model. It’s defensive by design: if your EA is JSON in one environment and pipe-delimited or multiline in another, the parser still produces clean rows. A special case is “No baseline set.” You’ll see that status on the per-device report so you can fix scoping, but it’s excluded from the fleet summary so it doesn’t distort the counts. The point is predictable output that compares cleanly across days and audits.
Requirements
You need a Jamf Pro API account with read access to inventory and authentication endpoints, and you should already be deploying a compliance baseline that populates the EA this script reads. On the runtime side, plan to use the MacAdmins Python framework on your admin host or runner—the script expects to be invoked with the managed_python3 shim that’s standard in a lot of MacAdmin shops. With those pieces in place, you can run locally for ad-hoc snapshots or schedule it to produce daily evidence.
Usage
Export credentials first. OAuth client credentials are preferred; username/password will work as a fallback:
# OAuth (recommended)
export JAMF_URL="https://yourorg.jamfcloud.com"
export JAMF_CLIENT_ID="your_client_id"
export JAMF_CLIENT_SECRET="your_client_secret"
# or username/password fallback
export JAMF_USER="jamf_api_reader"
export JAMF_PASSWORD="••••••••"
Then run the tool:h
/usr/local/bin/managed_python3 "JAMF Compliance Reports.py" --ea-name "Compliance - Failed Result List" --out-dir "./Reports"
You’ll end up with two files—compliance_failed_by_device.csv and compliance_failed_counts.csv—in the output directory you specify. Save them with the date in the filename or drop them into an evidence bucket you control so they form a reliable trail.
Operational notes
If a large slice of the fleet reports “No baseline set,” fix that first. It’s almost always scoping or profile precedence, and until baselines land consistently you’ll be chasing noise. Once baselines are stable, the fleet summary makes prioritization obvious. There are usually a handful of recurring items that deserve focused remediation or a profile cleanup; when you fix those, the counts move quickly and the before/after story is easy to tell. Treat the CSVs as artifacts, not just diagnostics. Store them in a place with retention and immutability so you can answer “what did this look like last quarter?” without rebuilding anything.
Where POA&M fits
A Plan of Action and Milestones (POA&M) is the administrative counterpart to technical remediation. It’s a record that captures the weakness, the owner, the plan, and the dates—then closes with evidence. The per-device CSV tells you exactly which systems and users are in scope so you can assign work with precision. The fleet summary gives you a rational way to prioritize and communicate risk. When you attach a dated CSV to the POA&M record, and later attach a newer one showing the reduction or closure, you’ve moved from “we know this is a problem” to “we fixed it on purpose and here’s the proof.” That’s what auditors expect, and it’s healthier operationally because the process is repeatable.
If you want the nuts and bolts, the code lives here: Scripts/Security/NIST in my repo. It’s intentionally small. Run it, produce the two files, and keep moving.
Sources
- JAMF Pro Compliance Report Script - REPO & Readme
- Apple: macOS Security Compliance Project overview and docs — Apple Platform Security / mSCP site (NIST Pages).
- Jamf: Compliance Editor baseline guidance — Trusted Jamf Docs • Jamf Pro API — API Overview / API Authentication.
- NIST CSRC: Plan of Action & Milestones (POA&M) — CSRC Glossary.
- MacAdmins Python: framework used widely with Jamf — GitHub Repo / Releases.
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.33 · Moderate AI Influence
Summary
This script fills the gap in compliance reporting by producing two CSVs: one per-device view with failing items and one fleet-level summary of unique failing items with counts.
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.
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.
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.