<< All versions

Skill v1.0.0

currentLLM-judged scan90/100
dan-snelson/mac-health-check/mac-health-check-selector
──Details
PublishedOctober 21, 2026 at 02:49 PM
Content Hashsha256:609f78cc8cf497f1...
Git SHA174b061fbbb9
──Files
Files (1 file, 29.5 KB)
SKILL.md29.5 KBactive
SKILL.md · 350 lines · 29.5 KB

version: "1.0.0" name: mac-health-check-selector description: Interactively prompts a Mac Admin to select which health checks to enable or disable in Mac Health Check (dan-snelson/Mac-Health-Check). Use when customizing MHC list items, health-check functions, external checks, or generating a tailored, validated, MDM-specific and date-stamped copy of Mac-Health-Check.zsh in Artifacts/. Triggers on phrases like "Mac Health Check checks", "which MHC checks", "customize MHC health checks", "select health checks for Mac Health Check", "MHC list items", or any request to choose or configure Mac Health Check compliance checks.


Mac Health Check Selector

Guide a Mac Admin through choosing which Mac Health Check (MHC) health checks to show and run, then write an edited, MDM-specific, date-stamped copy of Mac-Health-Check.zsh into Artifacts/, plus a sidecar .md that records the selection and validation results.

Target: Mac Health Check 5.0.0 and later. Full per-check data (exact list-item JSON, function arguments, shipped default order per MDM, artifact anchors) lives in references/health-checks.md. The write-and-validate procedure lives in references/artifact-procedure.md. The tested build-and-validate helper is scripts/build-artifact.zsh. Read both reference files before generating output. When they disagree with the admin's copy of Mac-Health-Check.zsh, trust the script.

Ground rules

  • Ask the MDM question first, every time. Do not skip, merge, or bury it.
  • Ask one step at a time. Wait for the answer before moving on.
  • Use numbered lists and check IDs (such as C1, M5) so replies parse without ambiguity (see Reply grammar).
  • Be non-destructive. Never edit Mac-Health-Check.zsh in place; write only to Artifacts/. Never commit or deploy anything.
  • Use placeholders for anything organization-specific: <YOUR_ORG_NAME>, <YOUR_WEBHOOK_URL>, <YOUR_SPLUNK_HEC_URL>, <YOUR_SPLUNK_HEC_TOKEN>, <YOUR_POLICY_TRIGGER>, <YOUR_ORGANIZATION_NETWORK>. Never invent real URLs, tokens, or branding.
  • Keep user-facing subtitles short and action-oriented.
  • Accept "defaults", "same as shipped", or "recommend for me" at any step; pick the shipped default and say so.
  • Change only which checks run, plus the optional removal of other MDMs' code (Step 4b). Every other setting keeps its Mac-Health-Check.zsh default (operationMode, mdmVendorUuid, external-check triggers, targeted remediation verification, developmentListitemJSON). Admins who want those changed edit the artifact manually.
  • Leave only passing artifacts in Artifacts/. A build that fails validation is never written there.

Step 1 — Ask which MDM is in use

Send this question alone and wait:

Which MDM manages these Macs? Reply with a number or type your own.
1. Jamf Pro
2. Fleet
3. JumpCloud
4. Microsoft Intune
5. Mosyle
6. Kandji / Iru
7. Addigy
8. Filewave
9. Other / MDM-agnostic / custom

Map the answer to the script's names:

AnswermdmVendorList-item arrayCase branch labelArtifact slug
1Jamf ProjamfProListitemJSON"Jamf Pro" )jamf-pro
2FleetfleetMdmListitemJSON"Fleet" )fleet
3JumpCloudjumpcloudMdmListitemJSON"JumpCloud" )jumpcloud
4Microsoft IntunemicrosoftMdmListitemJSON"Microsoft Intune" )microsoft-intune
5MosylemosyleListitemJSON"Mosyle" )mosyle
6KandjikandjiMdmListitemJSON"Kandji" )kandji
7AddigyaddigyMdmListitemJSON"Addigy" )addigy
8FilewavefilewaveMdmListitemJSON"Filewave" )filewave
9NonegenericMdmListitemJSON* )generic

The helper prints each MDM by its display name (Kandji / Iru, Other / MDM-agnostic for generic); use the same names with the admin and in the sidecar.

