Skip to main content

Nudge for macOS Software Updates (macOS Script)

What

Nudge is a multi-linguistic application offering custom user deferrals, strongly encouraging macOS updates. This macOS application helps users stay up-to-date with software updates and security patches installed. It is a lightweight and simple application that runs in the background and periodically checks for updates. Once it detects the administrative’s configured settings for a minimum update, it displays a notification to the user, urging them to update the software package. It is available here: GitHub - macadmins/nudge: A tool for encouraging the installation of macOS security updates.

When/Why

Keeping software up-to-date is essential for any system's security and smooth functioning. However, it can be a daunting task to manually track software updates, especially when multiple software packages are installed on the device. That's where Nudge comes into the picture. It automates the software update checking and notification process, making it easier for users to stay on top of updates.

Nudge also helps to address security vulnerabilities in software packages, which malicious actors can exploit to gain unauthorized access to the device or steal sensitive data. By promptly updating software packages, users can significantly reduce the risk of such security incidents.

Moreover, Nudge helps improve the system's overall performance by updating software packages with bug fixes and other improvements. Outdated software can be a major cause of system crashes, lagging, and other performance issues, which can be avoided by updating software packages regularly.

How

Nudge will only work on macOS Big Sur 11 and later. Nudge has two main objects that must be configured to be useful in production: a LaunchAgent and a Configuration. Nudge configuration could be achieved using either of the following two primary methods:

  • Configuration Profile

OR

  • JSON file

Nudge functionality: Rather than trying to install updates via the macOS built-in softwareupdate binary, Nudge prompts users to install updates via Apple approved/tested methods: System Preferences > Software Update and major application upgrades via the standalone macOS installer (Ex: Install macOS Monterey.app). This method does require the use of admin password. If your end users have administrative access Nudge is an excellent alternative approved by Apple’s methods.

Prior to macOS 11, Software Updates were pulled from Apple's catalogue (not MDM App Store) through FileWave. To achieve this, the client will overwrite the current Software Update plist whilst running and then revert the file once done. This will likely conflict with any Nudge process, causing Nudge to fail if the two occur at the same time. You can however get around this.

There is a client setting that could be pushed with Superpref to disable non MDM updates, but easier still, if you disable Legacy Apple Software Updates entirely from the FileWave Central > Preferences > Software Updates tab. This will allow clients not request to attempt non-MDM checks anymore.SoftwareUpdatePreferences.pngWorth noting, that every Model Update, Inventory, Verify, the fwcld client process overwrites this file, since it needs to report which updates are appropriate, so this isn't a case of they might only conflict if you have associated updates, this happens always if not disabled.

Setting Up Nudge with FileWave

Installing Nudge

Nudge has provided a script that can be used to install the latest Nudge suite package. Below is the script contents, also included is logging for the FileWave client:

Install Nudge script
#!/bin/bash

# Writing details to the FileWave Client Log
exec 1>>/var/log/fwcld.log
exec 2>>/var/log/fwcld.log

# Variables
nudgeLatestURL="https://github.com/macadmins/nudge/releases/latest/"
versionUrl=$(curl "${nudgeLatestURL}" -s -L -I -o /dev/null -w '%{url_effective}')
versionNumber=$(printf "%s" "${versionUrl[@]}" | sed 's@.*/@@' | sed 's/%20/-/g')
versionNumber=${versionNumber:1}
downloadUrl="https://github.com/macadmins/nudge/releases/download/v$versionNumber/Nudge_Suite-$versionNumber.pkg"
header="$(curl -sI "$downloadUrl" | tr -d '\r')"
pkgName=$(printf "%s" "${downloadUrl[@]}" | sed 's@.*/@@' | sed 's/%20/-/g')
pkgPath="/tmp/$pkgName"

# Download files
/usr/bin/curl -L -o "$pkgPath" "$downloadUrl"

# Install PKGs
sudo installer -pkg $pkgPath -target /

# Delete PKGs
sudo /bin/rm "$pkgPath"

exit 0

 

