Another major upgrade to Mac Admins’ go-to solution for “set-it-and-forget-it” end-user messaging of Apple’s Declarative Device Management-enforced macOS update deadlines features a new, robust heartbeat daemon architecture, easily configurable daily reminder times, pre-deadline threshold alerts, and aggressive past-deadline mode with persistent compliance prompting
Overview
While Apple’s Declarative Device Management (DDM) provides Mac Admins with a powerful way to enforce macOS updates, its built-in notification is often too subtle for most administrators:
DDM OS Reminder intelligently resolves DDM-enforced macOS update deadlines from recent /var/log/install.log activity, while using a declaration-aware resolver which prioritizes applicable enforced-install signals. End-user reminders are suppressed when declaration state is missing, conflicting, or invalid, only honoring setPastDuePaddedEnforcementDate when it safely matches the resolved declaration. Failed stale SoftwareUpdateSubscriber attempts are ignored, and enforcement timestamps with full timezone offsets such as +05:30 are accepted before using a swiftDialog-enabled script and LaunchDaemon to deliver a more prominent end-user reminder dialog.
🆕 4.0.0 Highlights
Heartbeat daemon architecture: /Library/LaunchDaemons/<rdnn>.dor.plist now runs lightweight dor-starter.zsh every 60 seconds. The starter checks /Library/Management/<rdnn>/dor-state.plist and only launches dor.zsh when a reminder is due.
Runtime scheduler state: NextScheduledReminder, DaemonLastTriggered, delivered pre-deadline thresholds, and the active dor.pid live in /Library/Management/<rdnn>/. Managed and local preferences remain admin-controlled configuration only.
Remote session monitoring: Resources/monitorRemoteSession.zsh provides one remote-Terminal snapshot of the heartbeat LaunchDaemon, deployed runtime files, dor-state.plist, dor.pid, matching processes, aggressive-mode kill switch, and recent project log entries. Use --rdnn <value> for your organization’s deployments, --watch <seconds> for live refresh, and --log-lines <n> to adjust log tail depth.
Baseline reminder schedule: DailyReminderTimes controls local reminder slots in HH:MM CSV format. The default baseline is 08:00,12:00,16:00.
Final-minute threshold reminders: MinutesBeforeDeadlineReminderSchedule controls discrete pre-deadline reminders, defaulting to 45,30,15,10,5. These threshold reminders bypass quiet-period suppression and can refresh an already-open daemon-managed dialog when a later threshold becomes due.
Aggressive past-deadline mode: Easily control urgent redisplay cadence after the effective deadline:
AggressiveModePastDeadlineHours and AggressiveModeFrequencyMinutes
Exact redisplay scheduling continues after Open Software Update until compliance or support suppression with /Library/Management/<rdnn>/dor-aggressive-kill
Features
Customizable: Easily customize the reminder dialog’s title, message, icons and button text to fit your organization’s requirements by distributing a Configuration Profile via any MDM solution.
Easy Installation: The assemble.zsh script makes it easy to deploy your reminder dialog and display frequency customizations via any MDM solution, enabling quick rollout of DDM OS Reminder organization-wide.
Set-it-and-forget-it: Once configured and installed, a LaunchDaemon displays your customized reminder dialog — automatically checking the installed macOS version against the DDM-required version — to remind users if an update is required.
Deadline Awareness: Whenever a DDM-enforced macOS version or its deadline is updated via your MDM solution, the reminder dialog dynamically updates the countdown to both the deadline and required macOS version to drive timely compliance.
Intelligently Intrusive: The reminder dialog is designed to be informative without being disruptive. Before displaying, it checks for active display-sleep assertions from an allowlist of approved meeting apps, helping users stay productive while still being reminded to update.
Logging: The script logs its actions to your specified log file, allowing Mac Admins to monitor its activity and troubleshoot as necessary.
Demonstration Mode: A built-in demo mode allows Mac Admins to test the appearance and functionality of the reminder dialog with ease.
Configurable Post-Deadline Restart Policy: Choose whether past-deadline devices are left alone, prompted to restart, or forced to restart (Off, Prompt, Force) after your defined grace period, balancing user flexibility with reliable compliance.
Upgrade-friendly: assemble.zsh can now import supported settings from a previously generated DDM OS Reminder .plist, infer the RDNN and deployment lane (dev, test, prod), and generate a matched assembled script, organizational .plist, and unsigned .mobileconfig in a single pass. (See 3. Upgrading.)
Full Multi-language Experience: Beginning with version 3.1.0, English dialog defaults are provided in-script, with .plist support for: German, French, Spanish, Italian, Dutch, Portuguese, and Japanese. Additional languages through localized *Localized_<code> preference keys, with locale-aware dialog content, support messaging, human-readable deadline dates, and past-deadline restart copy that match the resolved language.
Granular Control for Displaying IT Support Information: New HideSupport* preferences allow Mac Admins to easily choose which IT Support fields are displayed to their end-users.
UsereminderDialogPreferenceTest.zsh when you want to easily validate dialog copy, localization, branding, support contact details, button visibility, and infobox rendering from deployed preferences without waiting for an actual DDM deadline.
Lean Artifact Options: Keep the full localization surface, generate a minimal artifact (--minimal = base keys + exact _Localized_en keys only), or retain only selected language families with --languages <csv>. In assemble.zsh --interactive, same choice appears as Full, Minimal, or Selected languages.
Implementation
1. Local Testing
Jumpstart your DDM OS Reminder implementation by first conducting a local test on a non-production Mac which has swiftDialog installed.
Ideally, use a non-production Mac which is already in-scope of a pending Declarative Device Management-enforced macOS update from your MDM server.
Re-executezsh reminderDialog.zsh demo and confirm you now observe the word “Sample” in various places in the reminder dialog, as configured in sample.plist:
2. MDM Deployment
The included assemble.zsh script makes MDM deployment easy by generating organization-specific deployment artifacts
Generate customized deployment artifacts for your organization by using the assemble.zshscript, specifying your organization’s Reverse Domain Name Notation (i.e., us.snelson) with --interactive mode:
zsh assemble.zsh us.snelson --interactive
root@XDT8675309 DDM-OS-Reminder-main # zsh assemble.zsh us.snelson --interactive
===============================================================
🧩 Assemble DDM OS Reminder (4.0.0)
===============================================================
📍 Full Paths:
Reminder Dialog: /Users/dan/Downloads/DDM-OS-Reminder-main/reminderDialog.zsh
LaunchDaemon Management: /Users/dan/Downloads/DDM-OS-Reminder-main/launchDaemonManagement.zsh
Working Directory: /Users/dan/Downloads/DDM-OS-Reminder-main
Resources Directory: /Users/dan/Downloads/DDM-OS-Reminder-main/Resources
🔍 Checking Reverse Domain Name Notation …
Reminder Dialog (reminderDialog.zsh):
reverseDomainNameNotation = org.churchofjesuschrist
organizationScriptName = dorm
LaunchDaemon Management (launchDaemonManagement.zsh):
reverseDomainNameNotation = org.churchofjesuschrist
organizationScriptName = dor
📥 RDNN provided via command-line argument: 'us.snelson'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🛠️ Interactive Configuration
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Drag-and-drop an earlier DOR .plist to import [Return to skip] (or ‘X’ to exit):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🏷️ Using 'us.snelson' as the Reverse Domain Name Notation
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎛️ IT Support, Branding, Restart & Aggressive Mode Policy (Interactive)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Support Team Name [IT Support] (or ‘X’ to exit): Support
Support Team Phone [+1 (801) 555-1212] (or ‘X’ to exit): +1 (937) 555-1212
Hide Support Team Phone (YES/NO) [NO] (or ‘X’ to exit):
Support Team Email [rescue@snelson.us] (or ‘X’ to exit):
Hide Support Team Email (YES/NO) [NO] (or ‘X’ to exit):
Support Team Website [https://support.snelson.us] (or ‘X’ to exit):
Hide Support Team Website (YES/NO) [NO] (or ‘X’ to exit):
Info Button ('YES' to specify; 'NO' to hide) [YES] (or ‘X’ to exit):
Info Button Text [Update macOS on Mac] (or ‘X’ to exit):
Info Button Action [https://support.snelson.us] (or ‘X’ to exit):
Knowledge Base Row ('YES' to specify; 'NO' to hide) [YES] (or ‘X’ to exit):
Support KB Title [Update macOS on Mac] (or ‘X’ to exit): KB8675309
Support KB Markdown Link [[KB8675309](https://support.snelson.us)] (or ‘X’ to exit):
Hide Support Assistance Message (YES/NO) [NO] (or ‘X’ to exit):
Overlay Icon URL (Light) [https://use2.ics.services.jamfcloud.com/icon/hash_2d64ce7f0042ad68234a2515211adb067ad6714703dd8ebd6f33c1ab30354b1d] (or ‘X’ to exit):
Overlay Icon URL (Dark) [https://use2.ics.services.jamfcloud.com/icon/hash_d3a3bc5e06d2db5f9697f9b4fa095bfecb2dc0d22c71aadea525eb38ff981d39] (or ‘X’ to exit):
Swap Overlay and Logo (YES/NO) [NO] (or ‘X’ to exit):
Past-deadline Restart Behavior (Off / [P]rompt / [F]orce) [Off] (or ‘X’ to exit): P
Days Past Deadline Before Restart Workflow (0-999) [2] (or ‘X’ to exit):
Aggressive Mode Past Deadline Hours (0-999; use 720 to effectively suppress) [2] (or ‘X’ to exit):
Aggressive Mode Frequency Minutes (1-999) [20] (or ‘X’ to exit): 17
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🌐 Localization Artifact Mode
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Localization Output (Full / [M]inimal / [S]elected languages) [Full] (or ‘X’ to exit): M
ℹ️ Localization mode set to: minimal localization surface (base keys + English localized keys)
🌐 Artifact Localization: minimal localization surface (base keys + English localized keys)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🚦 Select Deployment Mode:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1) 🧪 Development - Keep placeholder text for local testing
2) 🔬 Testing - Replace placeholder text with 'TEST' for staging
3) 🚀 Production - Remove placeholder text for clean deployment
[Press ‘X’ to exit ❎]
Enter mode [1/2/3]: 3
📦 Deployment Mode: prod
🔧 Inserting reminderDialog.zsh into launchDaemonManagement.zsh …
✅ Assembly complete [2026-07-09-073557]
→ Artifacts/ddm-os-reminder-assembled-2026-07-09-073557.zsh
🔁 Updating reverseDomainNameNotation to 'us.snelson' in assembled script …
🔍 Performing syntax check on 'Artifacts/ddm-os-reminder-assembled-2026-07-09-073557.zsh' …
✅ Syntax check passed.
🗂 Generating LaunchDaemon plist …
🗂 Creating us.snelson.dorm plist from /Users/dan/Downloads/DDM-OS-Reminder-main/Resources/sample.plist …
🔧 Updating internal plist content …
🔓 Production mode: removing placeholder text for clean deployment
🔧 Applying IT support, branding, restart and aggressive mode values …
🌐 Removed 249 localized key(s) from generated plist
→ Artifacts/us.snelson.dorm-2026-07-09-073557-prod.plist
🧩 Generating Configuration Profile (.mobileconfig) …
→ Artifacts/us.snelson.dorm-2026-07-09-073557-prod-unsigned.mobileconfig
🔍 Performing syntax check on 'Artifacts/us.snelson.dorm-2026-07-09-073557-prod-unsigned.mobileconfig' …
✅ Profile syntax check passed.
🔁 Renaming assembled script …
🔁 Updating scriptLog path based on RDNN …
🏁 Done.
📦 Deployment Artifacts:
Assembled Script: Artifacts/ddm-os-reminder-us.snelson-2026-07-09-073557-prod.zsh
Organizational Plist: Artifacts/us.snelson.dorm-2026-07-09-073557-prod.plist
Configuration Profile: Artifacts/us.snelson.dorm-2026-07-09-073557-prod-unsigned.mobileconfig
Deployed Runtime Assets: /Library/Management/<RDNN>/dor-starter.zsh, dor-state.plist, dor.pid
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠️ Important Next Steps:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Production Artifacts Generated:
- All placeholder text removed (clean output)
- Localization artifact mode: minimal localization surface (base keys + English localized keys)
- IT support, branding, restart and aggressive mode values applied from prompts
- Past-deadline restart policy set to 'Prompt'
- Aggressive mode begins 2 hour(s) past deadline and repeats every 17 minute(s)
- Restart workflow begins 2 day(s) past deadline
Recommended review items:
- Support team name, phone, email, website
- DailyReminderTimes baseline schedule
- AggressiveModePastDeadlineHours and AggressiveModeFrequencyMinutes
- Localization key set matches intended artifact mode
- Support KB title/link and Info button URL
- Organization overlay icon URLs
- Button labels and dialog messages
Files to review:
- Artifacts/us.snelson.dorm-2026-07-09-073557-prod.plist
- Artifacts/us.snelson.dorm-2026-07-09-073557-prod-unsigned.mobileconfig
===============================================================
Carefullyreview deployment artifacts and distribute the appropriate files to a single test Mac via your MDM:
Either the .mobileconfigor the .plist (as a Configuration Profile)
The assembled .zsh script (install only once)
After the assembled script and configuration profile have installed on the test Mac, use Resources/monitorRemoteSession.zsh during a remote Terminal session when you need one view of the 4.0.0 heartbeat daemon, deployed runtime files, dor-state.plist, dor.pid, matching processes, aggressive-mode kill switch, and recent log entries. Use --watch 5 while testing or immediately after a kickstart:
In a second, elevated Terminal window, kickstart the DDM OS Reminder heartbeat LaunchDaemon when you want to force an immediate starter evaluation. In version 4.0.0, kickstart may exit quietly if NextScheduledReminder is FALSE or future-dated; check monitorRemoteSession.zsh before treating a missing dialog as a failure:
rdnn="us.snelson"
launchctl kickstart -kp system/"${rdnn}".dor
UseResources/reminderDialogPreferenceTest.zshwhen you want to validate dialog copy, localization, branding, support contact details, button visibility, and infobox rendering from deployed preferences. Use monitorRemoteSession.zsh for runtime heartbeat, scheduler, PID, process, kill-switch, and log troubleshooting:
Version 3.0.0 (and later) of assemble.zsh can import supported settings from a previously generated DDM OS Reminder .plist, infer the RDNN and deployment lane (dev, test, prod), and generate a matched assembled script, organizational .plist, and unsigned .mobileconfig in a single pass.
zsh assemble.zsh drag-and-drop-prior.plist
root@XDT8675309 DDM-OS-Reminder-main # zsh assemble.zsh /Users/dan/Downloads/DDM-OS-Reminder-2.2.0/Artifacts/org.churchofjesuschrist.dorm-2026-01-06-073608.plist
===============================================================
🧩 Assemble DDM OS Reminder (4.0.0)
===============================================================
📍 Full Paths:
Reminder Dialog: /Users/dan/Downloads/DDM-OS-Reminder-main/reminderDialog.zsh
LaunchDaemon Management: /Users/dan/Downloads/DDM-OS-Reminder-main/launchDaemonManagement.zsh
Working Directory: /Users/dan/Downloads/DDM-OS-Reminder-main
Resources Directory: /Users/dan/Downloads/DDM-OS-Reminder-main/Resources
🔍 Checking Reverse Domain Name Notation …
Reminder Dialog (reminderDialog.zsh):
reverseDomainNameNotation = org.churchofjesuschrist
organizationScriptName = dorm
LaunchDaemon Management (launchDaemonManagement.zsh):
reverseDomainNameNotation = org.churchofjesuschrist
organizationScriptName = dor
📥 Prior plist provided via command-line argument: '/Users/dan/Downloads/DDM-OS-Reminder-2.2.0/Artifacts/org.churchofjesuschrist.dorm-2026-01-06-073608.plist'
ℹ️ Importing supported values from: /Users/dan/Downloads/DDM-OS-Reminder-2.2.0/Artifacts/org.churchofjesuschrist.dorm-2026-01-06-073608.plist
🔎 Inferred RDNN from prior plist: 'org.churchofjesuschrist'
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🏷️ Using 'org.churchofjesuschrist' as the Reverse Domain Name Notation
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ️ Prior plist supplied; skipping IT support, branding and restart policy prompts.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🛠️ Interactive Configuration
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🌐 Localization Artifact Mode
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Localization Output (Full / [M]inimal / [S]elected languages) [Full] (or ‘X’ to exit): m
ℹ️ Localization mode set to: minimal localization surface (base keys + English localized keys)
🌐 Artifact Localization: minimal localization surface (base keys + English localized keys)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🚦 Select Deployment Mode:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1) 🧪 Development - Keep placeholder text for local testing
2) 🔬 Testing - Replace placeholder text with 'TEST' for staging
3) 🚀 Production - Remove placeholder text for clean deployment
[Press ‘X’ to exit ❎]
Enter mode [1/2/3]: 3
📦 Deployment Mode: prod
🔧 Inserting reminderDialog.zsh into launchDaemonManagement.zsh …
✅ Assembly complete [2026-07-09-083149]
→ Artifacts/ddm-os-reminder-assembled-2026-07-09-083149.zsh
🔁 Updating reverseDomainNameNotation to 'org.churchofjesuschrist' in assembled script …
🔍 Performing syntax check on 'Artifacts/ddm-os-reminder-assembled-2026-07-09-083149.zsh' …
✅ Syntax check passed.
🗂 Generating LaunchDaemon plist …
🗂 Creating org.churchofjesuschrist.dorm plist from /Users/dan/Downloads/DDM-OS-Reminder-main/Resources/sample.plist …
🔧 Updating internal plist content …
🔓 Production mode: removing placeholder text for clean deployment
🔧 Importing supported values from prior plist …
ℹ️ Preserving imported ScriptLog: /var/log/org.churchofjesuschrist.log
🌐 Removed 249 localized key(s) from generated plist
→ Artifacts/org.churchofjesuschrist.dorm-2026-07-09-083149-prod.plist
🧩 Generating Configuration Profile (.mobileconfig) …
→ Artifacts/org.churchofjesuschrist.dorm-2026-07-09-083149-prod-unsigned.mobileconfig
🔍 Performing syntax check on 'Artifacts/org.churchofjesuschrist.dorm-2026-07-09-083149-prod-unsigned.mobileconfig' …
✅ Profile syntax check passed.
🔁 Renaming assembled script …
🔁 Updating scriptLog path based on RDNN …
🏁 Done.
📦 Deployment Artifacts:
Assembled Script: Artifacts/ddm-os-reminder-org.churchofjesuschrist-2026-07-09-083149-prod.zsh
Organizational Plist: Artifacts/org.churchofjesuschrist.dorm-2026-07-09-083149-prod.plist
Configuration Profile: Artifacts/org.churchofjesuschrist.dorm-2026-07-09-083149-prod-unsigned.mobileconfig
Deployed Runtime Assets: /Library/Management/<RDNN>/dor-starter.zsh, dor-state.plist, dor.pid
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠️ Important Next Steps:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Production Artifacts Generated:
- All placeholder text removed (clean output)
- Localization artifact mode: minimal localization surface (base keys + English localized keys)
- Supported configuration values imported from prior plist
- Prior plist: /Users/dan/Downloads/DDM-OS-Reminder-2.2.0/Artifacts/org.churchofjesuschrist.dorm-2026-01-06-073608.plist
- ScriptLog resolved to '/var/log/org.churchofjesuschrist.log'
Recommended review items:
- Support team name, phone, email, website
- DailyReminderTimes baseline schedule
- AggressiveModePastDeadlineHours and AggressiveModeFrequencyMinutes
- Localization key set matches intended artifact mode
- Imported ScriptLog path and any carried-forward KB/help visibility
- Organization overlay icon URLs
- Button labels and dialog messages
Files to review:
- Artifacts/org.churchofjesuschrist.dorm-2026-07-09-083149-prod.plist
- Artifacts/org.churchofjesuschrist.dorm-2026-07-09-083149-prod-unsigned.mobileconfig
===============================================================
As always, carefullyreview each deployment artifact and distribute the appropriate files to a single test Mac via your MDM. (See Steps 2.2 through 2.4.)
2.1.0 (and earlier)
Author’s Highly Opinionated Thought: There are enough changes since version 2.1.0 (and earlier) that it’s best to just start-from-scratch — first uninstalling earlier versions — rather than attempting to upgrade to the latest version.
4. Resources
4.1 AI-generated Documentation
AI-generated documentation is available in the GitHub repository
Diagrams: Comprehensive, AI-generated visual diagrams to augment this documentation
Executive Overview: High-level lifecycle view for Mac Admins who need the big picture first
System Architecture: Complete ecosystem overview from development through runtime execution
The following have proved helpful during development and testing
XTRACE
Execute the client-side reminder dialog script — under xtrace with a custom prompt — using the following as an example, substituting your organization’s Reverse Domain Name Notation:
Note: Once the reminder dialog appears, the last several output blocks tend to be the most informative
The following commands can be used to manually execute the deployed reminder runtime and force-display the reminder dialog on Macs with a pending update and valid DDM enforcement state.
### # Force-display Reminder Dialog # # Note: Works only on Macs with pending updates # AND a valid DDM enforcement state ###
rdnn="org.churchofjesuschrist"
rm -v "/var/log/${rdnn}.log"
zsh "/Library/Management/${rdnn}/dor.zsh" demo
Note: The above bypasses the so-called “heartbeat” scheduler; use monitorRemoteSession.zsh when validating dor-starter.zsh, dor-state.plist, NextScheduledReminder, or LaunchDaemon behavior.
Conduct the following troubleshooting steps in an elevated Terminal session, on a test Mac in-scope of a pending Declarative Device Management-enforced macOS update from your MDM server.
System Settings > General > Device Management > MDM Profile > Device Declarations
1. Core Functionality
Define a rdnn variable to aid in completing the following steps:
rdnn="org.churchofjesuschrist"
Start monitorRemoteSession.zsh for one live view of the heartbeat LaunchDaemon, runtime files, scheduler state, PID, matching processes, aggressive-mode kill switch, and recent logs:
ls -l /Library/Management/"${rdnn}"/dor.zsh ls -l /Library/Management/"${rdnn}"/dor-starter.zsh ls -l /Library/Management/"${rdnn}"/dor-state.plist ls -l /Library/Management/"${rdnn}"/dor.pid
Review the client-side managed preferences .plist for any obvious issues:
Review the /var/log/install.log for relevant DDM and Software Update entries:
Space : next page
Arrow keys : scroll horizontally or vertically
q : quit
tail -n 1000 /var/log/install.log | grep -nE 'declarationFromKeys\]: Falling back to default applicable declaration|Found DDM enforced install \(|EnforcedInstallDate:|requestedPMV=|MADownloadNoMatchFound|pallasNoPMVMatchFound=true|No available updates found\. Please try again later\.|setPastDuePaddedEnforcementDate|Removed [0-9]+ invalid declarations' | less -S
To more easily validate the DDM declaration parsing logic, run the following Jamf Pro Extension Attribute scripts locally and confirm the reported date and version match the pending DDM-enforced macOS update from your MDM server:
When troubleshooting user-interface issues, leverage the dialog binary and your client-side managed preferences .plist values.
2. User-interface Issues
Confirm dialog is installed and working as expected:
dialog --title "Dialog Test" --message "swiftDialog is installed and can render a basic dialog." --icon /System/Library/CoreServices/Finder.app --infotext
Define a rdnn variable to aid in completing the following steps:
Community-supplied, best-effort support is available on the Mac Admins Slack (free, registration required) #ddm-os-reminders channel, or you can open an issue.