Last active
May 3, 2023 08:01
-
-
Save lazymutt/5a3e7b3631b073db5529722f857f54aa to your computer and use it in GitHub Desktop.
parses update versions, some managed by `sudo softwareupdate --background-critical`, ported from an applescript found at https://www.jamf.com/jamf-nation/discussions/19111/xprotect-status-extension-attribute
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# Copyright (c) 2019 University of Utah Student Computing Labs. ################ | |
# All Rights Reserved. | |
# | |
# Permission to use, copy, modify, and distribute this software and | |
# its documentation for any purpose and without fee is hereby granted, | |
# provided that the above copyright notice appears in all copies and | |
# that both that copyright notice and this permission notice appear | |
# in supporting documentation, and that the name of The University | |
# of Utah not be used in advertising or publicity pertaining to | |
# distribution of the software without specific, written prior | |
# permission. This software is supplied as is without expressed or | |
# implied warranties of any kind. | |
################################################################################ | |
# report_critical_update_versions.py ########################################### | |
# 07/12/19, v0.4, [email protected] | |
# | |
# works with Python 2 or 3 | |
# | |
# more of a learning experience than a useful product. | |
# ported from an applescript found here: | |
# https://www.jamf.com/jamf-nation/discussions/19111/xprotect-status-extension-attribute | |
# parses update versions, some managed by `sudo softwareupdate --background-critical` | |
# | |
################################################################################ | |
from __future__ import print_function | |
import datetime | |
import os | |
import subprocess | |
import sys | |
def main(): | |
# format for update description: | |
# update title, file for date calculation, file for version discovery, version command to use | |
py2 = False | |
py3 = False | |
if sys.version_info[0] == 2: | |
py2 = True | |
elif sys.version_info[0] == 3: | |
py3 = True | |
updates = [ | |
["XProtect", "/System/Library/CoreServices/XProtect.bundle/Contents/Resources/XProtect.meta.plist", "/System/Library/CoreServices/XProtect.bundle/Contents/Resources/XProtect.meta.plist", "Version"], | |
["Gatekeeper", "/private/var/db/gkopaque.bundle/Contents/version.plist", "/private/var/db/gkopaque.bundle/Contents/version.plist", "CFBundleShortVersionString"], | |
["SIP", "/System/Library/Sandbox/Compatibility.bundle/Contents/version.plist", "/System/Library/Sandbox/Compatibility.bundle/Contents/version.plist", "CFBundleShortVersionString"], | |
["MRT", "/System/Library/CoreServices/MRT.app/Contents/version.plist", "/System/Library/CoreServices/MRT.app/Contents/version", "CFBundleShortVersionString"], | |
["Core Suggestions", "/System/Library/Intelligent Suggestions/Assets.suggestionsassets/Contents/version.plist", "/System/Library/Intelligent Suggestions/Assets.suggestionsassets/Contents/version.plist", "CFBundleShortVersionString"], | |
["Incompatible Kernel Ext.", "/System/Library/Extensions/AppleKextExcludeList.kext/Contents/version.plist", "/System/Library/Extensions/AppleKextExcludeList.kext/Contents/version", "CFBundleShortVersionString"], | |
["Chinese Word List", "/usr/share/mecabra/updates/com.apple.inputmethod.SCIM.bundle/Contents/version.plist", "/usr/share/mecabra/updates/com.apple.inputmethod.SCIM.bundle/Contents/info", "SUVersionString"], | |
["Core LSKD (dkrl)", "/usr/share/kdrl.bundle/info.plist", "/usr/share/kdrl.bundle/info", "CFBundleVersion"] | |
] | |
print("-" * 50) | |
print("| {:<24} | {} | {:>6}|".format("Name", "Dated", "Version")) | |
for _, data in enumerate(updates): | |
print("|" + "-" * 26 + "+" + "-" * 12 + "+" + "-" * 8 + "|") | |
version_number = "" | |
try: | |
mod_time = datetime.datetime.fromtimestamp(os.path.getmtime(data[1])) | |
formatted_modtime = mod_time.strftime('%Y.%m.%d') | |
try: | |
version_string = subprocess.check_output(["defaults", "read", data[2], data[3]]) | |
if py2: | |
version_number = version_string.strip() | |
if py3: | |
version_number = str(version_string.strip(), 'utf-8') | |
except Exception as this_exception: | |
print(this_exception) | |
print("| {:<24} | {} | {:>6} |".format(data[0], formatted_modtime, version_number)) | |
except OSError: | |
formatted_modtime = "Deprecated/missing." | |
print("| {:<24} | {} |".format(data[0], formatted_modtime)) | |
print("-" * 50) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Sample output of new release: