Posted on 03-08-2016 11:14 AM
Hey all,
I'm researching this, but in the interest of not reinventing the wheel, I thought I'd ask the nation...
The Xprotect Status extension attribute posted here returns the following on 10.11.3:
The domain/default pair of (/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.meta, LastModification) does not exist
I've looked through the file referenced and there's no instance of a date or the words "modified," "modification," change," or "update" in the XML. Does anyone know where to look for the last Xprotect update?
Solved! Go to Solution.
Posted on 03-08-2016 11:30 AM
Hmm. That's a good question and I think the LastModification line has not shown up in that plist for a while now. Its not in my 10.10.5 Mac's plist anyway.
I seem to recall seeing somewhere that XProtect files moved around to different places, but I can't recall now where to find the modification date.
Just in case no-one shows up with a proper explanation, however unlikely that is here, here's a method using stat -s and converting the raw mtime format into a Casper friendly format:
date -jf "%s" $(stat -s /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.meta.plist | tr ' ' '
' | awk -F= '/st_mtime/{print $NF}') +"%Y-%m-%d %T"
As an aside, here's a nice way of getting a full list of the applied XProtect malware blocks. I have not confirmed if the list this pulls is accurate or not. It may or may not be.
xmllint --format /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.plist | awk -F'>|<' '/Description/{getline; print $3}' | sed '/^$/d'
Posted on 03-08-2016 12:20 PM
Now that I've seen @mm2270's method, I like his better for pulling the information from the 10.6 - 10.8 XProtect.meta.plist file. Updated EA below:
#!/bin/bash
osvers_major=$(sw_vers -productVersion | awk -F. '{print $1}')
osvers_minor=$(sw_vers -productVersion | awk -F. '{print $2}')
if [[ ${osvers_major} -eq 10 ]] && [[ ${osvers_minor} -lt 6 ]]; then
result="XProtect not available for `sw_vers -productVersion`"
echo "<result>$result</result>"
fi
if [[ ${osvers_major} -eq 10 ]] && [[ ${osvers_minor} -ge 6 ]] && [[ ${osvers_minor} -lt 9 ]]; then
last_xprotect_update_epoch_time=`date -jf "%s" $(stat -s /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.meta.plist | tr ' ' '
' | awk -F= '/st_mtime/{print $NF}') +%s`
last_xprotect_update_human_readable_time=`date -r "$last_xprotect_update_epoch_time" '+%m/%d/%Y %H:%M:%S'`
result="$last_xprotect_update_human_readable_time"
echo "<result>$result</result>"
fi
if [[ ${osvers_major} -eq 10 ]] && [[ ${osvers_minor} -ge 9 ]]; then
last_xprotect_update_epoch_time=$(printf "%s
" `for i in $(pkgutil --pkgs=".*XProtect.*"); do pkgutil --pkg-info $i | awk '/install-time/ {print $2}'; done` | sort -n | tail -1)
last_xprotect_update_human_readable_time=`/bin/date -r "$last_xprotect_update_epoch_time" '+%m/%d/%Y %H:%M:%S'`
result="$last_xprotect_update_human_readable_time"
echo "<result>$result</result>"
fi
That should give consistent human-readable output for 10.6.x and higher, as well as handling 10.5.8 and earlier by indicating that XProtect is not available for those versions of Mac OS X.
EDIT: After more testing, I realized that Apple changed how it named XProtect receipts sometime between 2014 and 2015. That meant that tailing the list may give an inaccurate result.
I've updated the EA so that it's checking when the individual XProtect installer packages were actually installed, as that will give a more accurate reading of the last time XProtect was updated.
Posted on 03-08-2016 06:21 PM
Hey @milesleacy, something like this is close I think:
/usr/bin/defaults read /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.meta.plist PlugInBlacklist | awk -F'"' '{print $2}' | sed '/^$/d;N;s/
/ /'
On my 10.10.5 Mac this outputs:
com.apple.java.JavaAppletPlugin 14.8.0
com.apple.java.JavaPlugin2_NPAPI 14.8.0
com.macromedia.Flash Player ESR.plugin 18.0.0.324
com.macromedia.Flash Player.plugin 20.0.0.267
com.microsoft.SilverlightPlugin 5.1.41212.0
com.oracle.java.JavaAppletPlugin 1.8.51.16
The only issue is that there is a key above the 'PlugInBlacklist' dict that has the following, which won't show up in the results:
<key>JavaWebComponentVersionMinimum</key>
<string>1.6.0_45-b06-451</string>
I believe that's a very old Java version for 10.6 and earlier, back when Apple maintained it, not Oracle. (Actually this looks like Oracle Java now that I'm looking closer at it, so it may just be a simple minimum version string for that, just as it implies) I'm not sure how relevant it is to get that in the results since I don't think that line has changed now in years. For some reason, Apple keeps it outside of the PlugInBlacklist section.
EDIT: Actually I just realized you also wanted the ExtensionBlacklist, not just the Plugin one. Hmm. Not sure if its possible to have a one liner, but you could combine two or three commands to pull it all together I think.
Or, I'd probably maintain two separate EAs. One for the Plugins and one for Safari Extensions.
Here's one for pulling the Safari Extension Blacklist.
/usr/bin/defaults read /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.meta.plist ExtensionBlacklist | awk -F'"' '{print $2}' | sed '/^$/d;/Developer Identifier/d'
And the output:
com.searchnt.safari
com.spigot.safari.searchme
com.spigot.safari.ebayshopassist
com.smokycap.safari
com.searchconnect.safariext
com.codec.extension
com.zako.chatzum
com.adobe.flash
com.optimalcycling.safari.popupblocker
com.genieo.safari
com.app65867
com.defaultsearch.safariext
com.jbsearch.safariext
com.mtsearch.safariext
com.rohit.MacMInSale
com.tabgreg.safariext
com.gold.safari
com.eliaho.safari
com.nariabox.safari
com.diigo.safari.awesomeScreenshot
com.portsayd.safari
Posted on 03-08-2016 11:30 AM
Hmm. That's a good question and I think the LastModification line has not shown up in that plist for a while now. Its not in my 10.10.5 Mac's plist anyway.
I seem to recall seeing somewhere that XProtect files moved around to different places, but I can't recall now where to find the modification date.
Just in case no-one shows up with a proper explanation, however unlikely that is here, here's a method using stat -s and converting the raw mtime format into a Casper friendly format:
date -jf "%s" $(stat -s /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.meta.plist | tr ' ' '
' | awk -F= '/st_mtime/{print $NF}') +"%Y-%m-%d %T"
As an aside, here's a nice way of getting a full list of the applied XProtect malware blocks. I have not confirmed if the list this pulls is accurate or not. It may or may not be.
xmllint --format /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.plist | awk -F'>|<' '/Description/{getline; print $3}' | sed '/^$/d'
Posted on 03-08-2016 11:34 AM
True. There is no LastModification key in that plist. I use 'Version' myself.
Posted on 03-08-2016 11:56 AM
For 10.6.x - 10.8.x, you should still be able to pull the LastModification
value from the plist. For 10.9.x and later, I'd go by the installer package receipt, as XProtect updates now come down from the Apple software update feed:
To poll for the last modified date, I've written the following extension attribute:
#!/bin/bash
osvers_major=$(sw_vers -productVersion | awk -F. '{print $1}')
osvers_minor=$(sw_vers -productVersion | awk -F. '{print $2}')
if [[ ${osvers_major} -eq 10 ]] && [[ ${osvers_minor} -lt 9 ]]; then
last_xprotect_update_human_readable_time=`/usr/bin/defaults read /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.meta LastModification`
echo "<result>$last_xprotect_update_human_readable_time</result>"
fi
if [[ ${osvers_major} -eq 10 ]] && [[ ${osvers_minor} -ge 9 ]]; then
last_xprotect_update_install=`pkgutil --pkgs=".*XProtect.*" | tail -1`
last_xprotect_update_epoch_time=`pkgutil --pkg-info "$last_xprotect_update_install" | awk '/install-time/ {print $2}'`
last_xprotect_update_human_readable_time=`date -r "$last_xprotect_update_epoch_time" '+%m/%d/%Y %H:%M:%S'`
echo "<result>$last_xprotect_update_human_readable_time</result>"
fi
Posted on 03-08-2016 12:20 PM
Now that I've seen @mm2270's method, I like his better for pulling the information from the 10.6 - 10.8 XProtect.meta.plist file. Updated EA below:
#!/bin/bash
osvers_major=$(sw_vers -productVersion | awk -F. '{print $1}')
osvers_minor=$(sw_vers -productVersion | awk -F. '{print $2}')
if [[ ${osvers_major} -eq 10 ]] && [[ ${osvers_minor} -lt 6 ]]; then
result="XProtect not available for `sw_vers -productVersion`"
echo "<result>$result</result>"
fi
if [[ ${osvers_major} -eq 10 ]] && [[ ${osvers_minor} -ge 6 ]] && [[ ${osvers_minor} -lt 9 ]]; then
last_xprotect_update_epoch_time=`date -jf "%s" $(stat -s /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.meta.plist | tr ' ' '
' | awk -F= '/st_mtime/{print $NF}') +%s`
last_xprotect_update_human_readable_time=`date -r "$last_xprotect_update_epoch_time" '+%m/%d/%Y %H:%M:%S'`
result="$last_xprotect_update_human_readable_time"
echo "<result>$result</result>"
fi
if [[ ${osvers_major} -eq 10 ]] && [[ ${osvers_minor} -ge 9 ]]; then
last_xprotect_update_epoch_time=$(printf "%s
" `for i in $(pkgutil --pkgs=".*XProtect.*"); do pkgutil --pkg-info $i | awk '/install-time/ {print $2}'; done` | sort -n | tail -1)
last_xprotect_update_human_readable_time=`/bin/date -r "$last_xprotect_update_epoch_time" '+%m/%d/%Y %H:%M:%S'`
result="$last_xprotect_update_human_readable_time"
echo "<result>$result</result>"
fi
That should give consistent human-readable output for 10.6.x and higher, as well as handling 10.5.8 and earlier by indicating that XProtect is not available for those versions of Mac OS X.
EDIT: After more testing, I realized that Apple changed how it named XProtect receipts sometime between 2014 and 2015. That meant that tailing the list may give an inaccurate result.
I've updated the EA so that it's checking when the individual XProtect installer packages were actually installed, as that will give a more accurate reading of the last time XProtect was updated.
Posted on 03-08-2016 01:14 PM
Good stuff, thanks!
Posted on 03-08-2016 03:19 PM
Cool, thanks for this!
I'm trying to create a Smart Group of machines that haven't received it - but not sure what an "acceptable" timeframe is. Does anybody know the frequency in which Apple pushes these - is it a regular interval at all?
Any suggestions on how best to do that?
Thanks,
mbezzo
Posted on 03-08-2016 04:40 PM
@mbezzo Use a Configuration Profile to automate...
ConfigDataInstall is the key that needs to be set to true.
As far as I know, these updates are issued as needed to respond to exploits. I'm planning to ask my Apple rep in later this week if they're able to share a feed of the latest update either by date or version.
Failing that, you could set up a Mac or OS X VM with known-good automatic updates enabled. Then use it and the JSS API to update your smart group whenever the version/date changes.
Posted on 03-08-2016 04:45 PM
Anyone have a one liner similar to @mm2270 's XProtect malware blocks list that will output the pluglin and extension blacklists in the format of <bundleIdentifier><space><minimumPluginBundleVersion>?
I want Extension Attributes that InfoSec teams can reference to verify remediation.
I'll give it a whirl when I get home unless anyone else gets it before then.
Posted on 03-08-2016 06:21 PM
Hey @milesleacy, something like this is close I think:
/usr/bin/defaults read /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.meta.plist PlugInBlacklist | awk -F'"' '{print $2}' | sed '/^$/d;N;s/
/ /'
On my 10.10.5 Mac this outputs:
com.apple.java.JavaAppletPlugin 14.8.0
com.apple.java.JavaPlugin2_NPAPI 14.8.0
com.macromedia.Flash Player ESR.plugin 18.0.0.324
com.macromedia.Flash Player.plugin 20.0.0.267
com.microsoft.SilverlightPlugin 5.1.41212.0
com.oracle.java.JavaAppletPlugin 1.8.51.16
The only issue is that there is a key above the 'PlugInBlacklist' dict that has the following, which won't show up in the results:
<key>JavaWebComponentVersionMinimum</key>
<string>1.6.0_45-b06-451</string>
I believe that's a very old Java version for 10.6 and earlier, back when Apple maintained it, not Oracle. (Actually this looks like Oracle Java now that I'm looking closer at it, so it may just be a simple minimum version string for that, just as it implies) I'm not sure how relevant it is to get that in the results since I don't think that line has changed now in years. For some reason, Apple keeps it outside of the PlugInBlacklist section.
EDIT: Actually I just realized you also wanted the ExtensionBlacklist, not just the Plugin one. Hmm. Not sure if its possible to have a one liner, but you could combine two or three commands to pull it all together I think.
Or, I'd probably maintain two separate EAs. One for the Plugins and one for Safari Extensions.
Here's one for pulling the Safari Extension Blacklist.
/usr/bin/defaults read /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.meta.plist ExtensionBlacklist | awk -F'"' '{print $2}' | sed '/^$/d;/Developer Identifier/d'
And the output:
com.searchnt.safari
com.spigot.safari.searchme
com.spigot.safari.ebayshopassist
com.smokycap.safari
com.searchconnect.safariext
com.codec.extension
com.zako.chatzum
com.adobe.flash
com.optimalcycling.safari.popupblocker
com.genieo.safari
com.app65867
com.defaultsearch.safariext
com.jbsearch.safariext
com.mtsearch.safariext
com.rohit.MacMInSale
com.tabgreg.safariext
com.gold.safari
com.eliaho.safari
com.nariabox.safari
com.diigo.safari.awesomeScreenshot
com.portsayd.safari
Posted on 03-08-2016 06:31 PM
Thanks @mm2270! That's exactly what I was looking for. I owe you a beer next time you're in the Bay Area.
Posted on 03-08-2016 07:47 PM
Thanks to @rtrouton as well.
The second script you posted is great for environments where running an old OS X version is acceptable.
Posted on 03-09-2016 11:31 AM
FWIW, you can force this stuff to update using:
sudo softwareupdate --background-critical
Posted on 03-09-2016 12:47 PM
@thoule I used "Version" as you suggested and my EA works now by pulling the version and I get "2076" as the output for the EA on my test device. Where do you cross reference or look up to actually see what the latest version is? Does Apple post it somewhere? All of my Google searches have tuned up empty.
Posted on 03-09-2016 04:20 PM
There are a number of items that fall within Apple's newer security updates scheme. Here is a screenshot of the little AppleScript app we use that shows the items and the dates, etc.
I won't post up the code as it's a rudimentary AS that was written by someone else and it got a lot of grief from guys that know how to write code properly. It does the job nicely, and we can see when the Macs are getting behind on things or not.
Posted on 03-09-2016 06:00 PM
@scottb Nice lil trick there. I am by know means a coder, would love a look at the code if you don't mind off this thread somehow? Having those stats would be extremely helpful!
Posted on 03-09-2016 07:42 PM
@scottb Never be afraid of rough code. It's how we all learn. I'd love to see what's behind that screenshot!
Posted on 03-10-2016 09:39 AM
Me too : ) I know that I can use your exact AS in my environment. And I don't care what it looks like : ) it will get the job done and allow me move on to the next thing I have to fix/improve : )
C
Posted on 03-10-2016 09:52 AM
+1 to the above comments. I'm interested to see how its pulling the above info. I took a quick look yesterday, and I can see where its getting the XProtect version, as already mentioned on this thread, but I'm not sure where its getting the other data from. Would love to see it.
Posted on 03-10-2016 11:22 AM
OK, I'll post it. Again - I did NOT write this. I didn't even know it was "crap" until I put it on Slack one day and got endless ribbing over it. I'm just learning the basics now and was only trying to be helpful. So, again, with apologies towards those who know WTH they are doing with code, here it is. Hope you find it useful. This one if for 10.11.x. I think I also have one setup for the older OS X's. I'll locate that and post later.
Open up Script Editor and create a new item. Save as a ".app" and run.
set a to do shell script "defaults read /System/Library/CoreServices/XProtect.bundle/Contents/Resources/XProtect.meta.plist Version"
tell application "Finder" to set b to get creation date of (POSIX file "/System/Library/CoreServices/XProtect.bundle/Contents/Resources/XProtect.meta.plist" as alias)
set s to short date string of b
set t to time string of b
set c to do shell script "defaults read /private/var/db/gkopaque.bundle/Contents/version.plist CFBundleShortVersionString"
tell application "Finder" to set d to get creation date of (POSIX file "/private/var/db/gkopaque.bundle/Contents/version.plist" as alias)
set u to short date string of d
set v to time string of d
set e to do shell script "defaults read /System/Library/CoreServices/SystemVersion.plist ProductVersion"
set f to do shell script "defaults read /System/Library/CoreServices/SystemVersion.plist ProductBuildVersion"
set g to do shell script "defaults read /System/Library/Sandbox/Compatibility.bundle/Contents/version.plist CFBundleShortVersionString"
tell application "Finder" to set h to get creation date of (POSIX file "/System/Library/Sandbox/Compatibility.bundle/Contents/version.plist" as alias)
set w to short date string of h
set x to time string of h
set i to do shell script "defaults read /System/Library/CoreServices/MRT.app/Contents/version CFBundleShortVersionString"
tell application "Finder" to set j to get creation date of (POSIX file "/System/Library/CoreServices/MRT.app/Contents/version.plist" as alias)
set y to short date string of j
set z to time string of j
set k to do shell script "defaults read '/System/Library/Intelligent Suggestions/Assets.suggestionsassets/Contents/version.plist' CFBundleShortVersionString"
tell application "Finder" to set l to get creation date of (POSIX file "/System/Library/Intelligent Suggestions/Assets.suggestionsassets/Contents/version.plist" as alias)
set m to short date string of l
set n to time string of l
display dialog "XProtect " & tab & tab & a & tab & tab & s & tab & " " & t & return & "Gatekeeper " & tab & tab & c & tab & tab & tab & u & tab & " " & v & return & "SIP " & tab & tab & tab & tab & g & tab & tab & tab & w & tab & " " & x & return & "MRT " & tab & tab & tab & i & tab & tab & tab & y & tab & " " & z & return & "Core Suggest " & tab & k & tab & tab & tab & m & tab & " " & n & return & return & "OS X " & e & " (" & f & ")" buttons {"Close"} default button 1
Posted on 03-10-2016 11:36 AM
Thanks for posting @scottb. Its not crap, but I would say that some of the labels used throughout could be more descriptive. Its a little tough to follow what "h" or "x" means, so if anything I would only change some of the set <label> strings to things that are more descriptive so its easier to understand and troubleshoot. Also, a few items could be shortened, but again, far from crap.
Posted on 03-10-2016 11:43 AM
@mm2270 - I was going to try and re-do it and make it a little easier to grasp - just never took the time to do it.
I see what you mean, and honestly, I often grab code here and there and try to understand it and re-form it to my needs. I'll mess around one day to see if I can clean it up while keeping it functional. I already feel subpar when it comes to the guys like you who write the code, so I was a bit thin-skinned over the response to it before, even though it's not my creation.
Posted on 03-10-2016 11:55 AM
@scottb Yes, well, its an unfortunate fact of the internet age that snobs of all kinds (code snobs, intellectual snobs, grammar snobs, etc) have found a haven behind their screens and keyboards to make fun of anyone who doesn't know as much as them in their preferred topic. Its a sign of confidence issues in themselves really, and I doubt most of them would say what they say online to someone's face, but.. I digress.
Personally I learned a lot looking at that, because I was honestly not aware of some of those files and plists to check for versions and creation dates, so props to whomever wrote it for knowing what to look for in the first place, even if the code could be a little cleaner.
Posted on 03-10-2016 12:26 PM
Mike is spot on!!!! : ) Life is way to short for any snobs : ) That said I am an Apple and Casper snob
Thank you very much Scott!!!
C
Posted on 03-11-2016 05:55 AM
Excited to get this running but when I create the .app file with TextWrangler and run the file, the .app won't run, throws up an error "You can’t open the application “GetLatestVersionASU” because PowerPC applications are no longer supported.
Researching how to get his done, but if any of the gurus know the answer, I'd greatly appreciate the help!
Posted on 03-11-2016 06:49 AM
@TomDay Its an Applescript, so you need to paste it into Script Editor, located in /Applications/Utilities/
and then click the build button in the toolbar. Then save it as an application bundle. See screenshots...
Raw code, click the Build button highlighted
The compiled code. Save from here to an application bundle
Posted on 03-11-2016 07:32 AM
Posted on 03-11-2016 07:36 AM
@TomDay - I posted that above but maybe I should have used bold on it.
Glad you guys are finding it useful. We use it in testing seed builds of the OS so I guess I forgot how cool it was when I started using it as well. Maybe a good item to put into Self Service for checking on Macs in the "Maintenance" tab. Not that anyone would know what to do with the info, but it looks nice. :)
Posted on 03-15-2016 01:29 PM
Thanks scottb! Appreciate the share.
Forgive my ignorance, but anybody have any info on "Core Suggest"? I'm not familiar with it and didn't find much with a quick search.
Posted on 03-16-2016 03:10 PM
@mbezzo - here's the contents of it. Still not really sure, but you can get some ideas looking at this:
Posted on 03-16-2016 03:13 PM
@scottb Interesting - thanks!
Posted on 05-27-2016 01:53 PM
Here's an updated rev that is a little nicer. A mix of contributions by a few people.
Gives you the below in the screenshot.
--start of script
##########################################
# Variables
##########################################
set updateMarker to " *"
set saveLocation to "~/Library/Preferences/com.appleseedCriticalUpdates.txt"
set lastUpdate to {}
set thisDate to {}
set hasBeenUpdated to ""
set TimeStrings to {"/System/Library/CoreServices/XProtect.bundle/Contents/Resources/XProtect.meta.plist", "/private/var/db/gkopaque.bundle/Contents/version.plist", "/System/Library/Sandbox/Compatibility.bundle/Contents/version.plist", "/System/Library/CoreServices/MRT.app/Contents/version.plist", "'/System/Library/Intelligent Suggestions/Assets.suggestionsassets/Contents/version.plist'", "/System/Library/Extensions/AppleKextExcludeList.kext/Contents/version.plist", "/usr/share/mecabra/updates/com.apple.inputmethod.SCIM.bundle/Contents/version.plist", "/usr/share/kdrl.bundle/info.plist"}
set VersionStrings to {"/System/Library/CoreServices/XProtect.bundle/Contents/Resources/XProtect.meta.plist Version", "/private/var/db/gkopaque.bundle/Contents/version.plist CFBundleShortVersionString", "/System/Library/Sandbox/Compatibility.bundle/Contents/version.plist CFBundleShortVersionString", "/System/Library/CoreServices/MRT.app/Contents/version CFBundleShortVersionString", "/System/Library/Intelligent\ Suggestions/Assets.suggestionsassets/Contents/version.plist CFBundleShortVersionString", "/System/Library/Extensions/AppleKextExcludeList.kext/Contents/version CFBundleShortVersionString", "/usr/share/mecabra/updates/com.apple.inputmethod.SCIM.bundle/Contents/info SUVersionString", "/usr/share/kdrl.bundle/info CFBundleVersion"}
set theComponents to {"XProtect", "Gatekeeper", "System Integrity Protect...", "Malware Removal Tool", "Core Suggestions", "Incompatible Kernel Ext...", "Chinese Word List", "Core LSKD (dkrl)"}
set theTabSpaces to ""
set _multiTabs to tab & tab & tab & tab
set displayString to "Component" & _multiTabs & "Version" & tab & "Updated" & tab & tab & "Time" & return & "_______________________________________________________________" & return & return
##########################################
# Handlers
##########################################
# calculate the number of tabs required for the display dialog
on getTabs(aWord)
set n to round (25 - (length of aWord)) / 4
if n is less than 0 then set n to 1
if length of aWord is 10 then set n to 3
set this_tab to tab
repeat n times
set this_tab to this_tab & tab
end repeat
return this_tab
end getTabs
#get the last modification date
on getUpdatedDate(aFile)
set d to do shell script "stat -f "%Sc" -t "%d-%m-%Y %H:%M" " & aFile
set end of my thisDate to d
return d
end getUpdatedDate
#compare the dates to see if there's been a change
on checkLastUpdate(aDateString, anIndex)
set n to text 1 thru 10 of aDateString
set o to text 1 thru 10 of my (item anIndex of lastUpdate)
if (n is equal to o) then
return ""
else
return my updateMarker
end if
end checkLastUpdate
##########################################
# Commands
##########################################
# read the dates into our script from the last run
set oldTIDS to AppleScript's text item delimiters
set AppleScript's text item delimiters to ","
try
set s to (do shell script "cat " & saveLocation)
set lastUpdate to text items of s
end try
set AppleScript's text item delimiters to oldTIDS
# this is the workhorse, getting all the data for each component
repeat with i from 1 to number of items in theComponents
set component_item to item i of theComponents
set version_item to item i of VersionStrings
set time_item to item i of TimeStrings
set theTabSpaces to getTabs(component_item)
set updatedDate to getUpdatedDate(time_item)
# check if we had some saved dates from a previous run
#and if so, check them against the current dates
if (count of (lastUpdate as list)) = (count of theComponents) then
set my hasBeenUpdated to checkLastUpdate(updatedDate, i)
end if
# organise the display string
set v to (do shell script "defaults read " & version_item)
if length of v < 4 or (length of v = 4 and v contains ".") then set v to v & tab
set displayString to displayString & component_item & theTabSpaces & v & tab & updatedDate & my hasBeenUpdated & return
set my hasBeenUpdated to ""
end repeat
#write out current dates to file
set writeData to ""
repeat with i from 1 to number of items in thisDate
set this_item to item i of thisDate
if length of writeData is 0 then
set writeData to this_item
else
set writeData to writeData & "," & this_item
end if
end repeat
do shell script "echo " & writeData & "> " & saveLocation
# finally, get the OS version and build
set theSysInfo to (do shell script "sw_vers")
set sysString to paragraph 2 of theSysInfo & return & paragraph 3 of theSysInfo
set displayString to displayString & return & sysString
# and...
display dialog displayString buttons {"Close"} default button "Close" with title "Critical Updates (v1.1)"
--EOF
Posted on 06-30-2017 07:14 AM
Nice AppleScript! Hey have you updated this for 10.12?
Posted on 06-30-2017 07:36 AM
@ClassicII - not yet. I'll see if that can be looked at and post back. Thanks for the reminder... Happy 4th!
Posted on 06-30-2017 11:22 AM
Hey @ClassicII et.al, Phil has taken this over and is offering it up on his site (with other stuff). Check it out - he's a dev and a longtime fellow AppleSeeder. I pinged him about getting the script as he delivers it in .app form now. If he's cool with me posting the script here, I'll add it later. We used to pass it around and folks would edit to their needs...guess he's the gatekeeper (not intended) now.
Current screenie