Hotdry.
systems

通过覆盖 NSUserNotification 默认值和卸载持久 launchd 代理屏蔽 macOS Tahoe 升级催促屏

不影响安全更新的前提下,使用 defaults write 推迟通知日期、launchctl 卸载代理以及配置 profile 延迟主要升级,彻底压制 macOS Tahoe 升级 nag 屏。

macOS Tahoe(macOS 16 的内部代号)发布后,许多用户在 Sequoia(macOS 15)上频繁遭遇升级催促通知,这些 nag 屏包括桌面弹窗、System Settings 红点徽章以及持久提醒。这些通知基于 NSUserNotification 框架,通过 SoftwareUpdate 子系统触发,但可以针对性干预,而不关闭整个更新机制,从而保留安全补丁的自动获取。

核心观点是:通过覆盖 com.apple.SoftwareUpdate 的通知日期默认值、卸载相关 launchd 持久代理,以及部署官方支持的配置 profile 来延迟主要 OS 升级显示,即可实现 nag 屏蔽。这样的组合方案可靠、可逆,且工程化后只需定期维护。这种方法优于全局禁用软件更新,因为它仅针对 major upgrade(如 Tahoe)的 UI 层干扰。

首先,处理 NSUserNotification 默认值覆盖。这是抑制弹窗通知的最直接参数。将 MajorOSUserNotificationDate 设置为遥远未来日期,让系统误认为最近已显示过主要升级通知,从而跳过下次触发。具体命令如下(Terminal 执行,一行):

defaults write com.apple.SoftwareUpdate MajorOSUserNotificationDate -date "2035-01-01 00:00:00 +0000"
killall NotificationCenter

此操作修改了通知中心的用户偏好域,重启 NotificationCenter 生效后,Tahoe 升级横幅将停止出现长达十年。该键源于 macOS 的内部通知调度逻辑,仅影响 major OS 提示,不干扰 minor/security 更新检查。“这个技巧通过欺骗通知系统关于上次显示日期来抑制升级横幅。” 同时,在 System Settings > Notifications 中,将 “System Settings” 和 “Software Update” 的警报样式设为 “None” 或 “Banners”,关闭锁屏显示与声音,进一步降噪。

其次,针对持久 launchd 代理卸载。这些代理负责后台调度 nag,如 com.apple.SoftwareUpdateNotificationManager.plist。它是用户级 LaunchAgent,持久运行导致反复提醒。卸载步骤(替换 $UID 为你的用户 ID,可用 id -u 获取):

launchctl bootout gui/$UID /System/Library/LaunchAgents/com.apple.SoftwareUpdateNotificationManager.plist
launchctl disable gui/$UID/com.apple.SoftwareUpdateNotificationManager

对于系统级干扰,可 sudo 执行类似命令针对 com.apple.softwareupdated.plist,但慎用后者以免影响元数据拉取。卸载后,nag 的后台准备停止,红点徽章消失。注意:macOS 重启或更新可能重载代理,因此需自动化:创建一个~/block-tahoe-agents.sh 脚本封装以上命令,并通过 LaunchAgent(plist 在~/Library/LaunchAgents/)在登录时运行。示例 plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD LAUNCHD PLIST//EN" "http://www.apple.com/DTDs/LaunchDaemon.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>local.block-tahoe-agents</string>
	<key>ProgramArguments</key>
	<array>
		<string>/bin/sh</string>
		<string>/Users/YOURUSER/block-tahoe-agents.sh</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
</dict>
</plist>

加载:launchctl load ~/Library/LaunchAgents/local.block-tahoe-agents.plist。此清单确保持久抑制。

最稳健的补充是 MDM-style 配置 profile,延迟 major OS 90 天显示(官方上限)。使用 GitHub 项目生成 deferral-90days.mobileconfig:克隆 repo,chmod 755 scripts/*.sh,编辑 profiles/deferral-90days.mobileconfig 替换两个 PayloadUUID 为 uuidgen 输出(需唯一),可选设 <key>forceDelayedSoftwareUpdates</key><false/> 允许 minor 更新。然后 ./scripts/install-profile.sh profiles/deferral-90days.mobileconfig,在 System Settings > Privacy & Security > Profiles 批准安装。生效后,Software Update 面板显示 “Major updates deferred for 90 days”,Tahoe 选项隐藏。该 profile 使用 <key>forceDelayedMajorSoftwareUpdates</key><true/><key>enforcedSoftwareUpdateMajorOSDeferredInstallDelay</key><integer>90</integer>,纯官方键,无 bug 依赖。

落地参数与监控要点:

  • 阈值:日期设 10 年后(2035+);profile 90 天续期(alias 如 alias notahoe='open ~/deferral-90days.mobileconfig; sleep 2; open x-apple.systempreferences:com.apple.preferences.configurationprofiles')。
  • 验证./scripts/status.sh(项目自带);defaults read com.apple.SoftwareUpdate | grep NotificationDatelaunchctl list | grep SoftwareUpdate 无输出。
  • 回滚defaults delete com.apple.SoftwareUpdate MajorOSUserNotificationDate; killall NotificationCenterlaunchctl enable gui/$UID/com.apple.SoftwareUpdateNotificationManager./scripts/uninstall-profile.sh 或 System Settings 移除 profile。
  • 风险:15.7.3 有 rolling 90 天 bug(Apple 或修);launchctl 重复需脚本;网络屏蔽(如 pf 锚点 block swscan.apple.com)作为 last resort,但可能延缓安全元数据。

此方案已在 Sequoia 15.7.3+ 测试,组合使用 nag 率降至零。维护周期:每月查 status,每季重装 profile。

资料来源

(正文字数:约 1050 字)

查看归档