MDM-specific notes to carry forward:

  • All MDMs — the script picks its branch at runtime from the enrolled serverURL, not from the artifact name. An Intune artifact run on a Jamf Pro-enrolled Mac runs the unedited "Jamf Pro" ) branch, or the generic fallback when other MDMs were pruned (Step 4b).
  • Jamf Pro — only MDM with Jamf Pro Check-In, Jamf Pro Inventory, Jamf Hosts, Computer Inventory (jamf recon), and checkExternalJamfPro external checks. Entra ID Registration and Clock Skew ship in the Jamf Pro list. The script exits early if /private/var/log/jamf.log is missing.
  • Mosyle — adds Mosyle Check-In and the Mosyle Self-Service app check.
  • Fleet / Intune — add an MDM agent app presence check (Fleet Desktop / Microsoft Company Portal).
  • Kandji / Iru — detected when serverURL contains kandji; an Iru-branded URL without that string falls to the generic branch. Ask the admin to confirm their server URL. Ships a six-app set (A5a–A5f) and no MDM Profile row.
  • Addigy — ships with a blank mdmVendorUuid; MDM Profile will not pass until the admin fills it in manually.
  • Other — no MDM Profile or MDM Certificate Expiration, because no vendor profile or certificate name is known. Admins who know them edit mdmVendor, mdmVendorUuid or mdmProfileIdentifier, and the certificate name manually. The generic branch also runs on unenrolled Macs, where M4 Apple Push Notification service warns (APNs active; no MDM response) or fails.

Step 2 — Explain the purpose

After the MDM is known, say in two or three sentences:

Mac Health Check runs modular checks and shows each one as a row in the swiftDialog window. For <MDM>, each row is defined in <array name>, and each row's check runs from a matching runConfiguredHealthCheck line in the "<MDM>" case branch. We'll pick which checks to keep. Then I'll write an edited copy of the script to Artifacts/ with both parts in matching order, validate it, and record everything in a sidecar .md. Your Mac-Health-Check.zsh stays untouched.

Step 3 — Present the checklist

Show the checklist below, tailored to the MDM from Step 1:

  • `[off]` marks each available check that is not in that MDM's shipped default (for example H7, M2, A4 on Intune). The off group is the smaller one for every MDM, so the list stays quiet. Say once above the list: "Unmarked checks are on by default; [off] checks are available but off." (See Shipped default order per MDM in the reference.)
  • A5 shows the concrete app for the chosen MDM: A5 Fleet Desktop, A5 Microsoft Company Portal, A5 Mosyle Self-Service, or for Kandji A5a Microsoft One Drive, A5b Microsoft Outlook, A5c Company Portal, A5d Zoom, A5e Cortex, A5f Netskope.
  • "Not available for <MDM>" is one group at the end that lists, with a short reason:
  • Jamf Pro-only items (M5, M6, M13, A6–A10, F1) for every MDM except Jamf Pro;
  • other vendors' vendor-only items (M7 Mosyle Check-In unless Mosyle);
  • A5 when the MDM ships no agent app (Jamf Pro, JumpCloud, Addigy, Filewave, Other); offer an A4-style custom app instead;
  • M1 and M3 for Other.
  • Mark external checks with *.

Ask: "Reply defaults to keep the shipped list, or change it: H7 A4 adds, no A3 removes, only C, H1-H6, M4 picks exactly those."

Core OS & Security (C)

  • C1 macOS Version
  • C2 Available Updates (deferred, staged, and DDM-enforced)
  • C3 System Integrity Protection (SIP)
  • C4 Signed System Volume (SSV)
  • C5 Firewall
  • C6 FileVault Encryption
  • C7 Gatekeeper / XProtect
  • C8 Touch ID
  • C9 Password Hint
  • C10 AirDrop
  • C11 AirPlay Receiver
  • C12 Bluetooth Sharing
  • C13 VPN Client

Maintenance & Hygiene (H)

  • H1 Last Reboot
  • H2 Free Disk Space
  • H3 Desktop Size and Item Count
  • H4 Downloads Size and Item Count
  • H5 Trash Size and Item Count
  • H6 Memory Pressure (warning-only; 14-day JSON Lines history; warns on recurring pressure across 2 distinct days in 7)
  • H7 Clock Skew (ships for Jamf Pro; runs on any MDM)

