Why macOS 26 build numbers begin with 25

A question I’ve seen pop up in the Mac Admins Slack since the release of macOS Tahoe 26.x goes something like this:

Why does macOS 26 have a build number that starts with 25?

The answer has to do with Darwin, the core operating system that is the foundation for all of the following Apple operating systems:

For more details, please see below the jump.

The Darwin operating system has its own version number which is separate from the version number of the other Apple operating systems. In the case of macOS, Apple includes Darwin’s version number in the macOS build number. For example, the build number for macOS Tahoe 26.2.0 is the following:

25C56

The 25 part refers to the major version number for the current Darwin release. Beginning in 2011, the major version numbers of the Darwin operating system have coincided with the last two digits of the year it was released:



Darwin Version Release Date
11.0.0 July 20 2011
12.0.0 February 16 2012
13.0.0 June 11 2013
14.0.0 September 18 2014
15.0.0 September 16 2015
16.0.0 September 13 2016
17.0.0 September 19 2017
18.0.0 September 24 2018
19.0.0 September 19 2019
20.0.0 June 22 2020
21.0.0 June 7 2021
22.0.0 June 6 2022
23.0.0 September 18 2023
24.0.0 September 16 2024
25.0.0 September 15 2025

The current Darwin operating system release is 25.2.0 as of macOS Tahoe 26.2.0, so macOS Tahoe build numbers start with 25. Unless Apple decides to change Darwin’s version numbering system, this will mean that future macOS releases will continue to have build numbers that will start with a two digit number that is one number less than the macOS major version number.

Using printf to write variable values to JSON strings in Bash scripts

As part of my personal changeover from using the Jamf Pro Classic API to using the Jamf Pro API, I’ve needed to change from using XML for the Jamf Pro Classic API to now using JSON for the Jamf Pro API. In particular, one of my issues has been figuring out how to properly write variables to JSON when updating something on the Jamf Pro server using the Jamf Pro API. As always when writing scripts, there’s usually multiple ways to solve a problem and I figured out a solution to mine using the printf command. For more details, please see below the jump.

As an example, I had written a post a while back about updating the asset tag number of a Jamf Pro computer inventory record using a script. As part of that script, I was using a command similar to the one below to send the updated asset tag information to the Jamf Pro server, defined in a variable named asset_tag_number_goes_here.


/usr/bin/curl -s –header "Authorization: Bearer api_token_goes_here" "https://jamf.pro.server.here/JSSResource/computers/serialnumber/serial_number_goes_here&quot; -H "Content-Type: application/xml" -X PUT -d "<computer><general><asset_tag>${asset_tag_number_goes_here}</asset_tag></general></computer>"

view raw

gistfile1.txt

hosted with ❤ by GitHub

As part of that command, the following XML string is being sent with the asset_tag_number_goes_here variable being included:


"<computer><general><asset_tag>${asset_tag_number_goes_here}</asset_tag></general></computer>"

view raw

gistfile1.txt

hosted with ❤ by GitHub

The XML string is double quoted, so my script knows to read in the value from the asset_tag_number_goes_here variable because the variable is referenced using the $ character.

When I updated my script to use the Jamf Pro API and JSON, my command now looked similar to this:


/usr/bin/curl -s –header "Authorization: Bearer api_token_goes_here" "https://jamf.pro.server.here/api/v3/computers-inventory-detail/jamf_pro_id_goes_here&quot; -H "Content-Type: application/xml" -X PATCH -d '{"general":{"assetTag":"$asset_tag_number_goes_here"}}'

view raw

gistfile1.txt

hosted with ❤ by GitHub

My JSON string looked like this:


'{"general":{"assetTag":"${asset_tag_number_goes_here}"}}'

view raw

gistfile1.txt

hosted with ❤ by GitHub

However, that didn’t work right and the asset_tag_number_goes_here variable’s value wasn’t being read correctly. Why? Because the JSON string uses single quotes to enclose it and in Bash, enclosing characters in single quotes means every character is being sent exactly as it is written.

How to fix this? The printf command was my eventual solution to the problem because in Bash, you can use printf to write a variable using what’s known as a format specifier. In this case, I needed to use the s format specifier because that will allow a string of characters to be used. To call the s format specifier for printf, %s% should be used.

To set it up, I needed to do the following in my script:

  1. Create the JSON string with %s% in place of ${asset_tag_number_goes_here} and store that JSON string as a variable.
  2. Use printf in a separate variable to create the JSON string and use the s format specifier to substitute the %s  with the value of the asset_tag_number_goes_here variable in the correct place inside the JSON string.
  3. Send the API command and include the JSON string created by printf.

The end result looks similar to this:


