cheat sheet
softwareupdate
Deep-dive on softwareupdate(8), Apple's CLI for macOS system updates — listing pending updates, installing recommended-only or specific items, scheduling, ignoring updates, installing Rosetta and Command Line Tools, and pairing with mas and brew for full system update automation.
softwareupdate — macOS Updates From the Terminal
What it is
softwareupdate(8) is Apple's command-line interface to the macOS Software Update mechanism — the same engine that powers System Settings → General → Software Update. It lists pending updates, downloads them, installs them (with or without restart), schedules background checks, and can ignore specific updates so they stop pestering the GUI. It's part of base macOS at /usr/sbin/softwareupdate and runs as root for any install operation. Reach for it when you're patching a fleet via SSH, scripting a CI runner's pre-job update, automating Rosetta installation on a new Apple Silicon Mac, or just want to apply security updates without opening System Settings. The Apple-developer-tools subset (Command Line Tools, Xcode beta releases) is also installable here, although Xcode itself comes from the App Store via mas or the GUI. For App Store apps, pair softwareupdate with mas; for third-party CLI tools, pair with Homebrew.
[!WARN] MDM-managed fleets — the legacy update path is deprecated. As of macOS Tahoe 26, the classic MDM
com.apple.SoftwareUpdateconfiguration-profile payload, the matching MDM commands (ScheduleOSUpdate,AvailableOSUpdates), and their related query keys are deprecated and Apple has stated they will be removed in the next major macOS release. New fleet deployments must move to Declarative Software Update Management (thesoftwareUpdate.settingsandsoftwareUpdate.enforcementdeclarations). Thesoftwareupdate(8)binary itself is unaffected and continues to work for interactive / local use — only the MDM scheduling channel is going away. Reference: Apple's What's new for enterprise in macOS Tahoe 26 (linked in Sources below).
Install
softwareupdate ships with every macOS install at /usr/sbin/softwareupdate. It cannot be installed, removed, or upgraded independently — it's part of the OS. Most operations require root, so use sudo.
which softwareupdate
softwareupdate --help 2>&1 | head -20
Output:
/usr/sbin/softwareupdate
usage: softwareupdate <cmd> [<args> ...]
-l | --list List all appropriate updates
-d | --download Download Only
-i | --install Install
<label> ... specific updates
-a | --all all appropriate updates
-r | --recommended only recommended updates
-R | --restart automatically restart (or shut down) if required
--install-rosetta Install Rosetta 2
--fetch-full-installer Fetch full installer of macOS
--list-full-installers List the available full installers
--ignore <label>... Ignore specific updates
--reset-ignored Clear the list of ignored updates
--background Trigger a background scan and update operation
--schedule Set automatic checking
Syntax
Three workflows cover 90% of usage: list pending (-l), install everything (-ia), or install a named subset (-i LABEL1 LABEL2). Add -R to restart automatically; add --agree-to-license for Rosetta and other EULA-bearing installs.
sudo softwareupdate [--list | -l] # list pending
sudo softwareupdate --install --all [-R] # install everything
sudo softwareupdate --install --recommended [-R] # only recommended
sudo softwareupdate --install LABEL [LABEL...] # install specific
sudo softwareupdate --install-rosetta --agree-to-license # install Rosetta 2
sudo softwareupdate --ignore LABEL # ignore an update
softwareupdate --list-full-installers # list installable macOS versions
sudo softwareupdate --fetch-full-installer --full-installer-version 15.4
Output: (none — exits 0 on success)
Essential options
| Option | Meaning |
|---|---|
-l, --list | List available updates (no install) |
-d, --download | Download only — don't install |
-i, --install | Install (requires sudo) |
-a, --all | Apply to all pending updates |
-r, --recommended | Limit to "recommended" updates (excludes betas, optional installs) |
-R, --restart | Restart or shut down automatically when an update demands it |
--no-scan | Use the cached update catalog (skip a fresh check) |
--ignore LABEL | Add LABEL to the ignored list |
--reset-ignored | Clear the ignored list |
--install-rosetta | Install Rosetta 2 (Apple Silicon only) |
--agree-to-license | Auto-accept EULAs (required for Rosetta install) |
--fetch-full-installer | Download a full macOS installer to /Applications |
--full-installer-version VER | Specify which macOS version to fetch |
--list-full-installers | List available macOS installers |
--background | Trigger a background scan/update (used by launchd) |
| `--schedule { on | off }` |
--dump-state | Dump the current update daemon state to log |
-v, --verbose | More log detail |
Listing pending updates
softwareupdate -l checks Apple's update servers, refreshes the local catalog, and prints anything available for installation. Output is two lines per item: a * Label: SOMETHING row and an indented descriptive Title: ... row. The label is the stable identifier you pass to --install, --ignore, and --download.
softwareupdate -l
Output:
Software Update Tool
Finding available software
Software Update found the following new or updated software:
* Label: macOS Sequoia 15.5-24F74
Title: macOS Sequoia 15.5, Version: 15.5, Size: 6489524KiB, Recommended: YES, Action: restart,
* Label: Command Line Tools beta 6 for Xcode-16.4
Title: Command Line Tools beta 6 for Xcode, Version: 16.4, Size: 752856KiB, Recommended: NO,
* Label: Safari18.5MontereyAuto-18.5
Title: Safari, Version: 18.5, Size: 156432KiB, Recommended: YES,
The asterisk-prefixed Label: line is what you pass to -i. Note the trailing version segment (-24F74, -16.4) — labels are version-specific so they change with every catalog refresh.
# Just the labels, suitable for scripting
softwareupdate -l 2>/dev/null | awk -F': ' '/Label/ {print $2}'
Output:
macOS Sequoia 15.5-24F74
Command Line Tools beta 6 for Xcode-16.4
Safari18.5MontereyAuto-18.5
# Recommended only — strip non-recommended from the dump
softwareupdate -l 2>/dev/null | awk '
/Label:/ { lbl=$0 }
/Recommended: YES/ { print lbl }
'
Output:
* Label: macOS Sequoia 15.5-24F74
* Label: Safari18.5MontereyAuto-18.5
The first
softwareupdate -lafter a reboot or after--reset-ignoredcan take 30–90 seconds. Subsequent runs use the cached catalog (--no-scan).
Installing updates
The install flow is "list → confirm → install". For routine maintenance, softwareupdate -ia -R is the workhorse: install everything available, restart automatically if any item requires it. The --restart flag is mandatory for OS updates that contain a kernel or firmware component; without it the install completes but pending work stays queued until the next manual reboot.
# Install everything pending (security + recommended + optional)
sudo softwareupdate -ia
Output:
Software Update Tool
Downloading Safari
Downloaded Safari
Installing Safari
Done with Safari
Done.
# Install everything AND restart if any update requires it
sudo softwareupdate -ia -R
Output:
Software Update Tool
Downloading macOS Sequoia 15.5
Downloaded macOS Sequoia 15.5
Installing macOS Sequoia 15.5
You need to restart your computer to install these updates.
The computer will restart automatically.
# Only "recommended" — skip beta CLT, betas, optional firmware
sudo softwareupdate -i -r -R
Output:
Software Update Tool
Downloading Safari
Downloaded Safari
Installing Safari
Done with Safari
Done.
# Install a specific update by label
sudo softwareupdate -i "Safari18.5MontereyAuto-18.5"
Output:
Software Update Tool
Downloading Safari
Downloaded Safari
Installing Safari
Done with Safari
Done.
[!WARN] The label string is case-sensitive, must include the trailing version segment, and must not include the leading
* Label:prefix fromsoftwareupdate -l. Quote it because labels often contain spaces and version dashes that the shell might misparse.
Download-only mode
softwareupdate -d LABEL (or --download --all) downloads the update payload to /Library/Updates/ without installing. Useful when you want to pre-stage a large macOS update during off-hours and install it later during a maintenance window.
# Pre-stage all pending updates
sudo softwareupdate -d -a
Output:
Software Update Tool
Downloading macOS Sequoia 15.5
Downloading Safari
Done.
# Where downloads land
ls -lh /Library/Updates/
Output:
total 0
drwxr-xr-x 4 root wheel 128B May 25 10:02 071-12345
drwxr-xr-x 3 root wheel 96B May 25 10:03 091-67890
# Install from the cached download (no re-fetch)
sudo softwareupdate -i -a --no-scan -R
Output:
Software Update Tool
Installing macOS Sequoia 15.5
The computer will restart automatically.
Ignoring updates
--ignore LABEL adds an update to a system list that suppresses it from softwareupdate -l output and the System Settings notification badge. The list is per-system, stored in /Library/Preferences/com.apple.SoftwareUpdate.plist. Use this to defer a problematic update (e.g. an OS major version your enterprise hasn't certified) without disabling Software Update entirely.
# Ignore the macOS 16 upgrade prompt
sudo softwareupdate --ignore "macOS Sequoia 15.5-24F74"
softwareupdate -l
Output:
Software Update Tool
Finding available software
Software Update found the following new or updated software:
* Label: Safari18.5MontereyAuto-18.5
Title: Safari, Version: 18.5, Size: 156432KiB, Recommended: YES,
# View the ignored list
defaults read /Library/Preferences/com.apple.SoftwareUpdate InactiveUpdates 2>/dev/null
Output:
(
"macOS Sequoia 15.5-24F74"
)
# Clear the ignored list — everything reappears
sudo softwareupdate --reset-ignored
Output:
Software Update Tool
Modern macOS (Big Sur 11+) restricts
--ignorefor major OS upgrades on Apple-Silicon Macs — Apple removed that affordance. It still works for point releases, Safari, Command Line Tools, and firmware. For full major-version blocking on managed fleets, use an MDMSoftwareUpdatepayload.
Installing Rosetta 2
Rosetta 2 is Apple's x86_64-to-arm64 translation layer; first launch of an Intel-only binary on Apple Silicon triggers a GUI prompt, but the CLI install is the right step for unattended provisioning (CI runners, freshly imaged developer Macs, headless build hosts).
# Install Rosetta 2 non-interactively
sudo softwareupdate --install-rosetta --agree-to-license
Output:
Software Update Tool
Finding available software
Installing: Rosetta 2
2025-05-25 10:30:00.123 softwareupdate[1234:5678] Package Authoring Error: Rosetta 2 will be installed.
Done with Rosetta 2
Done.
# Verify Rosetta is installed by checking for the binary
ls -l /Library/Apple/usr/libexec/oah/translate
Output:
-rwxr-xr-x 1 root wheel 98432 May 20 14:30 /Library/Apple/usr/libexec/oah/translate
# Confirm an Intel binary now runs
arch -x86_64 uname -m
Output:
x86_64
[!WARN]
--install-rosettais a no-op on Intel Macs (it exits successfully with a "not needed" message). It only does meaningful work on Apple Silicon. Adding--agree-to-licenseis mandatory; without it the install pauses for an interactive EULA prompt that hangs in non-tty contexts.
Full installers — downloading the macOS installer app
For erasing and reinstalling a Mac (e.g. before resale, or to create a bootable installer USB), download the full installer app to /Applications and use it with createinstallmedia.
# What macOS versions are available?
softwareupdate --list-full-installers
Output:
Software Update Tool
Finding available software
Software Update found the following full installers:
* Title: macOS Sequoia, Version: 15.5, Size: 14523432KiB, Build: 24F74
* Title: macOS Sequoia, Version: 15.4.1, Size: 14512345KiB, Build: 24E263
* Title: macOS Sonoma, Version: 14.7.5, Size: 13458912KiB, Build: 23H527
* Title: macOS Ventura, Version: 13.7.6, Size: 12345678KiB, Build: 22H626
# Download the latest Sequoia installer (~14 GB)
sudo softwareupdate --fetch-full-installer --full-installer-version 15.5
Output:
Install finished successfully
# Resulting installer
ls /Applications/ | grep "Install macOS"
Output:
Install macOS Sequoia.app
# Create a bootable installer USB
sudo /Applications/Install\ macOS\ Sequoia.app/Contents/Resources/createinstallmedia \
--volume /Volumes/USB --nointeraction
Output:
Erasing disk: 0%... 10%... 20%... 100%
Copying to disk: 0%... 100%
Making disk bootable...
Install media now available at "/Volumes/Install macOS Sequoia"
Background and scheduled updates
macOS runs softwareupdate --background periodically from a launchd timer (com.apple.softwareupdated.plist). You can toggle the whole feature with --schedule on/off and inspect the scheduler state via defaults read /Library/Preferences/com.apple.SoftwareUpdate.
# Status of automatic updates
defaults read /Library/Preferences/com.apple.SoftwareUpdate AutomaticCheckEnabled
defaults read /Library/Preferences/com.apple.SoftwareUpdate AutomaticDownload
defaults read /Library/Preferences/com.apple.SoftwareUpdate AutomaticallyInstallMacOSUpdates
Output:
1
1
0
# Turn automatic checking on/off
sudo softwareupdate --schedule on
sudo softwareupdate --schedule off
Output:
Automatic check is on.
Automatic check is off.
# Trigger an immediate background pass (used by launchd, but you can invoke it manually)
sudo softwareupdate --background
Output:
Software Update Tool
Background scan complete
# Configure aggressive auto-update behaviour via defaults (then reboot)
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate AutomaticCheckEnabled -bool true
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate AutomaticDownload -bool true
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate AutomaticallyInstallMacOSUpdates -bool true
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate ConfigDataInstall -bool true
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate CriticalUpdateInstall -bool true
Output: (none — exits 0 on success)
Comparison vs mas and Homebrew
softwareupdate covers OS updates and Apple-shipped components only — macOS itself, Safari, Command Line Tools, XProtect, MRT, Gatekeeper signature bundles, Rosetta. It does not update third-party CLI tools (ripgrep, node) or App Store apps (Pages, Xcode). For complete fleet automation you need three tools, each with a specific scope.
| Tool | Scope | Install | Typical usage |
|---|---|---|---|
softwareupdate | macOS itself, Safari, CLT, XProtect, firmware, Rosetta | built-in | sudo softwareupdate -ia -R |
mas | Mac App Store apps (Pages, Xcode, Keynote, Slack-from-MAS) | brew install mas | mas upgrade |
brew | Homebrew formulae + casks (CLI + non-MAS GUI apps) | /bin/bash -c "$(curl ...)" | brew update && brew upgrade && brew upgrade --cask |
# Install mas if you don't have it
brew install mas
# List outdated Mac App Store apps
mas outdated
Output:
409183694 Keynote (14.0)
408981434 iMovie (10.4.2)
640199958 Apple Developer (12.1)
# Upgrade everything in the App Store
mas upgrade
Output:
==> Upgrading 3 outdated applications:
Keynote (14.0), iMovie (10.4.2), Apple Developer (12.1)
==> Downloading Keynote
==> Installed Keynote
...
# Compare: brew side
brew update
brew outdated
brew upgrade
brew upgrade --cask
brew cleanup
Output:
==> Auto-updated Homebrew!
==> Outdated Formulae
ripgrep 14.1.0 -> 14.1.1
node 20.12.0 -> 20.14.0
==> Upgrading 2 outdated packages:
ripgrep 14.1.0 -> 14.1.1
node 20.12.0 -> 20.14.0
A complete "Update Everything" sequence is
sudo softwareupdate -ia && brew update && brew upgrade && brew upgrade --cask && mas upgrade. Wrap in a single script and you have a one-command Mac maintenance routine.
Command Line Tools — installation paths
The Apple Command Line Tools (CLT) bundle (clang, git, make, headers) is also distributed via softwareupdate. There are three ways to install it.
# Method 1: xcode-select triggers an interactive popup
xcode-select --install
Output: (none — exits 0 on success; shows a GUI prompt)
# Method 2: softwareupdate, scriptable
# Step 1 — create the marker file softwareupdate uses to enable CLT in its listing
sudo touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
# Step 2 — find and install the latest CLT label
PROD=$(softwareupdate -l 2>&1 | awk '/Command Line Tools/ {sub(/^\* Label: /,""); print; exit}')
sudo softwareupdate -i "$PROD"
# Step 3 — remove the marker
sudo rm -f /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
# Verify
xcode-select -p
Output:
/Library/Developer/CommandLineTools
# Method 3: Full Xcode from the App Store (`mas install 497799835`) — also provides CLT
mas install 497799835
Output: (none — exits 0 on success)
Reading the update log
softwareupdate writes detailed activity to /var/log/install.log (install events) and to the unified system log under subsystem com.apple.SoftwareUpdate. For troubleshooting a stuck or failed update, both are essential.
# Recent install.log entries
sudo tail -50 /var/log/install.log
Output:
2026-05-25 10:30:00+0000 myhost softwareupdated[123]: SUTool: Available updates pre-flight=0 actually=2
2026-05-25 10:30:15+0000 myhost softwareupdated[123]: SUTool: Installing Safari18.5
2026-05-25 10:30:45+0000 myhost installd[456]: PackageKit: package install: stage success
2026-05-25 10:31:02+0000 myhost softwareupdated[123]: SUTool: Done with Safari18.5
# Stream live unified-log events from softwareupdated
log stream --predicate 'subsystem == "com.apple.SoftwareUpdate"' --level debug
Output: (streams continuously until Ctrl-C)
2026-05-25 10:30:00.123 softwareupdated [DEBUG] Beginning background scan
2026-05-25 10:30:01.456 softwareupdated [DEBUG] Catalog refreshed: 3 items
2026-05-25 10:30:02.789 softwareupdated [DEFAULT] Notification posted for available updates
# Historical log query — last 24 hours of softwareupdate activity
log show --predicate 'subsystem == "com.apple.SoftwareUpdate"' --last 24h --info
Output: (multi-page tabular log dump — pipe to less or grep to scope)
Common pitfalls
- Forgetting
sudo—softwareupdate -iawithoutsudoexits silently with no installs done. Always prefix install ops withsudo. - Quoting labels wrong — labels contain spaces, dashes, and digits. Use single quotes:
sudo softwareupdate -i 'macOS Sequoia 15.5-24F74'. - Major OS upgrades no longer install non-interactively — since Big Sur, upgrading to a new major macOS version via
softwareupdate -iis blocked on Apple Silicon. Use--fetch-full-installerplusstartosinstall, or use an MDM-pushed update. -Rwithout battery — on a laptop,--restarttriggers an immediate reboot. If you're on battery and below 50%, the install daemon refuses to start the OS update; checkpmset -g battbefore scheduling.- Rosetta install fails silently on Intel —
--install-rosettais a no-op on Intel; checkuname -mfirst. - Pre-staged downloads expire — items in
/Library/Updates/can be invalidated when the catalog refreshes. Use--no-scanto install from the cache without a fresh check, but only within ~24 hours of the download. --listreturns stale data —softwareupdate -l --no-scanuses cache that may be hours old. Force-refresh:sudo softwareupdate --backgroundfollowed bysoftwareupdate -l.- MDM-managed Macs override CLI choices — if a Jamf/Mosyle/Kandji profile restricts updates, your
--install/--ignoreoperations may be silently no-ops. Checkprofiles -P. - FileVault delays restart — if FileVault is enabled,
-Rschedules the restart but the system asks for credentials on the next boot. Headless servers should usefdesetup authrestart(provide unlock credentials in advance). --ignoredoesn't block silent installs — Apple-pushed XProtect, MRT, and Gatekeeper signature bundles install viasoftwareupdatedregardless of the ignore list. To suppress those, disableConfigDataInstallandCriticalUpdateInstallin the preferences plist — at your own risk.- Stale
softwareupdatedcache — ifsoftwareupdate -lshows the same update for days after you installed it, kill the daemon:sudo killall softwareupdated. It will respawn from launchd within seconds. - CLT label changes with each Xcode beta — automation that hardcodes a label like
Command Line Tools for Xcode-16.3breaks at Xcode 16.4. Always parse the latest label out ofsoftwareupdate -l.
Real-world recipes
One-shot "patch everything, restart if needed"
The single-command system update used for maintenance windows.
sudo softwareupdate -ia -R --no-scan
Output:
Software Update Tool
Downloading Safari
Downloaded Safari
Installing Safari
Done with Safari
Done.
Update macOS + Homebrew + App Store in one script
A complete maintenance routine. Run weekly.
#!/bin/bash
# update-everything.sh — patch macOS, Homebrew, and App Store apps
set -euo pipefail
log() { echo "[$(date +%H:%M:%S)] $*"; }
log "Apple updates"
sudo softwareupdate -ia -R --no-scan || log "softwareupdate had issues"
log "Homebrew formulae"
brew update
brew upgrade
brew cleanup -s
log "Homebrew casks"
brew upgrade --cask --greedy
log "Mac App Store"
if command -v mas >/dev/null; then
mas upgrade
fi
log "Done"
Output:
[10:30:01] Apple updates
[10:35:42] Homebrew formulae
==> Upgrading 5 outdated packages...
[10:38:11] Homebrew casks
[10:40:22] Mac App Store
[10:41:05] Done
Provision a fresh Apple Silicon Mac
After unboxing an M-series Mac, run this once to install Rosetta, CLT, and update everything.
#!/bin/bash
set -euo pipefail
# Rosetta 2 (for Intel binaries; needed by some Homebrew bottles)
if [[ "$(uname -m)" == "arm64" ]]; then
sudo softwareupdate --install-rosetta --agree-to-license
fi
# Command Line Tools (clang, git, make, headers)
if ! xcode-select -p >/dev/null 2>&1; then
sudo touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
CLT=$(softwareupdate -l 2>&1 | awk '/Command Line Tools/ {sub(/^\* Label: /,""); print; exit}')
sudo softwareupdate -i "$CLT" --verbose
sudo rm -f /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
fi
# OS updates
sudo softwareupdate -ia
# Homebrew
if ! command -v brew >/dev/null; then
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
echo "Bootstrap complete. Reboot when convenient."
Output:
Software Update Tool
Installing: Rosetta 2
Done with Rosetta 2
Done.
Software Update Tool
Downloading Command Line Tools for Xcode
Done.
==> Now run brew update && brew bundle to install your packages
Bootstrap complete. Reboot when convenient.
Defer the next major OS upgrade
Block the macOS 16 nag without disabling Software Update.
sudo softwareupdate --ignore "macOS Sequoia 16.0-25A123"
softwareupdate -l
Output:
Software Update Tool
Finding available software
No new software available.
(Replace the label with whatever softwareupdate -l actually shows.)
Audit pending updates across a fleet via SSH
A one-liner pattern for inventorying outstanding patches.
for host in mac01 mac02 mac03 mac04; do
printf "%-12s " "$host"
ssh "$host" 'softwareupdate -l 2>/dev/null | grep -c "^* Label:"'
done
Output:
mac01 2
mac02 0
mac03 5
mac04 1
# Or detailed: every host's pending labels
for host in mac01 mac02 mac03 mac04; do
echo "=== $host ==="
ssh "$host" 'softwareupdate -l 2>/dev/null | grep "^\* Label:"'
done
Output:
=== mac01 ===
* Label: Safari18.5MontereyAuto-18.5
* Label: macOS Sequoia 15.5-24F74
=== mac02 ===
=== mac03 ===
* Label: macOS Sequoia 15.5-24F74
* Label: Safari18.5MontereyAuto-18.5
* Label: XProtectPayloads_10_15-100
* Label: XProtectPlistConfigData_10_15-2186
* Label: Command Line Tools for Xcode-16.4
Create a bootable Sequoia installer USB
For tech-bench reinstall scenarios.
# 1. Fetch the full installer (~14 GB)
sudo softwareupdate --fetch-full-installer --full-installer-version 15.5
# 2. Format the target USB stick
diskutil eraseDisk JHFS+ "MacInstall" /dev/disk4
# 3. Build the bootable media
sudo /Applications/Install\ macOS\ Sequoia.app/Contents/Resources/createinstallmedia \
--volume /Volumes/MacInstall --nointeraction
Output:
Erasing disk: 0%... 10%... 20%... 100%
Making disk bootable...
Install media now available at "/Volumes/Install macOS Sequoia"
Schedule overnight downloads, install on demand
Pre-stage during the night, install during a controlled morning window.
# 11pm — schedule via cron or a launchd plist
sudo softwareupdate -d -a --no-scan
# Morning maintenance window — install from cache
sudo softwareupdate -ia --no-scan -R
Output: (none — see install.log for detail)
Block all auto-update behaviour
For an air-gapped build host where you control every install manually.
sudo softwareupdate --schedule off
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate AutomaticCheckEnabled -bool false
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate AutomaticDownload -bool false
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate AutomaticallyInstallMacOSUpdates -bool false
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate ConfigDataInstall -bool false
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate CriticalUpdateInstall -bool false
Output: (none — exits 0 on success)
[!WARN] Disabling
ConfigDataInstallandCriticalUpdateInstallblocks the silent XProtect / MRT signature bundles that protect against new malware families. Only do this on intentionally isolated hosts where you accept the trade-off.
Send a Slack ping when updates are available
Wire softwareupdate -l into a daily notification.
#!/bin/bash
# check-updates-and-notify.sh
COUNT=$(softwareupdate -l 2>/dev/null | grep -c "^\* Label:")
if (( COUNT > 0 )); then
LABELS=$(softwareupdate -l 2>/dev/null | grep "^\* Label:" | sed 's/^\* Label: / • /')
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\": \"*${HOSTNAME}* has $COUNT pending update(s):\n\`\`\`\n$LABELS\n\`\`\`\"}" \
"$SLACK_WEBHOOK_URL"
fi
Output: (none — webhook fires)
Schedule the script above as a daily launchd
StartCalendarIntervalagent under~/Library/LaunchAgents/. Seelaunchctlfor the plist skeleton.
See also
homebrew— third-party CLI and GUI package management.macos-cli— broader macOS terminal reference.xattr— clearing quarantine on downloaded installers beforeinstaller -pkg.mas—brew install masfor App Store CLI; pairs withsoftwareupdateandbrewfor full fleet update coverage.
Sources
References consulted while writing and updating this article. Links open in a new tab. Order is curated by relevance — sorting is intentionally disabled (data-no-sort).
| Source | Why cited |
|---|---|
| What's new for enterprise in macOS Tahoe 26 — Apple Support | Authoritative announcement that the MDM com.apple.SoftwareUpdate payload and related commands are deprecated and slated for removal in the next major macOS, motivating the Declarative-Software-Update WARN callout. |
| How macOS 26 Tahoe updates: 3 Catalogues — Eclectic Light Co. | Detailed trace of the softwareupdated catalog flow (Pallas server, macOS26Short / macOS26Long delta vs. full update, mobile-asset catalogs) underpinning the install-internals section. |
| How macOS 26 Tahoe updates: 4 Download, preparation, installation — Eclectic Light Co. | Preflight / cryptex / RecoveryOS phase walkthrough used to validate the modern restart-and-stage flow described in Installing updates. |
| Update macOS on Mac — Apple Support | Canonical user-facing Apple documentation cross-referenced for terminology (recommended vs. optional, point release vs. major upgrade) used in Listing pending updates and Installing updates. |
| The Software Update UI for Upgrading to macOS 26 Tahoe Is Needlessly Confusing — Daring Fireball | Independent commentary on the Tahoe upgrade UX confirming the recommendation to pin labels parsed at runtime rather than hard-coded. |
| mas-cli/mas on GitHub | Authoritative reference for the App Store CLI used in the "Update macOS + Homebrew + App Store in one script" recipe. |