You may download the Nudge Installation Fileset here: Nudge Installation.fileset.zip

The Fileset contents should be similar as shown below. This Fileset includes both the installation and uninstallation scripts.

NudgeInstallationFilesetContents.png

Configuration Profile

You may copy the complete example default config profile from GitHub Nudge - Getting Started: Configuration Profile. For this KB article, we have copied and removed the extra configuration settings to include only the basic items needed for Nudge to function.

Configuration Profile metadata
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>PayloadContent</key>
    <array>
      <dict>
        <key>PayloadDescription</key>
        <string>Configures all Nudge preferences</string>
        <key>PayloadDisplayName</key>
        <string>Nudge Preferences</string>
        <key>PayloadIdentifier</key>
        <string>com.github.macadmins.Nudge.preferences</string>
        <key>PayloadOrganization</key>
        <string></string>
        <key>PayloadType</key>
        <string>com.github.macadmins.Nudge</string>
        <key>PayloadUUID</key>
        <string>CA02957C-7472-446B-9F77-3E0414405556</string>
        <key>PayloadVersion</key>
        <integer>1</integer>
        <key>osVersionRequirements</key>
        <array>
          <dict>
            <key>requiredInstallationDate</key>
            <date>2023-05-30T04:00:00Z</date>
            <key>requiredMinimumOSVersion</key>
            <string>13.3.1</string>
          </dict>
        </array>
      </dict>
    </array>
    <key>PayloadDescription</key>
    <string>Configures Nudge application</string>
    <key>PayloadDisplayName</key>
    <string>Nudge Preferences</string>
    <key>PayloadIdentifier</key>
    <string>com.github.macadmins.Nudge.FileWave</string>
    <key>PayloadOrganization</key>
    <string>Nudge</string>
    <key>PayloadScope</key>
    <string>System</string>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>2F54F734-132D-4539-B583-F1DCF23DB5EB</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
  </dict>
</plist>

 

You may copy the above for the basic functions for Nudge and paste into a text editor, such as Atom, Notepad ++, etc. To configure, please note lines 26 and 28. These need to be modified based on your desired:

  • requiredInstallationDate: 2023-05-30T04:00:00Z, May, 30 2023 at 12:00AM EST

  • requiredMinimumVersion: 13.3.1, i.e. macOS 13.3.1 (Ventura)

Save the file, any name desired, as long as you save with the extension, .mobileconfig. Next import into FileWave Admin; drag and drop the .mobileconfig into FileWave Central Admin.

When you open the profile within FileWave, there will be no payload regarding the Nudge configurations displayed.

JSON File

You may copy the complete example JSON configuration file from GitHub Nudge - Getting Started: JSON Configuration File. Below is the JSON config file that we will use.