# Format a block of JSON and use %s to specify where printf should print a specified variable.
JSONBlockFormat='{"general":{"assetTag":"%s"}}'
# Use printf to create the needed JSON block and write the asset_tag_number_goes_here variable in the correct place in the JSON block.
JSONBlock=$(printf "$JSONBlockFormat" "$asset_tag_number_goes_here")
# Send an API command to update the computer inventory record with the specified asset tag information
/usr/bin/curl -s –header "Authorization: Bearer api_token_goes_here" "https://jamf.pro.server.here/api/v3/computers-inventory-detail/jamf_pro_id_goes_here&quot; -H "Content-Type: application/xml" -X PATCH -d "$JSONBlock"

view raw

gistfile1.txt

hosted with ❤ by GitHub

Reading DDM-managed Apple Software Update settings from the command line on macOS Tahoe 26.2.0

One of the challenges with reporting on DDM settings is that as of macOS Tahoe 26.2.0 there aren’t currently command line tools available which can report back on settings which are managed via DDM declarations. You can see the settings which have been applied on the managed Mac via System Settings, but so far that’s about it. However, in some cases, Apple is writing information for some DDM declarations to files which are readable by command line tools. I recently discovered that one of those declarations was the com.apple.configuration.softwareupdate.settings Software Update Settings declaration. For more details, please see below the jump.

I have an earlier post on the Software Update Settings declaration and how it is used by Jamf Pro’s Blueprints. Using that information, I built and deployed a Software Update Settings declaration which has the following settings:

  • Standard users can’t install Apple software updates
  • Logged-in users will see all software update notifications
  • OS updates will be automatically downloaded
  • OS updates will be automatically installed
  • Security updates will be automatically installed
  • Rapid Security Response updates will be installed
  • Rapid Security Response updates can be removed

Once deployed to managed Macs, you should be able to verify these settings by looking at the Software Update Settings declaration’s listing in System Settings.

You can also verify them by checking the following file:

/var/db/softwareupdate/SoftwareUpdateDDMStatePersistence.plist

On a managed Mac with those DDM settings running macOS Tahoe 26.2.0, the SoftwareUpdateDDMStatePersistence.plist file should show information similar to what’s shown below:


<?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"&gt;
<plist version="1.0">
<dict>
<key>SUCorePersistedStateContentsType</key>
<string>SoftwareUpdateCorePersistedStateFile</string>
<key>SUCorePersistedStateCoreFields</key>
<dict/>
<key>SUCorePersistedStateCoreSecureCodedObjectsFields</key>
<dict/>
<key>SUCorePersistedStateCoreVersion</key>
<string>2.1.0</string>
<key>SUCorePersistedStatePolicyFields</key>
<dict>
<key>SUCoreDDMDeclarationGlobalSettings</key>
<dict>
<key>adminInstallRequired</key>
<integer>1</integer>
<key>automaticallyDownload</key>
<integer>1</integer>
<key>automaticallyInstallOSUpdates</key>
<integer>1</integer>
<key>automaticallyInstallSystemAndSecurityUpdates</key>
<integer>1</integer>
<key>enableGlobalNotifications</key>
<true/>
<key>enableRapidSecurityResponse</key>
<true/>
<key>enableRapidSecurityResponseRollback</key>
<true/>
<key>serializedKeys</key>
<array>
<string>com.apple.RemoteManagement.SoftwareUpdateExtension.GlobalSettings/811362F1-10F1-4D2F-BFB7-F97393F3F44C:Qmx1ZXByaW50XzM3MTllZWRlLTI0MjUtNGE2ZC04YjljLTIyMGViMzMwYWQ2NF9zMV9jMV9zeXNfY2ZnMQ==.NDg5NTdiNjZkYmUwMWM3YzM2MzcwMTJjNTkxZTg4MWM1ZDk3YTNkMWUxZTI1MjI0NTYwMmJlNjQ0MTFmYjdkOA==</string>
</array>
</dict>
</dict>
<key>SUCorePersistedStatePolicySecureCodedObjectsFields</key>
<dict/>
<key>SUCorePersistedStatePolicyVersion</key>
<string>1.0</string>
</dict>
</plist>

From there, you can use tools like PlistBuddy to read the values stored in the /var/db/softwareupdate/SoftwareUpdateDDMStatePersistence.plist file. For example, the following command should read the value for the enableRapidSecurityResponse key from the SoftwareUpdateDDMStatePersistence.plist file.


/usr/libexec/PlistBuddy -c "Print :SUCorePersistedStatePolicyFields:SUCoreDDMDeclarationGlobalSettings:enableRapidSecurityResponse" /var/db/softwareupdate/SoftwareUpdateDDMStatePersistence.plist

view raw

gistfile1.txt

hosted with ❤ by GitHub

If Rapid Security Response updates are set to be installed, that should give you a value of true:


username@Z6WCW076MR ~ % /usr/libexec/PlistBuddy -c "Print :SUCorePersistedStatePolicyFields:SUCoreDDMDeclarationGlobalSettings:enableRapidSecurityResponse" /var/db/softwareupdate/SoftwareUpdateDDMStatePersistence.plist
true
username@Z6WCW076MR ~ %

view raw

gistfile1.txt

hosted with ❤ by GitHub

To the best of my knowledge, this method of verification is undocumented by Apple and they could choose to change it at any time. That said, if you’re looking for a way to report on Software Update Settings declaration settings, this is a way to do it as of macOS Tahoe 26.2.0.

PPPC device management settings visible in System Settings on macOS Tahoe 26.2.0

As part of the What’s new for enterprise in macOS Tahoe 26 release notes for macOS Tahoe 26.2.0, there’s this note:

App privacy permissions configured by device management are now shown in System Settings > Privacy & Security.

What this indicates is that a long-standing feature request by Mac admins has been fulfilled by Apple. For more details, please see below the jump.

As part of macOS 10.14 Mojave, Apple introduced a number of privacy controls for user data. At the same time, Apple also introduced device management options to allow authorized applications to access data protected by those privacy controls. These permissions are referred to collectively as Privacy Preferences Policy Control (PPPC) and are deployed via management profiles from an MDM server. However, up until macOS Tahoe 26.2, there was no way to see in the Privacy & Security section of System Settings which applications had which permissions granted via PPPC management profiles.

As an example, by default, Macs managed by Jamf Pro will get a management profile which allows the Jamf agent permission to access data stored in the user home folder via the PPPC permission known as full disk access. Here’s how this looks on macOS Tahoe 26.1.0:

Privacy Preferences Policy Control profile installed which enables full disk access to the Jamf agent.

No mention of the full disk access permissions granted to the Jamf agent in the Privacy & Security section of System Settings.

How this looks on macOS Tahoe 26.2.0:

Privacy Preferences Policy Control profile installed which enables full disk access for the Jamf agent.

Full disk access permissions granted to the Jamf agent are disclosed in the Privacy & Security section of System Settings. It is also disclosed that the permissions setting is configured by a profile.

Updating management status in Jamf Pro computer inventory records using the Jamf Pro API

A while back, I wrote a post on how to set Jamf Pro computer inventory records to be managed using a script. I recently revisited this script as part of a general effort on my part to update scripts which have been using the now-deprecated computers Classic API endpoint, to now use the Jamf Pro API’s computers-inventory-detail API endpoint.

As part of this effort, I decided to not only update my existing script for setting the management status in Jamf Pro computer inventory records to be managed but also write a second script for setting the management status to be unmanaged. For more details, please see below the jump.

You can set the management status in a Jamf Pro computer inventory record using the computers-inventory-detail endpoint for the Jamf Pro API. The API command to change the management status in a Jamf Pro computer inventory record to Managed should look similar to this:


/usr/bin/curl -H "Content-Type: application/json" "https://jamf.pro.server.here/api/v3/computers-inventory-detail/jamf_pro_computer_ID_goes_here&quot; –header "Authorization: Bearer api_token_goes_here" -X PATCH -d '{"general":{"managed":"true"}}'

view raw

gistfile1.txt

hosted with ❤ by GitHub

It’s sending the following JSON block to update the relevant computer inventory record and make the management change:


{
"general": {
"managed": "true"
}
}

view raw

gistfile1.txt

hosted with ❤ by GitHub

The API command to change the management status in a Jamf Pro computer inventory record to Not Managed should look similar to this:


/usr/bin/curl -H "Content-Type: application/json" "https://jamf.pro.server.here/api/v3/computers-inventory-detail/jamf_pro_computer_ID_goes_here&quot; –header "Authorization: Bearer api_token_goes_here" -X PATCH -d '{"general":{"managed":"false"}}'

view raw

gistfile1.txt

hosted with ❤ by GitHub

It’s sending the following JSON block to update the relevant computer inventory record and make the management change:


{
"general": {
"managed": "false"
}
}

view raw

gistfile1.txt

hosted with ❤ by GitHub

I was able to use the API information discussed above to create a couple of scripts which a) update the management status in specified computer inventory records and b) generates a report of the Macs whose computer inventory records were updated.

The scripts are named Set_Jamf_Pro_Computers_To_Managed_Status.sh and Set_Jamf_Pro_Computers_To_Unmanaged_Status.sh and are available via the links below:

https://github.com/rtrouton/rtrouton_scripts/tree/main/rtrouton_scripts/Casper_Scripts/Set_Jamf_Pro_Computers_To_Managed
https://github.com/rtrouton/rtrouton_scripts/tree/main/rtrouton_scripts/Casper_Scripts/Set_Jamf_Pro_Computers_To_Unmanaged