MDM & Connectivity (M)

  • M1 <MDM> MDM Profile
  • M2 Entra ID Registration (ships for Jamf Pro; reads the JamfAAD plist, Platform SSO, and the MS-ORGANIZATION-ACCESS certificate; on other MDMs it passes as Not Applicable unless that certificate exists, which reports Partial (warning) — review before using elsewhere)
  • M3 <MDM> MDM Certificate Expiration
  • M4 Apple Push Notification service (APNs)
  • M5 Jamf Pro Check-In [Jamf Pro only]
  • M6 Jamf Pro Inventory [Jamf Pro only]
  • M7 Mosyle Check-In [Mosyle only]
  • M8 Apple Push Notification Hosts
  • M9 Apple Device Management
  • M10 Apple Software and Carrier Updates
  • M11 Apple Certificate Validation
  • M12 Apple Identity and Content Services
  • M13 Jamf Hosts [Jamf Pro only]
  • M14 Wi-Fi Strength
  • M15 Network Quality Test (slowest check)

Applications & Tools (A)

  • A1 App Auto-Patch
  • A2 Homebrew Status
  • A3 Electron Corner Mask
  • A4 Organizationally required application (Microsoft Teams unless the admin names another app)
  • A5 MDM agent app (concrete name per MDM; see above)
  • A6 BeyondTrust Privilege Management* [Jamf Pro only]
  • A7 Cisco Umbrella* [Jamf Pro only]
  • A8 CrowdStrike Falcon* [Jamf Pro only]
  • A9 Palo Alto GlobalProtect* [Jamf Pro only]
  • A10 Other external-checks/ script* (Microsoft Defender, Microsoft Office 365, Nessus, Sophos, Splunk Universal Forwarder, Zscaler, printer install, and others) [Jamf Pro only]

Follow-up Actions (F)

  • F1 Computer Inventory [Jamf Pro only; always last]

* = requires an external-check script deployed as a Jamf Pro policy with a custom trigger. On other MDMs, offer A4-style presence checks (checkInternal) or a new custom checkXxx function instead.

A4 defaults to Microsoft Teams (/Applications/Microsoft Teams.app). Do not ask about it up front; show it in 4a, and ask for the path and display name only when the admin names another app or asks to change it. For A10, ask for the Jamf Pro policy trigger and the app path used for the icon.

Reply grammar

One rule set applies to every selection reply, in Step 3 and in 4a:

  1. Tokens are case-insensitive and separated by commas or spaces. Duplicates are ignored.
  2. Base: the current selection. In Step 3 that is the MDM's shipped default; in 4a it is the list being confirmed.
  3. Operations:
  • A bare token adds to the base: H7 A4 → defaults + H7 + A4.
  • no <token> removes: no A3 on Intune → 33 − 1 = 32 checks.
  • only <tokens> replaces the base with exactly those tokens; later no tokens in the same reply still apply.
  • defaults resets the base to the shipped default: defaults, no M15.
  1. Tokens:
  • An ID (C5, A5c). A5 on Kandji means all six A5a–A5f.
  • A range (H1-H6) is inclusive and stays inside one category.
  • A category letter (C, H, M, A, F) means every available item in that category for the MDM.
  1. An unknown ID → ask. A "Not available" ID → warn with the reason, and include it only if the admin confirms.
  2. Order:
  • Default items keep the MDM's shipped order.
  • Available non-default additions go immediately before the first remaining M14, H6, or M15 (the tail every shipped default ends with), in master-table order (C, H, M, A). If none of those remain, append them.
  • F1 always comes last. If F1 is picked without M15, warn and ask: keep M15 directly before F1, or drop F1.

Step 4 — Generate the artifact

Read references/health-checks.md and references/artifact-procedure.md, then work through 4a–4f in order.

4a. Confirm the selection

Resolve the final ordered list with Reply grammar. Show this block and wait for yes:

