DDM Software Update Local Status for macOS

Once a DDM software update declaration makes it to a Sonoma Mac, it stores some information on the device that we can use.

DDM Software Update Local Status for macOS

Just in time for Christmas (and the final day of macOS Sonoma deferral), we've got some small pieces of information we can snag about how DDM updates are running locally on Macs running Sonoma. Many MDMs are already providing this information to you. Still, it could be helpful to be able to poll your enrolled Macs for it, especially if the behavior they're exhibiting doesn't match up with what you expect.

Necessary disclaimer - this has been the behavior I've observed on Macs thus far in Sonoma's lifecycle (14.2.1) and is subject to change at any time as Apple makes alterations to it.

First, let's take a look at this file:

/var/db/softwareupdate/SoftwareUpdateDDMStatePersistence.plist

The DDM software update .plist file

This .plist is created when a DDM declaration for a software update hits your Mac. The contents change pretty drastically based on whether there's an update available for your Mac or not. Here's an example of what the file looks like when no update is available:

{
    SUCorePersistedStateContentsType = SoftwareUpdateCorePersistedStateFile;
    SUCorePersistedStateCoreFields =     {
    };
    SUCorePersistedStateCoreSecureCodedObjectsFields =     {
    };
    SUCorePersistedStateCoreVersion = "2.1.0";
    SUCorePersistedStatePolicyFields =     {
        Declarations =         {
        };
    };
    SUCorePersistedStatePolicySecureCodedObjectsFields =     {
    };
    SUCorePersistedStatePolicyVersion = "1.0";
}

Example when no software update is available

You can see we have a lot of empty keys, some policy versioning information, and not a lot else. When an update declaration has been sent to your Mac, however, the file lights up:

{
    SUCorePersistedStateContentsType = SoftwareUpdateCorePersistedStateFile;
    SUCorePersistedStateCoreFields =     {
    };
    SUCorePersistedStateCoreSecureCodedObjectsFields =     {
    };
    SUCorePersistedStateCoreVersion = "2.1.0";
    SUCorePersistedStatePolicyFields =     {
        Declarations =         {
            "com.apple.RemoteManagement.SoftwareUpdateExtension/ABCDEFG123-1234-ABCD-5678-A1B2C3D4E5:abcdeFghiJKLMNOpqrstUVwxyz1234567890.abcdeFghiJKLMNOpqrstUVwxyz1234567890=" =             {
                RMStoreDeclarationKey = "com.apple.RemoteManagement.SoftwareUpdateExtension/ABCDEFG123-1234-ABCD-5678-A1B2C3D4E5:abcdeFghiJKLMNOpqrstUVwxyz1234567890.abcdeFghiJKLMNOpqrstUVwxyz1234567890=";
                TargetLocalDateTime = "2023-11-14T00:00:00";
                TargetOSVersion = "14.1.1";
            };
        };
    };
    SUCorePersistedStatePolicySecureCodedObjectsFields =     {
    };
    SUCorePersistedStatePolicyVersion = "1.0";
}

Example when an update is scoped (note the declaration key values have been redacted)

You can see we now have some declarations to work with. Most important, though, check out these two lines - this is what we're looking for:

TargetLocalDateTime = "2023-11-14T00:00:00";
TargetOSVersion = "14.1.1";

Keys for due date and macOS version

By scraping this file, you can verify that a software update declaration made it to the device and pull these two variables to use in your scripts and reporting. You can use these for things like smart groups, user-facing scripts that can create intelligent alerts mentioning the due date or target version, and also to identify Macs that haven't received the DDM declaration yet when they really should have.

First, here's a one-liner to retrieve the DDM SWU due date:

defaults read /var/db/softwareupdate/SoftwareUpdateDDMStatePersistence.plist | grep TargetLocalDateTime | awk -F "\"" '/1/ {print $2}' | sed 's/T/, /'

# Sample output: 2023-11-14, 00:00:00

Print the due date of the current DDM software update declaration

And here's one for the target OS version:

defaults read /var/db/softwareupdate/SoftwareUpdateDDMStatePersistence.plist | grep TargetOSVersion | awk -F "\"" '/1/ {print $2}'

# Sample output: 14.1.1

Print the target macOS version queued in the DDM software update declaration

Should either of these values be null, or should the keys be missing, or even the .plist itself, have your script exit. I often have it return a "-" to differentiate it from a null return (script hasn't run yet).

After the holiday, I'll be putting together an early writeup of how DDM actions are stored in /var/log/install.log. Given that file's volatility, I may not recommend relying on it too heavily, but it can be helpful to try and do things like identify when users have been notified about the impending DDM update or to find evidence of a device being force-restarted to accommodate a DDM update.

Until then, stay warm, stay safe, stay rested.