Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
#!/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, todd.mcdaniel@utah.edu
#
# 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()
@lazymutt

This comment has been minimized.

Copy link
Owner Author

commented Jan 22, 2017

Sample output:

Name                     Date      Version
__________________________________________
XProtect                 2017.01.17   2087
Gatekeeper               2016.12.15    107
SIP                      2015.10.23   12.0
MRT                      2017.01.17   1.14
Core Suggestions         2017.01.03    778
Incompatible Kernel Ext. 2016.11.29 11.6.1
Chinese Word List        2016.08.24   4.22
Core LSKD (dkrl)         2014.06.24      8
@torinkwok

This comment has been minimized.

Copy link

commented May 3, 2017

Thank you Todd! Here's a Swift version written by me.

@lazymutt

This comment has been minimized.

Copy link
Owner Author

commented Jul 17, 2019

Sample output of new release:

--------------------------------------------------
| Name                     | Dated      | Version|
|--------------------------+------------+--------|
| XProtect                 | 2019.04.26 |   2103 |
|--------------------------+------------+--------|
| Gatekeeper               | 2019.07.12 |    172 |
|--------------------------+------------+--------|
| SIP                      | 2019.02.22 |   15.0 |
|--------------------------+------------+--------|
| MRT                      | 2019.07.15 |   1.46 |
|--------------------------+------------+--------|
| Core Suggestions         | Deprecated/missing. |
|--------------------------+------------+--------|
| Incompatible Kernel Ext. | 2019.04.10 | 14.5.1 |
|--------------------------+------------+--------|
| Chinese Word List        | Deprecated/missing. |
|--------------------------+------------+--------|
| Core LSKD (dkrl)         | 2019.02.28 |      8 |
--------------------------------------------------

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.