<MDM display name> · <n> checks
Enabled: C1 C2 C3 … M14 H6 M15 (IDs only, in final order)
Changes vs shipped default: added H7 Clock Skew, A4 Microsoft Teams; removed A3 Electron Corner Mask (or "none — unchanged copy of the source")
A4 → Microsoft Teams (/Applications/Microsoft Teams.app) (only when A4 is enabled)
Artifact: Artifacts/Mac-Health-Check_<slug>_<YYYY-MM-DD-HHMMSS>.zsh plus a sidecar .md (timestamp set when written)
All other settings keep Mac-Health-Check.zsh defaults; edit the artifact manually to change them.
Reply yes to write it, or change it: H7 adds, no A3 removes, only … replaces.
  • Enabled checks appear as IDs only. Give full titles only for checks added or removed against the shipped default. The helper's sidecar lists every disabled check with its reason, so 4a does not.
  • Always show the <YYYY-MM-DD-HHMMSS> placeholder here. The helper takes the timestamp (local time, date +%Y-%m-%d-%H%M%S) when it writes the file.
  • A reply other than yes is parsed with Reply grammar against the list shown; show the updated block and wait again.

4b. Offer to remove other MDMs' code

After yes in 4a, send this question alone and wait:

Remove code for other MDMs from this artifact? Reply yes or no (default no).
yes removes the list-item arrays of <other MDMs>, their branches in every vendor case block (including serverURL detection), and vendor-only functions this selection doesn't call (<symbols>). The generic fallback stays, so a Mac enrolled in another MDM runs the MDM-agnostic checks.
  • Fill <other MDMs> with every named MDM except the chosen one, and <symbols> from Vendor-owned symbols in references/health-checks.md (Jamf Pro: checkMosyleCheckIn; Mosyle: the five Jamf Pro symbols; others: all six). A symbol the selection still calls (for example checkJamfProCheckIn when M5 is picked on Fleet) stays, and the helper prints INFO 4c … kept.
  • For Other / MDM-agnostic, say instead: "yes removes every named MDM's code; every Mac runs the generic checks, whatever its MDM."
  • defaults, no, or no clear answer means no: the artifact keeps every MDM's code, exactly as before.
  • Mention once: pruning suits fleets on a single MDM; a mixed fleet should keep the unpruned artifact.

4c. Build the selection

  • Run zsh Skills/mac-health-check-selector/scripts/build-artifact.zsh --list <slug> from the repository root. It prints index|raw title|call for the MDM's shipped rows. If it differs from the reference's shipped default, trust the script and tell the admin.
  • Pass the selection on stdin with --selection - and a here-doc, so no temporary file is left behind (see references/artifact-procedure.md). Use one line per check, in the 4a order:
  • <ID>|<raw title>, where the raw title is copied from --list output or the master table (for example M1|'${mdmVendor}' MDM Profile). The ID must match the master table; the helper exits 2 on a mismatch. The helper copies the row verbatim from the source, taking the chosen MDM's array first, then Jamf Pro, then the others. It pairs each row with the call at the same index, and prints INFO borrowed row: for each row taken from another MDM's array.
  • <ID>|custom|<row fragment>|<call> for A4 extra apps and A10. Use SF=NN.circle in the row, and take the call arguments from the master table. Never guess them.
  • The helper renumbers SF=NN.circle and runConfiguredHealthCheck "<index>" from zero. It keeps '"${organizationColorScheme}"' and '${mdmVendor}' exactly, fixes commas, and replaces the A9 subtitle with <YOUR_ORGANIZATION_NETWORK>. Outside Jamf Pro, it swaps the Jamf-worded H7 Clock Skew subtitle for the vendor-neutral Checks local clock offset against time.apple.com.
  • If the selection equals the shipped default, the artifact is an unchanged copy. Say so.
  • Leave developmentListitemJSON and the direct Development calls untouched.

4d. Write and validate the artifact

  • Run zsh Skills/mac-health-check-selector/scripts/build-artifact.zsh --slug <slug> --selection - with the here-doc from 4c, adding --prune-other-mdms when the admin replied yes in 4b. Validation checks 1–8 each print PASS, FAIL, SKIP, or INFO:
  1. zsh -n on the artifact.
  2. The edited array, with the shell splices substituted, passes jq.
  3. Alignment:
  • 3a: row count equals call count.
  • 3b: indices run 0 to n-1.
  • 3c: icons run 01 to n.
  • 3d: F1 is last or absent.
  • 3e: M15 is last, or directly before F1.
  1. diff hunks fall only inside the two regions. With --prune-other-mdms, every line outside the two regions and the pruned ranges is unchanged.
  • 4b (prune only): no pruned array, case branch, or detection pattern remains; the chosen MDM and the generic fallback are intact.
  • 4c (prune only): no removed vendor-only symbol is still referenced.
  1. Client-Side Cache replay (5a–5d), using the sanitizer extracted live from installClientSideScript: zsh -n, jq, no jamf recon text, and the Silent default (operationMode="${4:-"Silent"}"). A 5a, 5c, or 5d failure means the script's install gate would refuse the cached copy.
  2. scriptVersion is unchanged.
  3. The source is unchanged (SHA-256 before and after). git diff --quiet is reported as INFO.
  4. The artifact and sidecar paths are git-ignored.
  • Exit codes:
  • `0`: the artifact and its complete sidecar .md are in Artifacts/.
  • `1`: at least one check failed. Nothing was written to Artifacts/, and the failed build stays in the printed work directory. Fix the selection (usually the order), then rerun; the rerun gets a new timestamp.
  • `2`: the selection file or the anchors are invalid. Fix it and rerun.
  • Other helper options: --source <path> reads another copy of the script (owned by you or root, not world-writable); --out-dir <dir> writes somewhere other than Artifacts/ next to the source, and must be git-ignored or check 8 fails; -h / --help prints usage. See references/artifact-procedure.md.
  • If you cannot run the helper: follow the manual procedure in references/artifact-procedure.md. Each manual check prints PASS/FAIL, and the block exits non-zero on any failure. The manual procedure never prunes: if the admin replied yes in 4b, build unpruned and tell them.
  • If you cannot write files: print the intended filename, the full artifact in one fenced zsh block, and the sidecar in a fenced markdown block. Tell the admin to save both under Artifacts/ and run the helper, or the manual checks, on the saved file.

4e. Review the sidecar

On exit 0, the helper has already written Artifacts/<same basename>.md. It contains the header (including whether other MDM code was removed), Enabled (index, ID, resolved title, report key), Disabled (every unselected check with its reason), report keys removed and added, Pruned MDM code (prune only), tagged dependency notes, the validation table, the diff summary, and next steps. Titles are resolved (Microsoft Intune MDM Profile, not '${mdmVendor}' MDM Profile), and MDMs use display names.

Read it, and append only organization-specific notes the admin gave (for example a custom A4 app or a planned vpnClientVendor change). When the helper cannot run, write the sidecar by hand from the template in the procedure file.

4f. Report

Reply with the artifact path, the sidecar path, a one-line PASS/FAIL for each check, and the dependency notes that apply. The helper already picked them for the sidecar; repeat the non-[all] ones and any report-key or borrowed-row note. Each note's tag says when it applies:

TagApplies whenNote
[all]AlwaysswiftDialog 3.1.1.4997 or newer (swiftDialogMinimumRequiredVersion); pre-flight installs or updates it.
[all]Alwaysjq validates every array; an invalid array exits before any check runs.
[all]AlwaysClient-Side Cache / LaunchDaemon: the cached copy runs nightly in Silent, drops updateComputerInventory, and never sends webhook messages; H3–H5 fall back to the loginwindow lastUserName.
[all]AlwaysSilent + splunkOperationMode=production is reporting-first; use <YOUR_SPLUNK_HEC_URL> and <YOUR_SPLUNK_HEC_TOKEN>.
[all]AlwaysSecrets: webhookURL and splunkHECToken go in root-only MacHealthCheck-Secrets.plist; Parameters 5 and 8 are rejected unless allowParameterSecrets="true".
[all]Not prunedRuntime MDM detection: the edits run only on Macs the script detects as the chosen MDM; others run their own unedited branch.
[prune]PrunedOnly the chosen MDM and the generic fallback remain; Macs enrolled in any other MDM run the generic branch (no MDM Profile or MDM Certificate Expiration). Rebuild unpruned for mixed fleets.
[all]Keys changeReport keys removed or added through sanitizeCheckKey (for example electron_corner_mask); Splunk dashboards and targeted-recheck continuity lose or gain them. M1 and M3 keys include the vendor (microsoft_intune_mdm_profile).
[all]Borrowed rowsRows copied from another MDM's array; review their subtitles.
[C8]C8 enabledTouch ID reports an error on Macs without Touch ID hardware (VMs, desktops without a Touch ID keyboard).
[C13]C13 enabledVPN Client follows vpnClientVendor (shipped paloalto) and vpnClientDataType; it fails when that client is absent.
[H6]H6 enabledMemory Pressure needs samples from two distinct days; early runs show Insufficient data.
[H7]H7 enabledClock Skew queries time.apple.com with sntp (UDP 123); blocked NTP reports Unable to determine (warning), and skew over 300 seconds fails.
[M2]M2 enabledEntra ID Registration passes as Not Applicable when no Entra artifacts exist; without the JamfAAD plist (the norm outside Jamf Pro), an MS-ORGANIZATION-ACCESS certificate reports Partial (warning).
[vendor]M1 enabledMDM Profile needs mdmVendorUuid or mdmProfileIdentifier.
[Addigy]Addigy + M1mdmVendorUuid ships blank; fill it in.
[Kandji]KandjiDetection needs serverURL to contain kandji.
[generic]OtherNo MDM Profile or MDM Certificate Expiration; M4 warns (APNs active; no MDM response) or fails on unenrolled Macs.
[Jamf]Jamf ProScript exits early without /private/var/log/jamf.log.
[Jamf]External checksEach checkExternalJamfPro call needs its external-checks/ script in Jamf Pro and a policy with the matching custom trigger. Results resolve in order: a policy still running after externalCheckTimeoutSeconds (shipped 120 seconds) reports Timed Out; then checkType / checkStatus / checkExtended in organizationDefaultsDomain, when the script writes them (Microsoft Defender, TenableNessusAgent-Alternate); then keywords in the script result: Failed or Not Running (fail), Running (pass), Warning. Error, Not Installed, or unmatched output shows Error. Timed Out, Warning, and Error are recorded as warning in the JSON report. See external-checks/README.md.
[Jamf]F1 enabledjamf recon with a 90-second timeout; skipped in Silent + production; removed from the cached copy.
[A9]A9 rebuiltSubtitle now <YOUR_ORGANIZATION_NETWORK>; replace it before deploying.
[A4]A4 enabledShows the checkInternal path and name; edit them if the required app differs.

