Posted on 03-16-2015 08:32 PM
Hello all, hope this can help some of you out if not give you a starting point for your own version reporting script.
Often I am walking from the cafeteria and get stopped or I'm making my way through a cubicle farm to one customer and get pulled aside by another. Either way it almost always ends up being a conversation about software version this or update that. Being that my brain isn't a functioning Casper database (yet) I either have to open the app(s) in question to view it's version number or if it's a plugin that is yelling at them to update I simply rely on good'ol Firefox "about:plugins" url. I decided to write this little gem, package it up and deploy it as /usr/sbin/versions, so a quick:
COMMAND + spacebar
to search for and open Terminal and running "versions" will give me a quick overview of what I need to know.
Does anyone disagree with putting it in /usr/sbin path?
Code below
#!/bin/sh
# Name : reportSystemInfo.sh
# Author : Snickasaurus
# Date : 20160117
# Purpose : Output a generated system report then open with default browser.
# Sauce : https://github.com/Snickasaurus/SystemReportToHTML/blob/master/runSystemReport.sh
# Variables
theTitle="System Report for host: [ $HOSTNAME ]"
theNow=$(date "+%Y/%m/%d at %r %Z")
theStamp="<h2>Created on $theNow by $USER</h2>"
# Begin script
# Remove previously ran report if found.
if [ -e /private/tmp/systemReport.html ]
then
rm /private/tmp/systemReport.html
fi
# Functions
function system_info
{
echo "<h3>System release info</h3>"
echo "<pre>"
sw_vers
echo "</pre>"
}
function show_uptime
{
echo "<h3>System uptime</h3>"
echo "<pre>"
uptime
echo "</pre>"
}
function drive_space
{
echo "<h3>Filesystem space</h3>"
echo "<pre>"
df -h
echo "</pre>"
}
function jss_check
{
echo "<h3>Jss Availability</h3>"
echo "<pre>"
jamf checkJSSConnection
echo "</pre>"
}
function user_list
{
echo "<h3>User List</h3>"
echo "<pre>"
userList=$(dscl /Local/Default -list /Users UniqueID | awk '$2 >= 500 { print $1; }')
for i in $userList
do
echo "$(id -un $i) > $(id -F $i)"
done
echo "</pre>"
}
function net_names
{
echo "<h3>Host Names</h3>"
echo "<pre>"
echo "ComputerName : $(scutil --get ComputerName)"
echo "HostName : $(scutil --get HostName)"
echo "LocalHostName : $(scutil --get LocalHostName)"
echo "NetBIOSName : $(defaults read /Library/Preferences/SystemConfiguration/com.apple.smb.server NetBIOSName)"
echo "</pre>"
}
function sw_update
{
theAUTODOWNLOAD=$(defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload)
if [ "$theAUTODOWNLOAD" == "1" ]
then
theAUTOD="True"
else
theAUTOD="False"
fi
theACECheck=$(defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticCheckEnabled)
if [ "$theACECheck" == "1" ]
then
theACE="True"
else
theACE="False"
fi
theCUICheck=$(defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist CriticalUpdateInstall)
if [ "$theCUICheck" == "1" ]
then
theCUI="True"
else
theCUI="False"
fi
theSECDATACheck=$(defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist ConfigDataInstall)
if [ "$theSECDATACheck" == "1" ]
then
theSECD="True"
else
theSECD="False"
fi
theLASTSUCCESS=$(defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist LastSuccessfulDate | awk '{print $1,$2}')
echo "<h3>Software Update Settings</h3>"
echo "<pre>"
echo "Automatic download updates? = $theAUTOD"
echo "Automatic update check enabled? = $theACE"
echo "Automatic Critical Update install? = $theCUI"
echo "Automatic Security & Data install? = $theSECD"
echo "Last Successful Update = $theLASTSUCCESS"
echo "</pre>"
}
function app_data
{
if [ -f /Applications/Adobe Acrobat XI Pro/Adobe Acrobat Pro.app/Contents/Info.plist ]
then
theAAP=$(defaults read /Applications/Adobe Acrobat XI Pro/Adobe Acrobat Pro.app/Contents/Info.plist CFBundleShortVersionString)
else
theAAP="Missing"
fi
if [ -e /Applications/Safari.app ]
then
theFirefox=$(defaults read /Applications/Safari.app/Contents/Info.plist CFBundleShortVersionString)
else
theSafari="Missing"
fi
if [ -e /Applications/Google Chrome.app ]
then
theChrome=$(defaults read /Applications/Google Chrome.app/Contents/Info.plist CFBundleShortVersionString)
else
theChrome="Missing"
fi
if [ -e /Applications/Firefox.app ]
then
theFirefox=$(defaults read /Applications/Firefox.app/Contents/Info.plist CFBundleShortVersionString)
else
theFirefox="Missing"
fi
if [ -f /Library/Internet Plug-Ins/Flash Player.plugin/Contents/Info.plist ]
then
theFlash=$(defaults read /Library/Internet Plug-Ins/Flash Player.plugin/Contents/Info CFBundleShortVersionString)
else
theFlash="Missing"
fi
if [ -f /Library/Application Support/Oracle/Java/Info.plist ]
then
theOracle=$(defaults read /Library/Application Support/Oracle/Java/Info.plist CFBundleShortVersionString)
else
theOracle="Missing"
fi
if [ -f /Applications/Microsoft Office 2011/Office/MicrosoftComponentPlugin.framework/Versions/14/Resources/Info.plist ]
then
theOffice11=$(defaults read /Applications/Microsoft Office 2011/Office/MicrosoftComponentPlugin.framework/Versions/14/Resources/Info CFBundleShortVersionString)
else
theOffice11="Missing"
fi
if [ -f /Applications/Sophos Anti-Virus.app/Contents/Info.plist ]
then
theSophos=$(/usr/libexec/PlistBuddy -c "print :ProductVersion:" /Library/Sophos Anti-Virus/product-info.plist)
else
theSophos="Missing"
fi
if [ -f /Applications/VMware Fusion.app/Contents/Info.plist ]
then
theVMWare=$(defaults read /Applications/VMware Fusion.app/Contents/Info.plist CFBundleShortVersionString)
else
theVMWare="Missing"
fi
if [ -f /Library/Internet Plug-Ins/Silverlight.plugin/Contents/Info.plist ]
then
theSilver=$(defaults read /Library/Internet Plug-Ins/Silverlight.plugin/Contents/Info.plist CFBundleShortVersionString)
else
theSilver="Missing"
fi
echo "<h3>Application Data</h3>"
echo "<pre>"
echo "Chrome = $theChrome"
echo "Firefox = $theFirefox"
echo "Safari = $theSafari"
echo "- - - - - - - - - - - - - - - - - - -"
echo "Flash = $theFlash"
echo "JavaO = $theOracle"
echo "Silverlight = $theSilver"
echo "- - - - - - - - - - - - - - - - - - -"
echo "Acrobat Pro = $theAAP"
echo "Office 2011 = $theOffice11"
echo "Sophos AV = $theSophos"
echo "VMware Fusion = $theVMWare"
echo "</pre>"
}
# Begin script
cat > /private/tmp/systemReport.html <<- EOF
<html>
<head>
<style>
body {background-color: black; color: white;}
h1 {text-align: center; color: red;}
h2 {text-align: center; color: green;}
h3 {color: blue;}
p {text-align: center;}
</style>
<title>$theTitle</title>
</head>
<body>
<h1>$theTitle</h1>
<p>$theStamp</p>
$(system_info)
$(show_uptime)
$(app_data)
$(drive_space)
$(jss_check)
$(user_list)
$(net_names)
$(sw_update)
</body>
</html>
EOF
open /private/tmp/systemReport.html
exit 0
Posted on 03-17-2015 05:34 AM
Do a google search on bin and sbin and you'll get reams of opinion.
I think the general consensus is to use /usr/local/bin
I see value in this idea as well. I'm working on a similar project to do the same thing but make it executable from Self Service, bringing up a dialog with the results.
Posted on 03-17-2015 05:45 AM
Thanks, thats pretty handy!
Do you have a copy in github, I've got a few ideas for it already!
Posted on 03-17-2015 06:32 AM
@dpertschi Thanks for your comment. I'll definitely do some more reading on /usr/local/bin
@davidacland You're welcome and thanks for the comment. I'll add it to my Git today and post back here with the link.
Posted on 03-18-2015 01:47 PM
This information is all accessible via the API as well. However, if the device has not submitted inventory it may not be up to date when you do the API call.
example code:
curl -k -u tlarkin https://casper9gm.local:8443/JSSResource/computers/id/10 | xpath //application
Example output:
<application><name>Activity Monitor.app</name><path>/Applications/Utilities/Activity Monitor.app</path><version>10.10.0</version></application>-- NODE --
<application><name>Adobe Flash Player Install Manager.app</name><path>/Applications/Utilities/Adobe Flash Player Install Manager.app</path><version>16.0.0.305</version></application>-- NODE --
<application><name>AirPort Utility.app</name><path>/Applications/Utilities/AirPort Utility.app</path><version>6.3.4</version></application>-- NODE --
<application><name>App Store.app</name><path>/Applications/App Store.app</path><version>2.0</version></application>-- NODE --
I will say I really like the idea of having something like an, "Application Version Check," in Self Service. Where users can click a button and show all their current software versions. You could also use an API script with read only access to pull down all their information and then take that XML and have Safari display it or something.
Also, it is not quite as pretty when it comes to output but mdfind can output all application versions very quickly with some simple one liners like this:
mdfind -onlyin /Applications 'kMDItemContentType==com.apple.application-bundle' -attr "kMDItemVersion"
After hacking together a quick script for POC purposes you could create a policy that runs this command, dumps it into a text file and then opens it, then deletes said text file for next time to be ran.
#!/bin/bash
# get list of all current apps installed and display in a dialog box to end user
appVersionList=$(mdfind -onlyin /Applications 'kMDItemContentType==com.apple.application-bundle' -attr "kMDItemDisplayName" -attr "kMDItemVersion" | sed 's/^.*kMDItemDisplayName//' | sed 's/kMDItemVersion//g' | tr '=' ' ' | sort >> /tmp/applist.txt)
open -a TextEdit /tmp/applist.txt
sleep 15 # make sure the file exists long enough for text edit to read it
rm /tmp/applist.txt
exit 0
Not the prettiest one liner, but it seems to work. Perhaps someone here could improve it and maybe toss it in a dialog box or something a bit more fancy.
Cheers,
Tom
Posted on 01-18-2016 05:59 PM
To: @dpertschi , @davidacland and @tlarkin as an update to this project I was working on and to @emilykausalik because of your lurking presence and SelfService mastery.
Here is a script I started from scratch and does the following:
1) Runs a bunch of stuff to collect info
2) Exports to an HTML file
3) Opens in whatever is set as the default browser
To: Tom
I never came back and commented on your work with the api stuff and I do want to send a big thank you for the quick tutorial on api commands and the mdfind oneliner. Neither of which I've messed with but have made notes on so in the future I can add them to my toolbox (especially the API stuff. I find it VERY interesting what people are doing with it theses days).
End: Tom
So here is my latest and greatest attempt to do something geeky and perhaps provide new scriptwriters a few examples of cool stuff you can do.
This could be a packaged script that is deployed in your imaging config to a location in your PATH (so you or a tech and pull up Terminal on a client machine an run the script easily) or added to Self Service and scoped to whomever you desire to have access to it.
Hope this helps someone. I'm posting this after showing @keaton today while we were on the phone discussing a super weird Filevault 2 issue I'm suffering from.
WHAT TO EDIT - With your fav text editor search for "MyCompany" and you will see where the report is saved. (4 places)
#!/bin/bash
# Name : reportSystemInfo.sh
# Author : Nick Smith
# Date : 20160117
# Purpose : Output a generated system report then open with default browser.
# Variables
theTitle="System Report for host: [ $HOSTNAME ]"
theNow=$(date "+%Y/%m/%d at %r %Z")
theStamp="Created on $theNow by $USER"
#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#
# #
# REMOVE old report if found #
# #
#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#
if [ -e /Library/Application Support/MyCompany/report.html ]
then
rm /Library/Application Support/MyCompany/report.html
fi
#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#
# #
# REMOVE old report if found #
# #
#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#
# Functions
function system_info
{
echo "<h3>System release info</h3>"
echo "<pre>"
sw_vers
echo "</pre>"
}
function show_uptime
{
echo "<h3>System uptime</h3>"
echo "<pre>"
uptime
echo "</pre>"
}
function drive_space
{
echo "<h3>Filesystem space</h3>"
echo "<pre>"
df -h
echo "</pre>"
}
function jss_check
{
echo "<h3>Jss Availability</h3>"
echo "<pre>"
jamf checkJSSConnection
echo "</pre>"
}
function user_list
{
echo "<h3>User List</h3>"
echo "<pre>"
userList=$(dscl /Local/Default -list /Users UniqueID | awk '$2 >= 500 { print $1; }')
for i in $userList
do
echo "$(id -un $i) <> $(id -F $i)"
done
echo "</pre>"
}
function net_names
{
echo "<h3>Network Names</h3>"
echo "<pre>"
echo "ComputerName : $(scutil --get ComputerName)"
echo "HostName : $(scutil --get HostName)"
echo "LocalHostName : $(scutil --get LocalHostName)"
echo "NetBIOSName : $(defaults read /Library/Preferences/SystemConfiguration/com.apple.smb.server NetBIOSName)"
echo "</pre>"
}
function sw_update
{
theAUTODOWNLOAD=$(defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload)
if [ "$theAUTODOWNLOAD" == "1" ]
then
theAUTOD="True"
else
theAUTOD="False"
fi
theACECheck=$(defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticCheckEnabled)
if [ "$theACECheck" == "1" ]
then
theACE="True"
else
theACE="False"
fi
theCUICheck=$(defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist CriticalUpdateInstall)
if [ "$theCUICheck" == "1" ]
then
theCUI="True"
else
theCUI="False"
fi
theSECDATACheck=$(defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist ConfigDataInstall)
if [ "$theSECDATACheck" == "1" ]
then
theSECD="True"
else
theSECD="False"
fi
echo "<h3>Software Update Settings</h3>"
echo "<pre>"
echo "Automatic download updates? = $theAUTOD"
echo "Automatic update check enabled? = $theACE"
echo "Automatic Critical Update install? = $theCUI"
echo "Automatic Security & Data install? = $theSECD"
echo "</pre>"
}
function app_data
{
if [ -f /Applications/Adobe Acrobat XI Pro/Adobe Acrobat Pro.app/Contents/Info.plist ]
then
theAAP=$(defaults read /Applications/Adobe Acrobat XI Pro/Adobe Acrobat Pro.app/Contents/Info.plist CFBundleShortVersionString)
else
theAAP="Missing"
fi
if [ -e /Applications/Google Chrome.app ]
then
theChrome=$(defaults read /Applications/Google Chrome.app/Contents/Info.plist CFBundleShortVersionString)
else
theChrome="Missing"
fi
if [ -e /Applications/Firefox.app ]
then
theFirefox=$(defaults read /Applications/Firefox.app/Contents/Info.plist CFBundleShortVersionString)
else
theFirefox="Missing"
fi
if [ -f /Library/Internet Plug-Ins/Flash Player.plugin/Contents/Info.plist ]
then
theFlash=$(defaults read /Library/Internet Plug-Ins/Flash Player.plugin/Contents/Info CFBundleShortVersionString)
else
theFlash="Missing"
fi
if [ -f /Library/Application Support/Oracle/Java/Info.plist ]
then
theOracle=$(defaults read /Library/Application Support/Oracle/Java/Info.plist CFBundleShortVersionString)
else
theOracle="Missing"
fi
if [ -f /Applications/Microsoft Office 2011/Office/MicrosoftComponentPlugin.framework/Versions/14/Resources/Info.plist ]
then
theOffice11=$(defaults read /Applications/Microsoft Office 2011/Office/MicrosoftComponentPlugin.framework/Versions/14/Resources/Info CFBundleShortVersionString)
else
theOffice11="Missing"
fi
if [ -f /Applications/Sophos Anti-Virus.app/Contents/Info.plist ]
then
theSophos=$(/usr/libexec/PlistBuddy -c "print :ProductVersion:" /Library/Sophos Anti-Virus/product-info.plist)
else
theSophos="Missing"
fi
if [ -f /Applications/VMware Fusion.app/Contents/Info.plist ]
then
theVMWare=$(defaults read /Applications/VMware Fusion.app/Contents/Info.plist CFBundleShortVersionString)
else
theVMWare="Missing"
fi
echo "<h3>Application Data</h3>"
echo "<pre>"
echo "Acrobat Pro = $theAAP"
echo "Chrome = $theChrome"
echo "Firefox = $theFirefox"
echo "Flash = $theFlash"
echo "JavaO = $theOracle"
echo "Office 2011 = $theOffice11"
echo "Sophos AV = $theSophos"
echo "VMware Fusion = $theVMWare"
echo "</pre>"
}
# Begin script
cat > /Library/Application Support/MyCompany/report.html <<- EOF
<html>
<head>
<title>$theTitle</title>
</head>
<body>
<h2>$theTitle</h2>
<p>$theStamp</p>
$(system_info)
$(show_uptime)
$(drive_space)
$(jss_check)
$(user_list)
$(net_names)
$(sw_update)
$(app_data)
</body>
</html>
EOF
open /Library/Application Support/MyCompany/report.html
exit 0
Posted on 01-18-2016 11:58 PM
Thanks @Snickasaurus, been busy!
Just tried it on my Mac, worked perfectly!
Posted on 05-06-2016 08:07 AM
@davidacland Thanks, I know all too well what it's like to be super busy. Updated the script in original post. Give it a try and and let me know what you think.