Skip to main content
Jamf Nation, hosted by Jamf, is the largest Apple IT management community in the world. Dialog with your fellow IT professionals, gain insight about Apple device deployments, share best practices and bounce ideas off each other. Join the conversation.

Smart computer group application version compare with greater than & less than

It would be great to have a smart group check for software version using greater than or less than.

This would be most helpful for those pesky updates that only apply to certain versions of software. For Office 2011, you could use these new smart groups to target the 14.1 update to computers with version 14.0 and greater than 14.0, but less than 14.1 and target the 14.1.4 update to computers with version 14.1.0 or greater.

Posted: by erin.miska

As a few users have explained below, many software titles are versioned in such a way that makes this problematic. For example, when a version has more than one decimal point or includes a letter, "greater/less than" determinations are tough to automate.

However with the new patch reporting functionality in 9.93, we have cataloged the versions of 34 third-party software titles, allowing us to reliably perform "greater/less than” calculations for these titles. You can now use “greater/less than” as the operator for smart groups based on any of these titles.

Order by:

Posted: by talkingmoose

The whole "like" and "not like" is coming from MySQL's pattern matching syntax not the JAMF folks. Their page to create smart groups is just a web accessible way of creating a pattern match.

You can accomplish the same thing by adding additional patterns:

Application Title   has     Microsoft
and Application Version like        14.1.
and Application Version is not      14.1.4

Posted: by acostj

You can sit there all day adding versions would't it just be easier to get a greater than and less than option? I think in a previous version I was able to do this. Don't see it now but it was way back almost 2 years ago. It had a greater than and less than option for version checking. My problem now is when a user goes and gets a new version on his own Casper thinks he has an old version and auto installs the version in Casper or the user goes thru Self Service and reinstalls his version.


Posted: by talkingmoose

Don't get me wrong. I'm not saying that "greater than" or "less than" wouldn't be useful. It's certainly more human friendly. The search in JSS just isn't implemented in a way to support it.

I have no idea how easy or how difficult translating the "like" and "not like" syntax of MySQL to the "greater than" and "less than" syntax would be but some rework would definitely have to be done and I'd bet it's not minor.

Also, I was wrong to call this "pattern matching". I should have called it "comparison".


Posted: by janhy

Doesn't MySQL have greater than and less than operators?

select application_title, application_version from application_table where application_title = '' and application_version < 11;


This would be a nice feature...currently trying to create a custom search to show me all computers with firefox versions less than 11. The advanced application search doesn't even let me do a non-matching search, which would work, in this case.


Posted: by jarednichols

I believe MySQL has greater than and less than operators. The problem is when you get things like "3.6.16". Then it's no longer able to handle this as a number. Do you know any numbers with two decimal points? Humans can make the determination easily. MySQL, not so much.


Posted: by PeterClarke

I have used Application Version testing in smart group rules, and found "like" to work well…
I recognised this very problem... And have constructed a rule to tell me which machines had Office 2011 Vn 14 installed, which was not Vn 14.1.4

Example Smart Group:

Application Title (has) Microsoft Word (and) Application Version (is) 14.1.2

Shows me which machines had Vn 14.1.2 installed

You could similarly do:

Application Title (has) Microsoft Word
(and) Application Version (is not) 14.1.4

Would show all those NOT with Vn 14.1.4

Using < 14.1.4 would -- CORRECTLY NOT WORK --
Because "14.1.4" is a string, not a Number

So you have to use the string comparison operators
ie one of: (Is), (is not), (like), (not like)

And then it works well...


Posted: by PeterClarke

Addendum: Another case would be:

Application Title (has) Microsoft Word
(and) Application Version (is like) 14
(and) Application Version (is not) 14.1.4

That would be able to distinguish between Office-2008 (Vn 12.x) and Office-2011 (Vn 14.x),
and would show those machines with Office-2011, where work was not Vn 14.1.4, while also excluding any incidences of Office-2008 (or earlier)


Posted: by yr_joelbruner

This is sort of similar to my request here:

Recon/JSS: Collect Package Receipt versions and treat as its own data type

The version numbers as a type didn't fly \- but the other half of it is for the JSS to collect receipt versions, so you can base a policy of a single receipt version number, rather than a collection of app versions (Office got really messy back in 2004 with varying version numbers among its apps)

So if anyone likes this, vote mine up too ;)


Posted: by mhatch14