Both scripts are designed to take in a set of Jamf Pro ID numbers in a plaintext file, where the Jamf Pro ID numbers correspond the Macs where you want to change the management status in their Jamf Pro computer inventory records. The plaintext file should look similar to this:


416462
842736
434703
338517
481915
596669

view raw

gistfile1.txt

hosted with ❤ by GitHub

Four items are required to use these scripts:

  • A text file containing the Jamf Pro IDs of the computer(s) you wish to delete.
  • The URL of the appropriate Jamf Pro server.
  • The username of an account on the Jamf Pro server with sufficient privileges to delete computers from the Jamf Pro server.
  • The password for the relevant account on the Jamf Pro server.
  • Jamf Pro account privileges required by the Jamf Pro server account referenced above:

Jamf Pro Server Objects:

  • Computers: Read, Update
  • Users: Update

Once the four specified items are available, the scripts can be run using the following commands:

For Set_Jamf_Pro_Computers_To_Managed_Status.sh:


/path/to/Set_Jamf_Pro_Computers_To_Managed_Status.sh /path/to/plaintext_filename_here.txt

view raw

gistfile1.txt

hosted with ❤ by GitHub

For Set_Jamf_Pro_Computers_To_Unmanaged_Status.sh:


/path/to/Set_Jamf_Pro_Computers_To_Unmanaged_Status.sh /path/to/plaintext_filename_here.txt

view raw

gistfile1.txt

hosted with ❤ by GitHub

For Set_Jamf_Pro_Computers_To_Managed_Status.sh, you should see output that looks like this:


username@computername ~ % /Users/Shared/Set_Jamf_Pro_Computers_To_Managed/Set_Jamf_Pro_Computers_To_Managed_Status.sh /Users/Shared/jamfpro_computer_ids.txt
Please enter your Jamf Pro server URL : https://jamf.pro.server.here
Please enter your Jamf Pro user account : username_goes_here
Please enter the password for the username_goes_here account:
Report being generated. File location will appear below once ready.
Updated management status in the computer inventory record for https://jamf.pro.server.here/computers.html?id=416462 from unmanaged to managed.
Updated management status in the computer inventory record for https://jamf.pro.server.here/computers.html?id=842736 from unmanaged to managed.
Updated management status in the computer inventory record for https://jamf.pro.server.here/computers.html?id=434703 from unmanaged to managed.
Updated management status in the computer inventory record for https://jamf.pro.server.here/computers.html?id=338517 from unmanaged to managed.
Updated management status in the computer inventory record for https://jamf.pro.server.here/computers.html?id=481915 from unmanaged to managed.
Updated management status in the computer inventory record for https://jamf.pro.server.here/computers.html?id=596669 from unmanaged to managed.
Report on Macs available here: /var/folders/ps/2_yw29gj711c9d7c5w5jhyv80000gp/T/tmp.eFStgTqa5l.tsv
username@computername ~ %

view raw

gistfile1.txt

hosted with ❤ by GitHub

As part of the script’s run, a report will be generated and you’ll be notified of where it is stored. The report will be in TSV format and appear similar to what’s shown below:



Jamf Pro ID Number Make Model Serial Number UDID Computer Management Status Jamf Pro URL
416462 Apple MacBook Pro (16-inch, 2019) WD8JB8F49YS4 4D8CD419-1892-4CFE-8D18-D1DD53CC7970 Managed https://jamf.pro.server.here/computers.html?id=416462
842736 Apple MacBook Pro (16-inch, 2019) R6JG7GYVNORW 904418F7-3695-44BF-9A00-74F5CF617377 Managed https://jamf.pro.server.here/computers.html?id=842736
434703 Apple MacBook Pro (16-inch, 2019) FWPATJHWC92O 5CF418CE-3E46-481C-A171-7ACC9E1E2E7A Managed https://jamf.pro.server.here/computers.html?id=434703
338517 Apple MacBook Pro (16-inch, 2019) CVZVJ8R55467 E82C6C63-5F49-4DD3-90A0-E01EC11F6954 Managed https://jamf.pro.server.here/computers.html?id=338517
481915 Apple MacBook Pro (13-inch, M1, 2020) QL6ROPPB1SK5 CBC87B4C-28DA-417F-8790-411AF9F105AD Managed https://jamf.pro.server.here/computers.html?id=481915
596669 Apple MacBook Pro (16-inch, 2021) CNA11CBMJSNI 72811617-8C97-4EB6-BC4B-B9FA9C87B259 Managed https://jamf.pro.server.here/computers.html?id=596669

For Set_Jamf_Pro_Computers_To_Unmanaged_Status.sh, you should see output that looks like this:


username@computername ~ % /Users/Shared/Set_Jamf_Pro_Computers_To_Unmanaged/Set_Jamf_Pro_Computers_To_Unmanaged_Status.sh /Users/Shared/jamfpro_computer_ids.txt
Please enter your Jamf Pro server URL : https://jamf.pro.server.here
Please enter your Jamf Pro user account : username_goes_here
Please enter the password for the username_goes_here account:
Report being generated. File location will appear below once ready.
Updated management status in the computer inventory record for https://jamf.pro.server.here/computers.html?id=416462 from managed to unmanaged.
Updated management status in the computer inventory record for https://jamf.pro.server.here/computers.html?id=842736 from managed to unmanaged.
Updated management status in the computer inventory record for https://jamf.pro.server.here/computers.html?id=434703 from managed to unmanaged.
Updated management status in the computer inventory record for https://jamf.pro.server.here/computers.html?id=338517 from managed to unmanaged.
Updated management status in the computer inventory record for https://jamf.pro.server.here/computers.html?id=481915 from managed to unmanaged.
Updated management status in the computer inventory record for https://jamf.pro.server.here/computers.html?id=596669 from managed to unmanaged.
Report on Macs available here: /var/folders/ps/2_yw29gj711c9d7c5w5jhyv80000gp/T/tmp.6Ic4bx2sT8.tsv
username@computername ~ %

view raw

gistfile1.txt

hosted with ❤ by GitHub

As part of the script’s run, a report will be generated and you’ll be notified of where it is stored. The report will be in TSV format and appear similar to what’s shown below:



Jamf Pro ID Number Make Model Serial Number UDID Computer Management Status Jamf Pro URL
416462 Apple MacBook Pro (16-inch, 2019) WD8JB8F49YS4 4D8CD419-1892-4CFE-8D18-D1DD53CC7970 Unmanaged https://jamf.pro.server.here/computers.html?id=416462
842736 Apple MacBook Pro (16-inch, 2019) R6JG7GYVNORW 904418F7-3695-44BF-9A00-74F5CF617377 Unmanaged https://jamf.pro.server.here/computers.html?id=842736
434703 Apple MacBook Pro (16-inch, 2019) FWPATJHWC92O 5CF418CE-3E46-481C-A171-7ACC9E1E2E7A Unmanaged https://jamf.pro.server.here/computers.html?id=434703
338517 Apple MacBook Pro (16-inch, 2019) CVZVJ8R55467 E82C6C63-5F49-4DD3-90A0-E01EC11F6954 Unmanaged https://jamf.pro.server.here/computers.html?id=338517
481915 Apple MacBook Pro (13-inch, M1, 2020) QL6ROPPB1SK5 CBC87B4C-28DA-417F-8790-411AF9F105AD Unmanaged https://jamf.pro.server.here/computers.html?id=481915
596669 Apple MacBook Pro (16-inch, 2021) CNA11CBMJSNI 72811617-8C97-4EB6-BC4B-B9FA9C87B259 Unmanaged https://jamf.pro.server.here/computers.html?id=596669

In addition to the scripts described above which use user accounts for authentication, there are also matching scripts which use API client authentication available on GitHub via the links above. If setting up an API client with limited rights, here are the required API role privileges for the API client on the Jamf Pro server:

  • Computers Read
  • Computers Update
  • Users Update

New application version smart group and advanced computer search criteria available as of Jamf Pro 11.23.0

In macOS, applications record version information in the Information Property List file. This file is stored inside the Contents directory of the application bundle and is named Info.plist.

There are two keys inside the Info.plist file for an application which store version information:

What’s the difference between the two?

  • CFBundleVersion: This is the version information used by macOS to determine which version is the most recent version of an application.
  • CFBundleShortVersionString: This is the version information which is displayed to the user in a Finder window or a Get Info window.

There is no requirement in macOS that both the CFBundleVersion and CFBundleShortVersionString keys in the Info.plist file contain the same version information. What can happen as a result? Let’s take a look at that the context of some Microsoft applications which record different information in the Info.plist file for those two keys. For more details, please see below the jump.

For this example, I installed the following Microsoft apps on a macOS 26.1.0 VM:

  • Microsoft Excel.app
  • Microsoft PowerPoint.app
  • Microsoft OneNote.app
  • Microsoft Outlook.app
  • Microsoft Word.app
  • OneDrive.app
  • Windows App.app

For each app, I checked the following:

  • CFBundleShortVersionString
  • CFBundleVersion
  • Reported version on the Mac

Microsoft Excel.app

  • CFBundleShortVersionString: 16.103.3
  • CFBundleVersion: 16.103.25113013
  • Reported version on the Mac: 16.103.3

