20-Oct-2026
- New low-battery warning: when a Mac is running on its internal battery below
MinimumBatteryPercentage, the reminder dialog asks the user to connect power and leave it plugged in until the macOS update completes (Issue #157; thanks, ebbg!)- New
MinimumBatteryPercentagepreference: integer0–100, default50;0disables. Invalid values log[WARNING]and fall back to50. - New
BatteryWarningMessagestring (localized foren,de,fr,es,pt,ja,nl, andit) with a{batteryPercentage}placeholder, inserted through the new{batteryWarningMessage}placeholder inMessage,AggressiveModeMessage,PreDeadlineThresholdMessage,PastDeadlinePromptMessage, andPastDeadlineForceMessage. Restart mode keeps the battery warning, because a restart does not charge the battery. - Shown only when
pmset -g psreportsBattery Powerand an internal-battery charge below the threshold; never on AC or UPS power, on Macs without an internal battery, or when the charge can't be read. - Each run logs one
[NOTICE] Battery: …line with power source, charge, threshold, and whether the warning was shown. - Messaging only:
PastDeadlineRestartBehaviorPrompt/Forcebehavior is unchanged. Resources/reminderDialogPreferenceTest.zshadds--battery-percentage <0-100>to preview the warning on a desktop or AC-powered Mac.assemble.zshlists any imported message template missing{batteryWarningMessage}under Recommended review items; it never rewrites your copy.- Non-English battery strings are new and would benefit from native-speaker review.
- New
- Client-side log entries now speak to Mac Admins: every run that shows no reminder ends with what happened, why, and what to do next (Issue #154)
Normal DDM resolver result: …is nowDDM update check: <plain-language outcome> (status=…; source=…; reason=…); thestatus=,source=, andreason=tokens are unchanged.Resolver suppression summary: …is replaced byNo reminder shown: …andNext step: …at the end of the run.missingand up-to-date outcomes log at[NOTICE];conflict,noMatch,invalidVersion, and unrecognized states stay[WARNING].- Each unresolved state names its own next step (for example, scope to one declaration, correct the target version, or configure a DDM Emergency Fallback).
conflictnow says which kind of conflict occurred; when installed macOS already meets the declared version, it logs at[NOTICE]withNext step: None. - Up-to-date Macs log
No reminder shown: macOS <installed> already meets DDM-enforced macOS <version>. - Display-window, periodic, Update Tonight, quiet-period, and meeting exits log
[QUIT] No reminder shown: …naming the controlling preference and when the reminder returns. Fatal exits (missing swiftDialog, non-root, no console user, overlapping run) include a next step. - Demo mode logs that it ignores DDM state and always shows a sample reminder.
- Routine lines are shorter and combined (installed macOS version/build, logged-in user, resolved declaration, Software Update handoff), and logs say "DDM Emergency Fallback" instead of "MDM fallback requirement".
- No changes to reminder timing, DDM trust rules, suppression decisions, preferences, or log line format.
assemble.zshnow accepts a prior.mobileconfigas well as a prior.plist, so a hand-edited Configuration Profile can be re-assembled without the generated.plistdrifting out of sync (Issue #153; thanks, @anewhouse!)- Works from the command line (
zsh assemble.zsh /path/to/prior.mobileconfig) and the drag-and-drop prompt; signed profiles are supported. - The profile must contain exactly one DDM OS Reminder (
*.dorm) preferences payload;Forcedsettings are preferred. Missing, multiple, or ambiguous payloads fail with a clear❌message. - RDNN and deployment lane are inferred as before; a
⚠️warning flags a profile whose*.dormdomain disagrees with the RDNN inScriptLog. - Supplying more than one prior
.plistor.mobileconfignow fails instead of treating the extra path as an RDNN. Prior.plistimport is otherwise unchanged.
- Works from the command line (
- Fixed:
{minutesBeforeDeadline}inPreDeadlineThresholdMessageshowed the crossed threshold (for example,45) instead of the time actually left, overstating time remaining on late runs (padded deadline, heartbeat delay, wake from sleep, or manual run) (Issue #160)- The placeholder now shows minutes remaining until the effective deadline, never above the crossed threshold; on-time runs still show the threshold value. Related
[NOTICE]lines append(<n> minute(s) remaining). - Known: copy reads
1 minuteswhen one minute remains.
- The placeholder now shows minutes remaining until the effective deadline, never above the crossed threshold; on-time runs still show the threshold value. Related
- Fixed: when the disk-space query failed, its fallback
[WARNING]was never written to the client-side log. MinimumDiskFreeGBsample default (Resources/sample.plist, generated.plist/.mobileconfig) raised from26to35after a fully staged macOS update was observed at26.60 GB. The script default (999),0-disables behavior, and imported values are unchanged.Resources/diagnoseReminderState.zsh(1.4.0) reads both new and pre-5.2.0log lines, so logs from older clients still diagnose. It recognizesMinimumBatteryPercentageandBatteryWarningMessage, lists the runtimeBattery:andDisk space:lines, and shows each run'sNo reminder shown:or[QUIT]reason in Client-log runs.- Reviewed the bundled Jamf Pro Extension Attributes for
5.2.0. The5.2.0client-side log changes do not affect them.JamfEA-Pending_OS_Update_Date.zsh,JamfEA-Pending_OS_Update_Version.zsh, andJamfEA-DDM-OS-Reminder-Next-Scheduled-Reminder.zshare now version5.2.0; their resolver and scheduler logic is unchanged.- Fixed:
JamfEA-DDM-OS-Reminder-User-Clicks.zsh(5.2.0) also reported the unformatted[INFO] … not re-showing dialog after <user> clicked …line. It now reports only[NOTICE]<user> clicked <button>lines, and/usr/localwas removed from itsPATH. - Fixed:
JamfEA-Volume_Owners.zshreported every local cryptographic user; it now reports only users flaggedVolume Owner: Yes. JamfEA-DDM_Executed_OS_Update_Date.zsh(5.2.0): corrected its header and theResources/README.mdexample to match its actual behavior andYYYY-MM-DD HH:MM:SSoutput (most recent matchinginstall.logentry).JamfEA-SecureToken_Users.zshandJamfEA-Volume_Owners.zshnow run with--no-rcs, like the other bundled Extension Attributes.
- Upgrade notes:
- Deploy the updated
dor.zshbefore, or together with, any Configuration Profile containing{batteryWarningMessage}; older scripts would show the literal placeholder. Customized message strings (and theirLocalized_<code>variants) need{batteryWarningMessage}added by hand, or the warning never appears. - Scripts, Extension Attributes, or log searches keyed on
Normal DDM resolver result,Resolver suppression summary,MDM fallback requirement,Version Comparison Result: No DDM enforcement log entry found,Installed macOS Version,Resolved DDM declaration, orSoftware Update handoffmust be updated; key onDDM update check:,status=,No reminder shown:,Currently installed macOS,Opening Software Update, andDDM Emergency Fallbackinstead.
- Deploy the updated
What's Changed
- 5.2.0 by @dan-snelson in #163
Full Changelog: v5.1.0...v5.2.0