For smart groups, I just want greater than, equal or less than for number/integer comparisons. Is that easier to do? It would be nice to have it for version numbers, as stated above, but I just want it for simple integers. "Is greater than 5" or "is less than 16". Is that any easier to accomplish?


Posted: by krichterjr

I too wish this was built into the JSS as an option. Since it's not, I've actually used EA's to grab the version number then within the EA script removed the decimal points.

For instance, I used @talkingmoose (thanks btw) EA to grab the current version of Office and make it an integer.


if [ -f "/Applications/Microsoft Office 2011/Office/MicrosoftComponentPlugin.framework/Versions/14/Resources/Info.plist" ] ; then
    VERSION=`defaults read "/Applications/Microsoft Office 2011/Office/MicrosoftComponentPlugin.framework/Versions/14/Resources/Info.plist" CFBundleShortVersionString  | sed 's/[.]//g'`
    VERSION="Not installed"
echo "<result>$VERSION</result>"

From there my smart groups can us greater than/less than via the EA's. It's kind of a shame that I have to go that route as opposed to using the built in Application versions in the JSS. I like it this way though so I don't have to have a page full of "is like" 14, but is not 14.3.1, 14.3.2., etc...


Posted: by MARL

JAMF can do this, we have to do the same thing, meaning create our own solution that JAMF simply just delivers the payload and sucks up our own attributes. I agree this would be great to have it built in.


Posted: by MARL

The NOT PLANNED comment at the top is just silly. Ok so it's a string. You have the delimiter right there, a period. Break the version up into an array and then perform your greater than or less than logic on each element working your way down. Crazy simple, why get hung up on "it's a string"?


Posted: by spalmer

@clarkml I agree it is doable, and I voted this up a while back as well, but I have come to realize it is not quite as simple as parsing out just a period. There are many developers that use the short version string incorrectly, including big developers like Adobe who can't even be consistent between all of the applications they offer. Here is a sample of incorrectly done applications I found from just two computers on our JSS:

Box Sync 4.0.4443 (e8d6b92)

Adobe Audition CC

Adobe Edge Code CC

Adobe Fireworks CS6
Adobe Fireworks CS6 version

Adobe Illustrator
682 (This is the build number not the actual version number. In Creative Cloud they switched to using the actual version number, like 17.1.0, without changing the application name to "Adobe Illustrator CC" so how do you compare those?)

Adobe Photoshop Lightroom 5
Adobe Photoshop Lightroom 5.3 [938183]

CD Spin Doctor

ExtendScript Toolkit

5.7.3 (5H683, Web Store)

Focal Point
2.0.9b (Suite 6.1)

JMP 10

License Manager
"6.1" (yes, they actually left the quotes in the version info string)

Sketchup 8.0


Wacom Tablet Utility

So as you can see sometimes you need to interpret the developers intentions with their version numbering system and you can make assumptions and programmatically figure out a large majority of it but some of it is not as easy to interpret. Build numbers and other text should be safe to drop off when comparing but you can't always be sure.

It also begins to be a lot of work on the server side if you need to interpret version strings every time you do a comparison. You could have the jamf binary interpret the version string at inventory time but it would make it less readable for JSS admins. It might be possible to have a secondary version field in the JSS that stores the interpreted version info for comparisons in Smart groups and such.


Posted: by loceee

I understand the problem, but penalising all apps for the crimes of a few isn't the way to deal with this. We should all be able to capture a certain level of non-complaint Office versions with a simple < 14.4.1 comparison.

For my money.... keep the current viewable version field in the table.

Create a new generated non viewable integer comparison field per app.

Parse scraped version \# like this, strip non-numerics \* 1000000000000 (or whatever is acceptable to truncate too)
\- anything with alphabetics can be flagged as "too hard" and this internal field set to "0". The JSS GUI would handle this by simply non allowing comparisons for these apps.

Please consider this.


Posted: by cvgs

Yes, please consider this.

Problem understood, but still i'd like to work it most of the time than never at all \- the admin is still in control of when to use a comparison (Office) or when not (some of the misbehaved applications above).