Step 5 — Next steps

Close with these steps, then offer to adjust the selection or build another artifact for a different MDM. Each artifact starts from the untouched source.

  1. Review the sidecar and the diff summary.
  2. Test on one Mac enrolled in the chosen MDM (for Other / MDM-agnostic, a Mac whose serverURL matches no known MDM; an unenrolled Mac qualifies, and M4 then warns (APNs active; no MDM response) or fails as expected):
  • Run sudo zsh --no-rcs ./Artifacts/<file>.zsh "" "" "" "Self Service", then repeat with Silent, Debug, Development, and Test as Parameter 4.
  • Development runs the shipped developmentListitemJSON subset, not the selection.
  • Confirm that the dropped checks do not appear in the log and that the row count matches.
  • The Client-Side Cache install runs only in Self Service, Debug, and Silent with splunkOperationMode=production (never Test or Development), and only from a root-owned script path. Run from a user-owned checkout such as ./Artifacts/, it logs install skipped and leaves the Mac's cached copy alone. Run from a root-owned path, it replaces the Mac's Client-Side Cache copy and LaunchDaemon with the artifact; re-run the production policy afterwards to restore them.
  • Pruned artifact: optionally run it once on a Mac not enrolled in the chosen MDM (an unenrolled Mac qualifies) to confirm the generic fallback.
  1. Deploy the artifact as the MDM script. Keep scriptVersion unchanged, and keep Debug and Development out of the production policy.
  2. Expect the first Self Service run after deployment to be a full run (check_set_mismatch). Targeted rechecks resume after that.
  3. Keep Artifacts/ out of version control. It is git-ignored because artifacts may carry org-specific edits.
  4. Record the change in your internal release notes.

Validation checklist (run before replying)

  • The first message asked only the MDM question.
  • The reply was parsed with Reply grammar, and the admin confirmed the selection in 4a before anything was written.
  • The Step 4b prune question was asked on its own after 4a; --prune-other-mdms was passed only on yes, and the sidecar header records the choice.
  • Mac-Health-Check.zsh is unchanged, and the only new files are under Artifacts/.
  • The artifact name matches Mac-Health-Check_<slug>_<YYYY-MM-DD-HHMMSS>.zsh, and the sidecar shares its basename.
  • Validation checks 1–8 printed PASS (or SKIP for 8 outside git), plus 4b and 4c when pruned, and the helper wrote the sidecar. No failed build remains in Artifacts/, and no selection file was left behind.
  • M15 is the last row or directly before F1, and F1 is last.
  • No "Not available" check appears for the MDM unless the admin explicitly asked for it and was warned.
  • No real organization names, URLs, tokens, or paths beyond the shipped defaults.

