As Thomas Larkin pointed out, Casper is already doing this with Recon and
reporting back to the main database (which should be running every week or
so by default), and you can use this for inventory and smart groups, you'll
find it in the Smart Group (or Advanced Search Criteria section), in the
Software Information section, then you can use a combination of Application
Title and Application Version to make a group/report on what you want...
Also, CFBundleShortVersionString is what you want to get for version number.
If you get CFBundleGetInfoString it is littered with copyright symbols and
other stuff that would make it hard to use the 'is/is not/like/not like'
criteria on it.
However I've been looking for the opportunity to share some code 🙂
I made an EA template, copy and paste and past into a text editor save it
with a name ending in .xml in:
If it's world readable I think it'll work, but I like keeping things neat so
it should also be owned by user _appserver and group _appserveradmin
If you don't want to go that far and this is a one off, just copy everything
in the <scriptContentsMac> tags and never mind about making it a template,
just put the app's path in the APPPATH variable. (I did because I made one
for Receipt Versions, which this is based off of, I'll include that too).
You may or may not want it to return a value if it can't find the
Info.plist, or if it finds it, the key may not exist and you may want to
return a value besides 'null' (FYI: JAMF has told me they recommend, because
blank value will match for 'is not', you can get around this by adding a
'not like' and leaving it empty, or having another criteria to match as
Anyway on with the code:
#Get Info String.xml
<?xml version="1.0" encoding="UTF-8"?>
<extensionAttribute> <displayName>Get Info String</displayName> <displayInCategory>System Information</displayInCategory> <dataType>string</dataType> <description>This attribute reports the value of CFBundleGetInfoString
from the specified Application path's Contents/Info.plist</description> <scriptContentsMac>#!/bin/bash
if [ -e "$APPPATH/Contents/Info.plist" ]; then
result=$(defaults read "$APPPATH/Contents/Info" CFBundleGetInfoString
else result="Not Found"
And to share if anyone thinks that not only getting the names of receipts on
the system is useful BUT ALSO THE VERSIONS is important (as I do!) let JAMF
know you'd like this to be a feature in the future, because Frameworks,
printers drivers, and many other aspects of installed software are not as
easily ascertained, either its too "noisy" when collecting Application
versions and plugins (a dev can have multiple Flash Player plugins that trip
up the system), or just certain things aren't reported on (printer drivers,
etc...). I think getting the receipt version does this elegantly and nicely.
Note this is best used in conjunction with "Packages Installed By
Installer.app/SWU" and the bundle name because I prefer to have nothing
returned if the receipt is not found....
<?xml version="1.0" encoding="UTF-8"?>
<extensionAttribute> <displayName>Receipt Version</displayName> <displayInCategory>Software Updates</displayInCategory> <dataType>string</dataType> <description>This attribute displays the value of the specified bundle's
receipt value on the client computer</description> <scriptContentsMac>#!/bin/bash
if [ -e /var/db/receipts/$BUNDLEID.plist ]; then
result=$(defaults read /var/db/receipts/$BUNDLEID PackageVersion
else #otherwise use pkg_util, only 10.6 reports on non apple packages and is
slow result=$(pkgutil --pkg-info $BUNDLEID 2>/dev/null | grep version | awk
Creative Technology Specialist
233 N. Michigan Ave. Ste 1500
Chicago, IL 60601
Mac Helpdesk: 312-596-2757
I already do know that NORMALLY you'd do the exact steps you describe, I
do that all the time. Unfortunately this vendor ONLY puts the version
number in the get info field, which is why I need to capture the data in a
special way. Had they put the version info where it belongs, none of this
would be necessary! You are right though, for all other vendors, if I
pulled this field I'd get garbage.
I adapted Ben Toms script and added it in to an extension attribute and
it's grabbing the info now so as Ben did, I'll pass along my edits below.
Thanks to all who helped out.
As the script will point out, this is for Promethean's Inspire
application, for Interactive Whiteboards. I know a lot of other districts
use this, so hopefully this will be of help. We're at a point now where
teachers haven't been upgrading their software as it had been decided it
would only be offered on a self-service basis and they'd be reminded.
That's not working now as we have versions all over the place.
if [ -e /Applications/Promethean/Activsoftware
Inspire/Inspire.app/Contents/Info.plist ]; then
result="$(defaults read /Applications/Promethean/Activsoftware
echo "Not installed"
I wouldn't bother with an extensions attribute. You know which app it is so write a script, that you can push out, to correct the Info.plist file.
defaults read [path to file] CFBundleGetInfoString
and place that into a variable, followed by
defaults write [path to file] CFBundleShortVersionString [variable]
Place it in a policy that reads CFBundleShortVersionString first and if it isn't there, then run the above script. That way, Casper will pick up the version like it does for everything else and the packages will always be updated automatically.
Of course, if you were to correct the info string before making a package to push out to your machines, then it would be correct by the time it gets to each machine and you wouldn't need any scripting.