JSON File metadata
{
    "optionalFeatures": {
        "acceptableApplicationBundleIDs": [],
        "acceptableAssertionUsage": false,
        "acceptableCameraUsage": false,
        "acceptableScreenSharingUsage": false,
        "aggressiveUserExperience": true,
        "aggressiveUserFullScreenExperience": true,
        "asynchronousSoftwareUpdate": true,
        "attemptToBlockApplicationLaunches": false,
        "attemptToFetchMajorUpgrade": true,
        "blockedApplicationBundleIDs": [],
        "enforceMinorUpdates": true,
        "terminateApplicationsOnLaunch": false
    },
    "osVersionRequirements": [
        {
            "aboutUpdateURL_disabled": "https://support.apple.com/en-us/HT211896#macos1121",
            "aboutUpdateURLs": [
                {
                    "_language": "en",
                    "aboutUpdateURL": "https://support.apple.com/en-us/HT211896#macos1121"
                },
                {
                    "_language": "es",
                    "aboutUpdateURL": "https://support.apple.com/es-es/HT211896"
                },
                {
                    "_language": "fr",
                    "aboutUpdateURL": "https://support.apple.com/fr-fr/HT211896"
                },
                {
                    "_language": "de",
                    "aboutUpdateURL": "https://support.apple.com/de-de/HT211896"
                }
            ],
            "actionButtonPath": "munki://updates",
            "majorUpgradeAppPath": "/Applications/Install macOS Big Sur.app",
            "requiredInstallationDate": "2021-08-28T00:00:00Z",
            "requiredMinimumOSVersion": "11.5.2",
            "targetedOSVersionsRule": "default"
        }
    ],
    "userExperience": {
        "allowGracePeriods": false,
        "allowLaterDeferralButton": true,
        "allowUserQuitDeferrals": true,
        "allowedDeferrals": 1000000,
        "allowedDeferralsUntilForcedSecondaryQuitButton": 14,
        "approachingRefreshCycle": 6000,
        "approachingWindowTime": 72,
        "calendarDeferralUnit": "imminentWindowTime",
        "elapsedRefreshCycle": 300,
        "gracePeriodInstallDelay": 23,
        "gracePeriodLaunchDelay": 1,
        "gracePeriodPath": "/private/var/db/.AppleSetupDone",
        "imminentRefreshCycle": 600,
        "imminentWindowTime": 24,
        "initialRefreshCycle": 18000,
        "launchAgentIdentifier": "com.github.macadmins.Nudge",
        "loadLaunchAgent": false,
        "maxRandomDelayInSeconds": 1200,
        "noTimers": false,
        "nudgeRefreshCycle": 60,
        "randomDelay": false
    },
    "userInterface": {
        "actionButtonPath": "munki://updates",
        "fallbackLanguage": "en",
        "forceFallbackLanguage": false,
        "forceScreenShotIcon": false,
        "iconDarkPath": "/somewhere/logoDark.png",
        "iconLightPath": "/somewhere/logoLight.png",
        "screenShotDarkPath": "/somewhere/screenShotDark.png",
        "screenShotLightPath": "/somewhere/screenShotLight.png",
        "showDeferralCount": true,
        "simpleMode": false,
        "singleQuitButton": false,
        "updateElements": [
            {
                "_language": "en",
                "actionButtonText": "Update Device",
                "customDeferralButtonText": "Custom",
                "customDeferralDropdownText": "Defer",
                "informationButtonText": "More Info",
                "mainContentHeader": "Your device will restart during this update",
                "mainContentNote": "Important Notes",
                "mainContentSubHeader": "Updates can take around 30 minutes to complete",
                "mainContentText": "A fully up-to-date device is required to ensure that IT can accurately protect your device.\n\nIf you do not update your device, you may lose access to some items necessary for your day-to-day tasks.\n\nTo begin the update, simply click on the Update Device button and follow the provided steps.",
                "mainHeader": "Your device requires a security update",
                "oneDayDeferralButtonText": "One Day",
                "oneHourDeferralButtonText": "One Hour",
                "primaryQuitButtonText": "Later",
                "secondaryQuitButtonText": "I understand",
                "subHeader": "A friendly reminder from your local IT team"
            },
            {
                "_language": "es",
                "actionButtonText": "Actualizar dispositivo",
                "informationButtonText": "Más información",
                "mainContentHeader": "Su dispositivo se reiniciará durante esta actualización",
                "mainContentNote": "Notas importantes",
                "mainContentSubHeader": "Las actualizaciones pueden tardar unos 30 minutos en completarse",
                "mainContentText": "Se requiere un dispositivo completamente actualizado para garantizar que IT pueda proteger su dispositivo con precisión.\n\nSi no actualiza su dispositivo, es posible que pierda el acceso a algunos elementos necesarios para sus tareas diarias.\n\nPara comenzar la actualización, simplemente haga clic en el botón Actualizar dispositivo y siga los pasos proporcionados.",
                "mainHeader": "Tu dispositivo requiere una actualización de seguridad",
                "primaryQuitButtonText": "Más tarde",
                "secondaryQuitButtonText": "Entiendo",
                "subHeader": "Un recordatorio amistoso de su equipo de IT local"
            },
            {
                "_language": "fr",
                "actionButtonText": "Mettre à jour l'appareil",
                "informationButtonText": "Plus d'informations",
                "mainContentHeader": "Votre appareil redémarrera pendant cette mise à jour",
                "mainContentNote": "Notes Importantes",
                "mainContentSubHeader": "Les mises à jour peuvent prendre environ 30 minutes.",
                "mainContentText": "Un appareil entièrement à jour est nécessaire pour garantir que le service informatique puisse protéger votre appareil efficacement.\n\n Si vous ne mettez pas à jour votre appareil, vous risquez de perdre l'accès à certains outils nécessaires à vos tâches quotidiennes.\n\nPour commencer la mise à jour, cliquez simplement sur le bouton Mettre à jour le périphérique et suivez les étapes fournies.",
                "mainHeader": "Votre appareil nécessite une mise à jour de sécurité.",
                "primaryQuitButtonText": "Plus tard",
                "secondaryQuitButtonText": "Je comprends",
                "subHeader": "Un rappel amical de votre équipe informatique locale"
            },
            {
                "_language": "de",
                "actionButtonText": "Gerät aktualisieren",
                "informationButtonText": "Mehr Informationen",
                "mainContentHeader": "Ihr Gerät wird während dieses Updates neu gestartet",
                "mainContentNote": "Wichtige Hinweise",
                "mainContentSubHeader": "Aktualisierungen können ca. 30 Minuten dauern.",
                "mainContentText": "Ein vollständig aktualisiertes Gerät ist erforderlich, um sicherzustellen, dass die IT-Abteilung Ihr Gerät effektiv schützen kann.\n\nWenn Sie Ihr Gerät nicht aktualisieren, verlieren Sie möglicherweise den Zugriff auf einige Werkzeuge, die Sie für Ihre täglichen Aufgaben benötigen.\n\nUm das Update zu starten, klicken Sie auf die Schaltfläche Gerät aktualisieren und befolgen Sie die angegebenen Schritte.",
                "mainHeader": "Ihr Gerät benötigt ein Sicherheitsupdate",
                "primaryQuitButtonText": "Später",
                "secondaryQuitButtonText": "Ich verstehe",
                "subHeader": "Eine freundliche Erinnerung von Ihrem IT-Team"
            }
        ]
    }
}

 