Right now we create an Extension Attribute for each Application that is of interest to us. We can hand-craft this attribute so that it always contains a proper version number, but still there is no way of properly comparing this value against a known version number.
This is quite frustrating, as we always have to future-proof your smart groups (like "EA not like "14.4.1" and EA not "14.4.2" and EA not like "15.") to prevent accidental group changes (at least as there is no version 15 released).

Or provide a completely new and enhanced way for patch management. I'm sure there is something happening in version 10, right?


Posted: by spalmer

Another possible way to do this would be to create a lookup table that could be managed by the JSS administrator. This table would do basic substitutions so that the JSS is doing less work translating strings. As data is reported back to inventory the version is looked up in this table and the, lets call it "Display Version", that was uploaded by the client is translated to the "Actual Version" and both versions are stored in the inventory records for that computer. This may be more work up front but it would save a lot of time during policy creation.

To take it even further so that there is less duplication of effort this could be a table that is updated daily from a central source, like JAMF. And if JAMF didn't want to do all of the work managing these version numbers this could something that is maintained by the JAMF Nation community. It could even be an extension of the "Third-Party Products" area of JAMF Nation.


Posted: by loceee

Here's a quick proof of concept and some sample data that comes out, even with junk version data from some apps. For what we are after, > < comparisons... it would work.



appabspath=( $(find /Applications -name "*.app" -type d -maxdepth 2) ) 
for app in ${appabspath[@]}
    vers=$(defaults read "$app/Contents/Info.plist" CFBundleShortVersionString  2> /dev/null)
    [ "$vers" == "" ] && continue
    versint=$(echo $vers | sed 's/[^0-9]*//g')
    if (( len > comparelen ))
        verscomp=$(echo $versint | cut -c-$comparelen)  
        verscomp=$(echo $versint | sed -e :a -e "s/^.\{1,$comparelen\}$/&0/;ta")
    echo "app:         $app"
    echo "versionstring:   $vers"
    echo "versionint:  $versint"
    echo "verscompare: $verscomp"


app:        /Applications/Adobe/Adobe
versionstring:  4.0.244
versionint: 40244
verscompare:    40244000000
app:        /Applications/Adobe Acrobat X Pro/Acrobat
versionstring:  10.1.10
versionint: 10110
verscompare:    10110000000
app:        /Applications/Adobe Acrobat X Pro/Adobe Acrobat
versionstring:  10.1.10
versionint: 10110
verscompare:    10110000000
app:        /Applications/Adobe Bridge CS6/Adobe Bridge
versionint: 5024
verscompare:    50240000000
app:        /Applications/Adobe Extension Manager CS6/Adobe Extension Manager
versionint: 60828
verscompare:    60828000000
app:        /Applications/Box
versionstring:  4.0.5059 (16f0d65)
versionint: 40505916065
verscompare:    4050591606
app:        /Applications/
versionstring:  10.8
versionint: 108
verscompare:    10800000000
app:        /Applications/
versionstring:  7.0
versionint: 70
verscompare:    70000000000
app:        /Applications/
versionstring:  3.5.4 (6790)
versionint: 3546790
verscompare:    35467900000
app:        /Applications/Utilities/
versionstring:  0.9.9 x86_64
versionint: 0998664
verscompare:    09986640000
app:        /Applications/
versionint: 084124355986
verscompare:    0841243559
app:        /Applications/Serato DJ
versionstring:  DJ version 1.7.0
versionint: 170
verscompare:    17000000000
app:        /Applications/Serato
versionstring:  DJ version 1.6.3
versionint: 163
verscompare:    16300000000
app:        /Applications/Mac Game
versionstring:  2.2.0  [Build 114]
versionint: 220114
verscompare:    22011400000
app:        /Applications/iTouchMidi
versionstring:  iTouchMidi OSX 1.4.5
versionint: 145
verscompare:    14500000000


I picked out a bunch that had build #s and even some that had software names and architecture info in the version string. All of which, when processed with this example, would do version comparisons using this method.

So, hide this as an internal field and process it. Push the majority of the processing on to the clients during the recon, and the JSS only needs to process the criteria we put in for comparisons.

Version comparisons are now cool, even for 99% of the naughty apps?


Posted: by loceee

With the exception of when major versions roll over from single to double digits of course.... but that's not all that common and further smarts could be introduced to solve that.


Posted: by acdesigntech

Responded: 25/07/13 at 22:50 by john.miller The comment by PeterClarke regarding the string vs a number comparison is the underlying issue. For example, 10.1.2 is actually less than 9.1.1, because of how string comparisons evaluate text.

Well thats disappointing. Also kind of feels like a cop-out. If the community can come up with ways of comparing version strings, surely the team of devs at JAMF can...

What about pulling the version info as a string and separating it out into major, minor, and patch versions? You probably wouldn't need to compare more than the major versions, but if they are the same, then you compare minor, patch, and so on. I KNOW this data can be separated out into table fields since I've done it myself in past lives. Casper already collects App version info, so the coding changes are completely doable.


Posted: by clifhirtle

I am just trying to get OS X versions above 10.8.4. @talkingmoose][/url does not appear your Office approach will work for OS X \- I get everything other than the "not like" version stated.

Other than specifying every potential future version of OS X as an OR like match, is there an a more direct way to get to OS X version above XYZ value? At least with OS X the version enumeration should be fairly consistent, yes?

Scratch that, this approach appears to work:

external image link


Posted: by talkingmoose


The only Mountain Lion version above 10.8.4 is 10.8.5. You can express that directly.

I see no way to specify an OS "greater than" something because that's not one of the operations built into the JSS. You could probably accomplish something like that with a scripted extension attribute but I think it would be easier just to add a line for each subsequent OS version.

Operating System    is  10.8.5
or  Operating System    like    10.9.
or  Operating System    like    10.10.

I'm guessing on that last line but that should get what you're asking. No? (No, sir, I have not checked my work.)


Posted: by clifhirtle

Thanks @talkingmoose. See my edit above. Going the other way around seems to work. Ex: stating the OS versions below the desired versions and including a "like" statement for the broader OS brings the desired results.


Posted: by BVikse

I too have also written code to parse integer values from strings to properly compare their values. In fact this was one of the first assignments as a freshman in a computer science course. We did it in Java 5 if that gives you any idea how long ago that was. We even got so far as to include alphabetic information in the comparison, just assign it a value 0-25. That made the code a bit more complex, comparing characterwise instead of integerwise, but still doable with a freshman's knowledge of code.


Posted: by cdenesha

Application Title (has) Microsoft Word (and) Application Version (is) 14.1.2

I'm curious.. Are you saying this works for Computer Smart Groups?

I've found that on the Mobile Devices side this would not create a proper Smart Group, because it matches the app name and then the version number for any app \- not the version number of Microsoft Word.




Posted: by BVikse


Yes the method quoted there works for Smart Computer Groups. I have not tried a similar trick for iOS, but that is how I scope policies for the Computer side.


Posted: by mzago

Just ran into this today with a smart group being used to upgrade old Flash versions. This is a feature that really would appeal to a great number of administrators so that we aren't forced to script up solutions or rely like logic that falls down when version numbers increase to unexpected version numbers.


Posted: by PeterClarke

You CAN get around this problem - at the COST of using an extension attribute...

If you use you own extension attribute, populated by a script,
then of course you can apply any logic you like.

I have sometimes used this (mostly in scripts - rather then in scripts populating extension attributes)
to convert awkward things like OS_Version, it's possible to extract just the middle part for instance
eg 10.10.1 & 10.9.3 => 10 and 9 respectively..

Other times I've wanted the 'whole thing' e.g. Vs
It that case, convert to 'simulated integer' => 13773 Vs 13253
Then it's easy to output that value for comparison.

Sometimes 'zero' packing is required, to make such strings of equal length.
an example would be Vs 13.5 a problem here is the different lengths..

Here the 13.5 needs 'inflating' to 135000 to compare it with 130234
So that both items have the same number of digits, then an integer comparison can be done.
- Or such an integer value returned by an extension attribute.

Yes, this kind of thing is an awkward solution, -- but at least it -IS- a solution...

In order to compare them - you do need to use "custom logic",
because of the wide variety of different formats...
So it depends on 'what' you want to compare with 'what'..


Posted: by claw

Any movement on this feature request? Other than it being Not Planned...
This would make patching alot easier.


Posted: by __Milton__

any update? this is a very badly missing feature that can cause issues due to inaccurate scoping!
Also feels like a basic feature to have in 2016...


Posted: by talkingmoose

The reply to the original feature request pretty much says why this isn't possible and marked as "NOT PLANNED".

Terms like "greater than" and "less than" apply to numbers. What you're trying to evaluate are not numbers.

While something like 10.0 is a valid number, something like 10.0.1 is not a valid number because it has two decimal points.

Something like 10.0.b is also not a valid number because numbers contain, well, numbers and not letters.


Posted: by spalmer

@erin.miska Thank you for taking a stab at this and moving this from Unplanned to Partially Planned. I do understand the issues at hand but I think that if other tools like Munki or SCCM can do something similar then so could JAMF.

I don't use SCCM but when talking with our Windows admins there is a feature called Supersedence and it is something I wish we had on the Mac side (maybe Munki does something similar). Basically it is letting the IT Admin define what the current application version replaces. For example you would define that Firefox 45.0.1 replaces Firefox 45.0.0 (and you previously defined that Firefox 45.0.0 replaced 44.0.2, etc.). So when Munki/SCCM discovers that a Mac has Firefox 44.0.0 installed it looks up that version and sees 44.0.0 is superseded by version 44.0.1 which is superseded by 44.0.2 which is superseded by version 45.0.0 which is superseded by 45.0.1 which is the current version because nothing else supersedes it. And as you can see this entire operation of lookups did not rely on comparing version numbers with numeric comparisons (<, >, =).

I hope that as you think about how to implement this that you will make it configurable/customizable by IT admins so that we are not stuck with a limited number of applications at the beginning. I am not trying to take a dig at JAMF but you guys are busy and I think something like defining supersedence (or whatever JAMF ends up doing) is best customized by the admin that knows their software situations very well. It would be a large task to define this for a large number of applications (and in the case of some applications like Firefox or Chrome a very large number of versions), but once the initial work is done I think it would flow pretty well. It may even be good to make this pull from a community supersedence database that could be stored on JAMF Nation to help speed up the initial setup.

Supersedence also allows some other pretty nice features:
1. It also ensures that, for the Firefox example above, that if somebody created a policy that installed Firefox and they accidentally selected the an older version like 35.0.0 it would do a look up in the supersedence database and install Firefox 38.0.0 instead.
2. It has the ability to mark whether a previous version of the application should be upgraded/patched or uninstalled and reinstalled (with the new version).
3. You can also define that a different application from a completely different vendor replace a previous application. This could be useful in scenarios where the old application (or company itself) no longer exists or if, for example, you replace your site license of Adobe Photoshop with Pixelmatr.
4. Supersedence allows you do define how to check what version of an application is installed. For example, if you know it is a drag-n-drop install it can just simply check the version number of the application installed in the Applications folder. If it was installed via a package installer it could do a look up of the package information via the following command:

pkgutil --pkg-info

Please look at the following references for further information.
How to Use Application Supersedence in Configuration Manager
The Application Model in the real world: Supersedence


Posted: by milesleacy

It's probably been mentioned before, but using "starts with" logic on the version strings would be helpful. For Example, Microsoft versions 15.22.0 and 15.22.1 both "start with" "15.22"


Posted: by donmontalvo

I really hope we get metadata fields, so we can enter proper versions, where a vendor's dev team may have smoked a doobie the day they designed Info.plist....not naming names....just sayin'...

$ defaults read /Applications/Aspera\ CFBundleVersion
$ defaults read /Applications/Aspera\ CFBundleShortVersionString

Munki lets you set version string on import, no reason JAMF can't.



Posted: by Look

Why doesn't JAMF just inventory both of the values, I have found in my scripts one or the other almost always gets the job done.
Then for the more technical of us we could use.
Application CFBundleVersion less/greater ...
Application CFBundleShortVersionString less/greater ...
As we felt appropriate for the application in question.


Posted: by donmontalvo

This is why we have EAs for both CFBundleShortVersionString and CFBundleVersion.

Even the best software companies have bad days...don't want to get caught with our pants down (again)...

Spot check...

$ defaults read /Applications/Microsoft\ CFBundleShortVersionString
$ defaults read /Applications/Microsoft\ CFBundleVersion

Posted: by marck

Someone from Jamf should be able to code this up in an afternoon. Version comparison of apps for doing updates has long been established. This should not be hard to do.

Every app that might live in /Applications contains a plist that has a CFBundleVersion in it. From Apple documentation - "The string should only contain numeric (0-9) and period (.) characters. Leading zeros are truncated from each integer and will be ignored (that is, 1.02.3 is equivalent to 1.2.3)."

So any developer using anything other than numbers in CFBundleVersion had done it incorrectly. CFBundleShortVersionString also indicates that only integers should used.


Posted: by donmontalvo

@marck I agree, many vendors don't follow Apple's guidelines, or even existing standards, or they try but their rotating door of Windows devs tasked with "Just making it happen on Mac" rotates too fast. Adobe, Microsoft, etc. Metadata fields would help here, assuming JSS can take the string we enter and do a comparison.