Microsoft PowerPoint.app

  • CFBundleShortVersionString: 16.103.3
  • CFBundleVersion: 16.103.25113013
  • Reported version on the Mac: 16.103.3

Microsoft OneNote.app

  • CFBundleShortVersionString: 16.103.3
  • CFBundleVersion: 16.103.25113013
  • Reported version on the Mac: 16.103.3

Microsoft Outlook.app

  • CFBundleShortVersionString: 16.103.3
  • CFBundleVersion: 16.103.25113013
  • Reported version on the Mac: 16.103.3

Microsoft Word.app

  • CFBundleShortVersionString: 16.103.3
  • CFBundleVersion: 16.103.25113013
  • Reported version on the Mac: 16.103.3

OneDrive.app

  • CFBundleShortVersionString: 25.209.1026
  • CFBundleVersion: 25209.1026.0002
  • Reported version on the Mac: 25.209.1026

Windows App.app

  • CFBundleShortVersionString: 11.2.9
  • CFBundleVersion: 2810
  • Reported version on the Mac: 11.2.9

As you can observe, what’s reported in these two fields can be very different. How does this affect Jamf Pro? Up until Jamf Pro 11.23.0, only one of those keys in the Info.plist file was being used to get version information for a macOS application:

CFBundleShortVersionString

This was reported as part of a computer inventory record as the following field:

  • Version

The Version reporting also has matching smart group and advanced computer search criteria:

  • Application Version

However, version information for Microsoft applications in particular were often being reported in Jamf Pro using the information contained in the following key:

  • CFBundleVersion

If CFBundleVersion and CFBundleShortVersionString did not have the same version information, now you have a problem because what you see in Jamf Pro for version information for that Microsoft app and what you’re seeing reported in a Finder window for version infomation are two different things. To help address this, as of Jamf Pro 11.23 two new reporting fields as well as matching smart group and advanced computer search criteria have been added:

  • Bundle Short Version
  • Bundle Version

Here’s how they’re mapping to the keys in the application’s Info.plist file:

  • Bundle Short Version: CFBundleShortVersionString
  • Bundle Version: CFBundleVersion

The existing Version reporting field and matching Application Version smart group and advanced computer search criteria have not gone away, since up until Jamf Pro 11.23 it was your only option. The new reporting information has been added and does not replace previously gathered data, so nothing in anyone’s existing version reporting setup should break.

Here’s how it should look as of Jamf Pro 11.23.0 for a computer inventory record’s application listing:

  • Name
  • Version
  • Bundle Short Version
  • Bundle Version
  • Path
  • App Store

Note: The Bundle Short Version and Bundle Version fields may initially be blank for devices which have not sent in an inventory update since Jamf Pro was upgraded to 11.23.

The matching smart group and advanced computer search criteria are as follows:

  • Applications inventory listing: Bundle Short Version
  • Smart and advanced computer search criteria: Application Bundle Short Version

  • Applications inventory listing: Bundle Version
  • Smart and advanced computer search criteria: Application Bundle Version

Suppressing the Welcome to macOS Tahoe 26 screen with a configuration profile on macOS Tahoe 26.1.0

Over the years, Apple has introduced a number of screens which appear the first time you log into a Mac. Among those which appear following an upgrade to macOS Tahoe 26 is the Welcome to macOS Tahoe 26 screen, which provides a walkthrough of selected new features available in macOS Tahoe.

I have not found a way to suppress this screen using a defaults command, but it is possible to suppress the Welcome to macOS Tahoe 26 screen on macOS Tahoe 26.1.0 using a configuration profile. For more details, please see below the jump.

The relevant preference domain and key values are below:

  • Preference domain: com.apple.SetupAssistant.managed
  • Key: SkipSetupItems
  • Value: OSShowcase

The profile is available on GitHub via the link below:

https://github.com/rtrouton/profiles/blob/main/SkipOSShowcaseSetup

Disabling the floating thumbnail preview for screenshots on macOS Tahoe

One of the features available when taking screenshots is the option to see a floating thumbnail preview of the screenshot before it gets saved to the location you’ve chosen to save screenshots to. This option is enabled by default and looks like this on macOS Tahoe.

  1. Screenshot is taken.
  2. Floating thumbnail preview appears and slides off-screen.
  3. Screenshot file icon appears (in this example, screenshots are being saved to the desktop.)

I prefer to have this option turned off, as I’d rather have the ability to select and work with the screenshot file right away in place of waiting for the floating thumbnail to appear and disappear.

Fortunately, this option can be turned off in a couple of ways. The first is through using Screenshot.app, which is included with macOS.

When you use Screenshot.app, it will provide a toolbar for selecting screenshot image or screencapture movie options. As part of that toolbar, there is an Options button.