You may copy the above for the optional languages and feature functions for Nudge and paste into a text editor, such as Atom, Notepad ++, etc. This is the example tester JSON file from the example assets page. To configure, please note lines 22 and 23. These need to be modified based on your desired:

  • requiredInstallationDate: 2023-05-30T04:00:00Z, May, 30 2023 at 12:00AM EST

  • requiredMinimumVersion: 13.3.1, i.e. macOS 13.3.1 (Ventura)

Deployment

Once you have the Install Nudge Fileset and .mobileconifg profile uploaded into FileWave Admin, you are ready for deployment. As always, grab a few macOS devices and assign them for testing. This will confirm the installation and settings are properly configured for your production environment. After testing has been completed, you are ready for mass deployment.

Nudge Filesets.png

For the JSON file you will move the JSON file into the /Library/Preferences folder. The LaunchAgent is looking for the domain "com.github.macadmins.Nudge.json", confirm that no misspellings are made for the default run times, every 30 minutes.

NudgeJSON.png

User End Experience

After installing both Nudge and the profile with your configurations, the end user will be prompted with a dialogue window with information regarding the update for the device. This includes:

  • Your configured Required OS Version

  • The devices' Current OS Version

  • Days Remaining To Update

  • How many Deferred Counts

  • Important Notes explaining the process and any other details.

NudgeUserEndExperience.png

Digging Deeper

Customizing Nudge to meet your needs:

With Nudge, there are many more optional features and configurations that may be applied to meet your production environment. You may review these features here: optionalFeatures · macadmins/nudge Wiki · GitHub.

Apple’s Rapid Security Responses:

Nudge has placed a feature-request to be added. For more information regarding, you may review the progress here: Add support for Rapid Security Response updates.