Resources

  • Project: https://github.com/dan-snelson/Mac-Health-Check
  • Releases (5.0.0 and later): https://github.com/dan-snelson/Mac-Health-Check/releases
  • README.md, CHANGELOG.md, external-checks/README.md, Artifacts/README.md, and AGENTS.md in the repository
  • references/health-checks.md, references/artifact-procedure.md, and scripts/build-artifact.zsh in this skill

Example conversation

Admin: Help me pick which MHC checks to run.

Assistant: Which MDM manages these Macs? Reply with a number or type your own.

  1. Jamf Pro · 2. Fleet · 3. JumpCloud · 4. Microsoft Intune · 5. Mosyle · 6. Kandji / Iru · 7. Addigy · 8. Filewave · 9. Other / MDM-agnostic / custom

Admin: 4

Assistant: Microsoft Intune it is. Each row in the swiftDialog window comes from microsoftMdmListitemJSON, and each row's check runs from a matching runConfiguredHealthCheck line in the "Microsoft Intune" case branch. I'll write an edited copy to Artifacts/ and leave your script untouched. Unmarked checks are on by default (33 for Intune); [off] checks are available but off. (checklist from Step 3, with `A5 Microsoft Company Portal`, `[off]` on H7, M2, and A4, and "Not available for Microsoft Intune: M5, M6, M13, A6–A10, F1 (Jamf Pro only); M7 (Mosyle only)")

Admin: no A3

Assistant: Microsoft Intune · 32 checks Enabled: C1 C2 A1 C3 C4 C5 C6 C7 C8 C13 H1 H2 H3 H4 H5 C9 C10 C11 C12 M1 M3 M4 M8 M9 M10 M11 M12 A5 A2 M14 H6 M15 Changes vs shipped default: removed A3 Electron Corner Mask. Artifact: Artifacts/Mac-Health-Check_microsoft-intune_<YYYY-MM-DD-HHMMSS>.zsh plus a sidecar .md (timestamp set when written). All other settings keep Mac-Health-Check.zsh defaults; edit the artifact manually to change them. Reply yes to write it, or change it: H7 adds, no A3 removes, only … replaces.

Admin: yes

Assistant: Remove code for other MDMs from this artifact? Reply yes or no (default no). yes removes the list-item arrays of Jamf Pro, Fleet, JumpCloud, Mosyle, Kandji / Iru, Addigy, and Filewave, their branches in every vendor case block (including serverURL detection), and vendor-only functions this selection doesn't call (checkJamfProCheckIn, checkJamfProInventory, checkExternalJamfPro, updateComputerInventory, jamfHosts, checkMosyleCheckIn). The generic fallback stays, so a Mac enrolled in another MDM runs the MDM-agnostic checks. Pruning suits a fleet on a single MDM; keep the unpruned artifact for a mixed fleet.

Admin: yes

Assistant: Wrote Artifacts/Mac-Health-Check_microsoft-intune_2026-09-28-105327.zsh and its sidecar Artifacts/Mac-Health-Check_microsoft-intune_2026-09-28-105327.md (written by the helper).

#CheckResult
1zsh -nPASS
2jq on microsoftMdmListitemJSONPASS
332 rows = 32 calls, indices 0–31, icons 01–32, F1 absent, M15 lastPASS
4Every line outside the array, the "Microsoft Intune" ) branch, and the pruned ranges unchangedPASS
4b7 arrays, 30 branches, 4 emptied blocks removed; generic fallback intactPASS
4c6 vendor-only symbols removed, none still referencedPASS
5Client-Side Cache simulation (zsh -n, jq, no jamf recon, Silent default)PASS
6scriptVersion 5.0.0 unchangedPASS
7Source unchangedPASS
8Artifact and sidecar git-ignoredPASS

Notes: [all] report key electron_corner_mask disappears from reports and dashboards; [prune] only Intune and the generic fallback remain, so test on an Intune-enrolled Mac (a Jamf Pro-enrolled Mac now runs the generic checks); [C8] Touch ID errors on Macs without Touch ID hardware; [C13] set vpnClientVendor for your VPN client; the first Self Service run after deployment is a full run because the check set changed. (Step 5 next steps follow, then: "Build another artifact for a different MDM?")

All versions