When you click the Options button, you get a menu where one of the selections is Show Floating Thumbnail. If you unselect that, the floating thumbnail preview no longer appears when taking screenshots or making screencapture movies.

You can also disable this from the command line, by running the two following commands in Terminal:


/usr/bin/defaults write com.apple.screencapture show-thumbnail -bool false
killall SystemUIServer

view raw

gistfile1.txt

hosted with ❤ by GitHub

In my case, I wanted to disable the floating thumbnail preview on my Macs so I’ve written a profile which can enforce this. It’s available via the link below:

https://github.com/rtrouton/profiles/blob/main/DisableScreenshotFloatingThumbnail

Deploying custom DDM declarations using Blueprints in Jamf Pro

One of the management options Jamf Pro provides with Blueprints is the ability to create and deploy custom declarative declarations to managed Macs. What this means that if you can manually build the JSON payload for a DDM declaration, you should now be able to deploy it using Blueprints even if Jamf does not have a Blueprint template available yet for that declaration. This is conceptually similar to Jamf Pro’s ability to deploy custom configurations in management profiles to macOS using the Application & Custom Settings management profile payload

For more details, please see below the jump.

For this example, I am using the following custom declaration to set disk management settings. Blueprints also has a declaration template for disk management, but using a custom declaration to deploy disk management settings allows the use of an example where that declaration is all in one JSON payload and doesn’t need to refer to other components (an example of a declaration which needs to refer to other components is a service configuration declaration deploying a sudo configuration, where files need to be downloaded from an external source.)


{
"Restrictions": {
"ExternalStorage": "Disallowed",
"NetworkStorage": "Disallowed"
}
}

In this case, the declaration is setting the following disk management settings:

  • External storage devices are disallowed: the system can’t mount any external storage.
  • Network storage is disallowed: the system can’t mount any storage from a network server.

As of Jamf Pro 11.22.1, there is not a Blueprints template available for creating blueprints which deploy custom declarations so the blueprint will need to be configured manually. To do this, use the following procedure:

1. Log into Jamf Pro.

2. Select Blueprints

3. Click the Create blueprint button.

4. You should see an unconfigured Blueprint. Click where it says Untitled blueprint and provide a name.

For this example, I’m using Disk Management Settings.

5. Scroll down in the list on the left-hand side of the browser window to locate the Custom Declarations component.

6. Click on the Custom Declarations component and drag the Custom Declarations component to the Declaration group section.

Drag custom declarations component.

7. Once added to the Declaration group section, click anywhere on the Custom Declarations component to open it for editing.

When the Custom Declarations component opens for editing, there is an explanation about custom configurations and a warning that using custom configurations can come with risks and to carefully test all configurations built using the Custom Declarations component before deploying them in a production environment.

8. Once you’ve read through the warnings and understand the potential risks, click the Get Started button.

9. Click the Add item button. The custom declarations settings will open and show a set of placeholder settings.

Before continuing further, if you have not already, I strongly recommend reading the Creating a Custom Declaration Blueprint documentation to understand all the parts involved in creating a custom declaration using the Custom Declarations Blueprints component.

In the Kind field of the Custom Declarations component, there are two choices:

  • Configuration
  • Asset

Configuration: Settings and policies that define how devices should be configured, functioning similarly to profile payloads.
Asset: Data used by configurations such as certificates, configuration files, scripts or other data supported for use in a DDM declaration.

For our example, we’re choosing Configuration.

In the Channel field of the Custom Declarations component, there are two choices:

  • System
  • User

System: applies management settings to the device.
User: applies management settings to the MDM-managed user or users.

For our example, we’re choosing System.

In the Type field, enter the declaration type.

For our example, we’re using the declaration type for disk management: com.apple.configuration.diskmanagement.settings

In the Payload field, enter the configuration of the declaration in JSON format. For our example, here’s the configuration we’re using:


{
"Restrictions": {
"ExternalStorage": "Disallowed",
"NetworkStorage": "Disallowed"
}
}

10. Once the Kind, Channel, Type and Payload settings have been configured and verified, click the Update button.

11. Verify that all settings look as expected, then click the Save button.

12. At this point, you should have a blueprint which has all settings configured but where no target scope has been set. To scope this blueprint, go to the Scope section and click the arrow button.

13. Select a Jamf Pro smart or static group. For this example, I’m selecting a static group named Disk Management Deployment Group.

14. Once everything has been configured, click the Deploy button to deploy the changes to the Macs you want to manage.

15. Once deployed, the Blueprints screen in Jamf Pro should show the newly-created Disk Management Settings Blueprint as being deployed.

On your managed devices, you can verify that the new custom declaration has been deployed by clicking on the enrollment profile, then scrolling to the bottom. In the case of this example, because you’re deploying a disk management configuration you should see a Device Declarations section with a listing for Disk Management.

