Posted on 04-25-2023 10:33 AM
We are attempting to build a compliance dashboard for senior leadership. One of the top compliance items is that macOS be up to date. That criterion is defined as that the endpoint must be on the latest patch and version of macOS within 30 days of release. What we need is a data source that we can poll for the most recent version of macOS and when it was released so that we can feed the logic in the dashboard.
Has anyone put together something like this, and if so, what did you use for the data source for the current version and patch level of macOS?
Solved! Go to Solution.
Posted on 04-25-2023 02:33 PM
This peaked my interests as I am tired of updating smart groups myself so I opened an enterprise ticket with Apple. Apples response was there is no way to grab this information from them. :/
Posted on 04-25-2023 11:56 AM
Honestly with this really the sky is the limit, Splunk, Service Now, whatever you use that has any from of API can grab this information from JAMF and report on it however you want. JAMF can also have Smart Groups that display numbers pinned to the dashboard if your execs happened to log in to the JAMF Console directly for some reason.
Posted on 04-25-2023 12:15 PM
Bruce is asking if anyone has a source for the data. Somewhere that can be queried so that it does not have populate that information into a local repository like Service Now.
Something that returns: OS version and release date. It would be lovey to find an automated way to get this data without having to manually keep track of it.
Posted on 04-25-2023 12:35 PM
The most direct way I could think of would be to query the AppStore with API. I am not well versed in Apples API, and I doubt they document it very well. That being said there may be a way to query Apples Update Servers directly. JAMF is doing it some how, so its possible in the very least.
Read App Store Version Information | Apple Developer Documentation
Posted on 04-25-2023 12:19 PM
Bruce and our team are already getting the information for what the current install base of our fleet is. What we are looking to set up is a way to dynamically change what version of OS is compliant as Apple releases a new version. In other words if 13.3.2 is released 13.3.1 automatically shows as non-compliant without manually adjusting the dashboard. (side note: This is a 3rd party dashboard not a Jamf dashboard)
Posted on 04-25-2023 12:31 PM
I've looked for this kind of information myself in the past but I've never found anything definitive. You'd think Apple would have a page somewhere that tracked all their OS releases and the dates, but it doesn't seem like they do.
There are plenty of other websites that have this info, but not in an easy to parse format for something like a script or API query to get. it needs to be in a db or table format for easy parsing, but as far as I can tell, nothing like this exists.
The closest thing I can find is this page, but I'm unsure how easy it would be to use it as a source - https://robservatory.com/a-full-history-of-macos-os-x-release-dates-and-rates/
Posted on 04-25-2023 02:33 PM
This peaked my interests as I am tired of updating smart groups myself so I opened an enterprise ticket with Apple. Apples response was there is no way to grab this information from them. :/
Posted on 04-25-2023 01:11 PM
The source should be JAMF Pro. Macintosh Operating Systems and Builds are natively part of JAMF Pro's Patch management. You can dynamically maintain Smart Groups marked compliant based on whatever criteria you need and can export your JAMF data to a CMDB via an API.
Posted on 04-25-2023 01:33 PM
This may be more than you are looking for but I wrote this script a few years ago that I run when I need a link to the latest update to download. I did include the date of release for the update in the output of the script. You may endeavor to tweak the script for you own personal use.
#!/bin/bash
# set -x
# This script lists the latest OS installers and
# their download links.
# Author: Andrew Thomson
# Date: 2021-04-30
IFS=$'\n'
echo "Please wait . . ."
# determine seed catalog path
if ! SEED_CATALOG="$(/usr/bin/defaults read /System/Library/PrivateFrameworks/Seeding.framework/Versions/Current/Resources/SeedCatalogs.plist CustomerSeed 2> /dev/null)"; then
echo "ERROR: Unable to determine seed catalog." >&2
exit $LINENO
fi
# download seed catalog
if ! CATALOG_XML=$(/usr/bin/curl -sfL "$SEED_CATALOG" | /usr/bin/zcat | /usr/bin/xmllint --format - 2> /dev/null); then
echo "ERROR: Unable to download specified seed catalog." >&2
exit $LINENO
fi
# get available product keys that include extended meta info and install assistant package indentifiers
PRODUCT_KEYS=($(echo $CATALOG_XML | /usr/bin/xmllint --xpath "/plist/dict[key='Products']/dict/dict[key='ExtendedMetaInfo']/dict[key='InstallAssistantPackageIdentifiers']/preceding-sibling::key[2]/parent::dict/preceding::key[1]" - 2> /dev/null | /usr/bin/awk -F'</?key>' '{for(i=2;i<=NF;i++) print $i}'))
# enumerate product keys
for KEY in "${PRODUCT_KEYS[@]}"; do
IFS=$'\n'
# get xml subset based on product key
PRODUCT_XML=$(echo $CATALOG_XML | /usr/bin/xmllint --xpath "/plist[1]/dict[1]/dict/key[.=\"$KEY\"]/following-sibling::dict[1]" - 2> /dev/null)
# get url to product distribution file
DISTRIBUTION_URL=$(echo $PRODUCT_XML | /usr/bin/xmllint --xpath "//key[.='Distributions']/following-sibling::dict/child::key[.='English']/following-sibling::string[1]/text()" - 2> /dev/null)
# get post date from product key subset xml
POST_DATE=$(/bin/date -j -f "%Y-%m-%dT%H:%M:%SZ" $(echo $PRODUCT_XML | /usr/bin/xmllint --xpath "//key[.='PostDate']/following-sibling::date[1]/text()" - 2> /dev/null) +"%Y-%m-%d")
# get title, build, and version from corresponding distribution file
IFS=',' PRODUCT_INFO=($(/usr/bin/curl -sL "$DISTRIBUTION_URL" | /usr/bin/xmllint --xpath "concat(//title/text(),',',//key[.='BUILD']/following-sibling::string[1]/text(),',',//key[.='VERSION']/following-sibling::string[1]/text())" - 2> /dev/null))
# filter for macos only titles
if echo ${PRODUCT_INFO[0]} | /usr/bin/grep -q "macOS"; then
# combine info into new products array
PRODUCTS+=($KEY,${PRODUCT_INFO[0]},${PRODUCT_INFO[1]},${PRODUCT_INFO[2]},$POST_DATE)
echo "$KEY,${PRODUCT_INFO[0]},${PRODUCT_INFO[1]},${PRODUCT_INFO[2]},$POST_DATE"
# get download path to install assistant
DOWNLOAD_PATH=$(echo $PRODUCT_XML | /usr/bin/xmllint --xpath "//key[.='URL']/following-sibling::string[contains(text(), 'InstallAssistant.pkg')]/text()" - 2> /dev/null)
echo -e "$DOWNLOAD_PATH\n"
fi
unset PRODUCT_INFO
done