If you click on the Disk Management listing, it should report the following:

  • External Storage Restriction: Not Allowed
  • Network Storage Restriction: Not Allowed

Granting a local user account administrator rights on a Mac which only has accounts with standard user rights

I recently saw a post on LinkedIn where the poster had apparently removed all accounts which were assigned administrator rights on the Mac from the local group named admin on macOS and then had difficulty recovering from this state.

On macOS, membership in the admin group is what grants administrator rights, so now this meant that the Mac only had accounts which had standard user rights.

There have been methods available in the past for fixing this from the Recovery environment which used the chroot command line tool in the Recovery environment to change the active filesystem from the Recovery environment to the Mac’s regular boot drive, then run the dseditgroup command line tool to re-add one or more local user accounts to the admin group on the boot drive.

However, it looks like the chroot command does not work currently in the Recovery environment available to macOS Tahoe on Apple Silicon Macs. When launched, it reports an error and then exits.

With the chroot command line tool no longer working in Recovery, that would seem to close off most avenues to re-adding users to the admin group for Apple Silicon Macs running macOS Tahoe. However, after some research, I’ve discovered an alternative method which uses the sudo command line tool. For more details, please see below the jump.

This method uses the ability on macOS for the sudo command line tool to use properly formatted configurations for the sudo tool, where those configuration files are stored as plaintext files in the /private/etc/sudoers.d directory. The following process will create a sudo configuration which is stored in a plaintext file named fixadmin which will be created from the Recovery environment and stored in the /private/etc/sudoers.d directory in the writeable part of the Mac’s boot drive.

What this configuration file will do is allow a user account which otherwise has standard user rights to run the dseditgroup command line tool with root privileges, which in turn will enable the user account to add itself (or another account) to the local group named admin using the dseditgroup command line tool. The end result of this process is that administrator rights will be granted to the account being added to the admin group.

Pre-requisites:

Once the pre-requisites are handled, use the following process to create the configuration file for the sudo command line tool:

1. Boot to the Recovery environment.
2. If required, enter the FileVault recovery key to access the Recovery environment.

3. If you needed to unlock using the FileVault recovery key, once unlocked choose the Exit to Recovery option.

4. From the Recovery window, click on Disk Utility.

5. Verify that the Data volume is mounted.

If the Data volume is not mounted, click the Mount button in Disk Utility to mount it.

If FileVault is enabled, you will need to enter the password of a FileVault-enabled account to mount the Data volume.

6. Quit out of Disk Utility.
7. Open Terminal using the Utilities menu.

8. Run the following command to create a file named fixadmin in the /Volumes/Data/private/etc/sudoers.d directory:


touch /Volumes/Data/private/etc/sudoers.d/fixadmin

view raw

gistfile1.txt

hosted with ❤ by GitHub

9. Run the following command to edit the /Volumes/Data/private/etc/sudoers.d/fixadmin file using the nano command line text editor:


/Volumes/Macintosh\ HD/usr/bin/nano /Volumes/Data/private/etc/sudoers.d/fixadmin

view raw

gistfile1.txt

hosted with ❤ by GitHub

10. Add the following line to the fixadmin file:


username_goes_here ALL = (ALL) /usr/sbin/dseditgroup

view raw

gistfile1.txt

hosted with ❤ by GitHub

This file should be formatted as follows:

A. Enter the account shortname of the user account that you want to grant rights to in order to run the dseditgroup command line tool using sudo.
B. Hit the Tab key to create a tabbed space
C. Enter the rest of the line:

ALL = (ALL) /usr/sbin/dseditgroup

For example, if the user account in question has the account shortname of username, the entry should look like this:


username ALL = (ALL) /usr/sbin/dseditgroup

view raw

gistfile1.txt

hosted with ❤ by GitHub

11. Verify that the line is formatted correctly.
12. To save changes, press the Control key and the X key together (Control + X) on your keyboard.
13. You will be prompted to save unsaved changes. When prompted, save the changes.

14. Boot back to macOS.
15. Log in as the account to which you granted rights to run the dseditgroup command line tool using sudo.
16. Open Terminal and run the following command to grant admin rights to a specified user account:


sudo dseditgroup -o edit -a username_goes_here -t user admin

view raw

gistfile1.txt

hosted with ❤ by GitHub

For example, if the user account in question has the account shortname of username, the command should look like this:


sudo dseditgroup -o edit -a username -t user admin

view raw

gistfile1.txt

hosted with ❤ by GitHub

17. Verify that the desired account now has administrator rights.

18. Remove the fixadmin file from the /private/etc/sudoers.d directory by running the following command:


sudo rm /private/etc/sudoers.d/fixadmin

view raw

gistfile1.txt

hosted with ❤ by GitHub