Does anyone know how I can use a RegEx in a smartgroup for devices less than 12.0.1
- Home
- Community
- Get Support
- General Discussions
- Regex for less than number in Smart Group
21 replies
- Author
- Honored Contributor
- 606 replies
- July 9, 2019
@pmendez No, I have an extension attribute to determine the version of OpenJDK installed
12.0.1 is the current version but I have some laptops that report in OpenJDK is not installed or the field is blank due to not executing the EA
So I'm looking at a way to ignore those with a blank field or those where OpenJDK is not installed
- Contributor
- 35 replies
- July 9, 2019
I am using our patch definition server to track OpenJDK Installs which I have setup with an EA that has been set not to match blank spaces as a requirement..
#!/usr/bin/env bash
##########################################################################################
# Collects information to determine which version of the Java JDK is installed by #
# looping through all the installed JDKs for the major version selected. And then #
# comparing the build number to determine the highest value. #
##########################################################################################
SEARCH_FOR_VERSION="12"
HIGHEST_BUILD="-1"
BUNDLENAME="AdoptOpenJDK"
RESULT="Not Installed"
installed_jdks=$(/bin/ls /Library/Java/JavaVirtualMachines/ )
for i in ${installed_jdks}; do
JAVA_VERSION=$( /usr/bin/defaults read "/Library/Java/JavaVirtualMachines/${i}/Contents/Info.plist" CFBundleVersion)
JAVA_BUNDLENAME=$( /usr/bin/defaults read "/Library/Java/JavaVirtualMachines/${i}/Contents/Info.plist" CFBundleName | awk '{ print $1 }')
MAJOR_VERSION=`/bin/echo $JAVA_VERSION | /usr/bin/cut -d '.' -f 1`
if [ "$BUNDLENAME" == "$JAVA_BUNDLENAME" ] ; then
if [ "$MAJOR_VERSION" == "$SEARCH_FOR_VERSION" ] ; then
RESULT=$( /usr/bin/defaults read "/Library/Java/JavaVirtualMachines/${i}/Contents/Info.plist" CFBundleGetInfoString | /usr/bin/awk '{print $2}' )
RESULT=${RESULT//+/-}
fi
fi
done
/bin/echo "<result>$RESULT</result>"
- Author
- Honored Contributor
- 606 replies
- July 10, 2019
So with my Smart group which is similar to yours I still get devices with a blank field in the group
I need a way to say IF you contain numbers AND are less than 12.0.1 for the criteria
- Author
- Honored Contributor
- 606 replies
- July 10, 2019
My EA code
#!/bin/sh
OpenJDKVersion=`/Library/Java/JavaVirtualMachines/jdk-12.0.1.jdk/Contents/Home/bin/java --version | sed 2,3d | cut -d ' ' -f 2`
# If the variable is empty then
if [ -z "$OpenJDKVersion" ]; then
echo "<result>$(printf "OpenJDKVersion isn't installed")</result>"
else
echo "<result>$(printf "${OpenJDKVersion}")</result>"
fi
- Hall of Fame
- 1798 replies
- July 15, 2019
This will get you anything 12.0.1 or higher: ^1[2-9].[0-9].[1-9]
A couple of caveats:
- only looks for a single digit in second and third decimal place (can add bracketed criteria for more places)
- if third place starts with a zero, it will not pick it up (i.e. 12.1.0)
Couple that with this for the blank: ^s*$
And that should get you what you want. Test it, of course.
- Hall of Fame
- 4293 replies
- May 1, 2020
@stevewood wish all software makers adhered to semantec versioning, that would make regex a lot easier.
EDIT: @mm2270 thanks for the heads up, Freudian slip...fixed typo.
- Community Manager
- 1911 replies
- May 1, 2020
Just posted this yesterday in another group. I have a script that does the opposite of the request — it generates a regex string identifying a specific version string or higher. But you can still create a smart group and either set its operator to "does not match regex" or use the smart group as an exclusion when scoping to get the same results.
There's more detail at the link above.
- Legendary Contributor
- 7884 replies
- May 1, 2020
@donmontalvo Your post confused me for a moment because of the word "symantec" in it. I thought, 'wait, Symantec has their own versioning that everyone should be using?' 🤔
Until I realized you meant "semantic". Kind of changes the meaning a bit. :)
Was that an auto-corrupt moment there, or was that just a habit spelling that came through?
- Hall of Fame
- 1798 replies
- May 1, 2020
And my regex-fu was off. I just use @talkingmoose script to create the regex now. ;-)

- Valued Contributor
- 67 replies
- May 4, 2020
^(1[0-1]|[1-9]).([0-9]).([0-9])|(12.0.[0-1])$
- Contributor
- 82 replies
- October 1, 2020
@stevewood
Similer pls advice in diffrent scenarios like V14.54.00
smanti v34.54.00
CID:12.23.45.32 STD:3.4.5 ID:2.3.4
- Hall of Fame
- 1798 replies
- October 1, 2020
Not sure I follow. I am no regex guru, more a regex newbie, so I don't know that I can help with those. Sorry.
- Jamf Heroes
- 3560 replies
- October 1, 2020
@mani2care See @talkingmoose's post above for what you need: https://www.jamf.com/jamf-nation/discussions/32562/regex-for-less-than-number-in-smart-group#responseChild201504
- Contributor
- 82 replies
- October 2, 2020
@stevewood thanks got it can try this script and catalina not working can able to help.
https://github.com/TravellingTechGuy/manageSecureTokens/blob/master/manageSecureTokens.sh
- Hall of Fame
- 1798 replies
- October 2, 2020
Typically DS Error
type errors are because the domain cannot be reached. I believe you need to be on a network that can connect to the domain controller to run that script. I haven't looked at that script. Make sure you're on the network, either on the acutal network or connected via VPN.

- Honored Contributor
- 2721 replies
- October 2, 2020
A different approach that some might be interested in, is to not use regex
at all. While regex
can be very powerful, it is also very fragile. Any change to the data you are parsing can and will break your regex
, which is why it is best suited for static data sets, or unstructured data that produces somewhat static format messaging.
zsh
has a built in called if-at-least
which you could easily edit in an EA and have it track "latest" versions
% ff_vers=$(mdls /Applications/Firefox.app -name kMDItemVersion -raw)
% echo $ff_vers
81.0
% autoload is-at-least
% if is-at-least 80.0 ${ff_vers}
if> then echo "Firefox meets minimum version"
then> fi
Firefox meets minimum version
While having to write a bunch of EAs is a good idea or not, Spotlight + is-at-least
will probably need way less engineering effort and get around the fragility of regex
. It is also super easy to maintain in comparison, and reduces risks of bugs because you are relying on Jamf's regex
to never break, while zsh
and Spotlight probably have a much lower risk of breaking.
I do think the real answer though is application state management, which I filed a FR for

- New Contributor
- 3 replies
- January 17, 2022
The original question was how to use Regex to find devices less than a certain version. All the answers gave 'greater than' results.
Fortunately this is easily achieved by using the 'greater than' regex but saying in the Smart Group criteria to return 'does not match regex' this therefore inverts the results and returns a list of 'less than' rather than 'greater than' answers.
- Hall of Fame
- 4293 replies
- January 17, 2022
I love it when @tlarkin posts new ways of doing things, seems like a good candidate for an EA template, assuming it works with version strings that don't adhere to semantic versioning guidelines.
The problem with either mdls/regex is that Open JDK includes the version in the path. So whether someone has one version installed, or multiple versions installed, the mdls/regex would need to be updated to work every time. I'm sure with enough logic an EA can be written to only look at the major version (X.x.x) and spit out the version. But then you'd need multiple major versions, if the goal is to keep that major version up to date and not roll back.
I only got started with regex a couple years ago, but most of the time I use https://regex101.com or https://regexr.com to cobble together strings. When I create a string, I try to keep the string as visually clear as possible so others on our team can look at it and have a fairly easy time understanding it.
This string coupled with matches regex will identify computers that have 12.0.1 or higher, all the way to 99.9.9.
^(12\\.0\\.[1-9]|12\\.[1-9]\\.[0-9]|1[3-9]\\.[0-9]\\.[0-9]|[2-9][0-9]\\.[0-9]\\.[0-9])&
- Honored Contributor
- 376 replies
- June 12, 2024
Just posted this yesterday in another group. I have a script that does the opposite of the request — it generates a regex string identifying a specific version string or higher. But you can still create a smart group and either set its operator to "does not match regex" or use the smart group as an exclusion when scoping to get the same results.
There's more detail at the link above.
@talkingmoose - thanks William. The link doesn't seem to go to your script any more but I found it in your Github repository. I cannot thank you enough. Not only does it figure out the regex but it shows you the regex growing as it works through it. It really helped me set up a smart group for zoom version less than 5.10.0
- Community Manager
- 1911 replies
- June 12, 2024
@talkingmoose - thanks William. The link doesn't seem to go to your script any more but I found it in your Github repository. I cannot thank you enough. Not only does it figure out the regex but it shows you the regex growing as it works through it. It really helped me set up a smart group for zoom version less than 5.10.0
Thanks for the nice words, @dlondon. :-)
Not sure why that link is going where it’s going, but for future visitors looking for something like it, I’ll add the link here:
Does anyone know how I can use a RegEx in a smartgroup for devices less than 12.0.1
Are you referring less than macOS 12.0.1?
@pmendez No, I have an extension attribute to determine the version of OpenJDK installed
12.0.1 is the current version but I have some laptops that report in OpenJDK is not installed or the field is blank due to not executing the EA
So I'm looking at a way to ignore those with a blank field or those where OpenJDK is not installed
I am using our patch definition server to track OpenJDK Installs which I have setup with an EA that has been set not to match blank spaces as a requirement..
#!/usr/bin/env bash
##########################################################################################
# Collects information to determine which version of the Java JDK is installed by #
# looping through all the installed JDKs for the major version selected. And then #
# comparing the build number to determine the highest value. #
##########################################################################################
SEARCH_FOR_VERSION="12"
HIGHEST_BUILD="-1"
BUNDLENAME="AdoptOpenJDK"
RESULT="Not Installed"
installed_jdks=$(/bin/ls /Library/Java/JavaVirtualMachines/ )
for i in ${installed_jdks}; do
JAVA_VERSION=$( /usr/bin/defaults read "/Library/Java/JavaVirtualMachines/${i}/Contents/Info.plist" CFBundleVersion)
JAVA_BUNDLENAME=$( /usr/bin/defaults read "/Library/Java/JavaVirtualMachines/${i}/Contents/Info.plist" CFBundleName | awk '{ print $1 }')
MAJOR_VERSION=`/bin/echo $JAVA_VERSION | /usr/bin/cut -d '.' -f 1`
if [ "$BUNDLENAME" == "$JAVA_BUNDLENAME" ] ; then
if [ "$MAJOR_VERSION" == "$SEARCH_FOR_VERSION" ] ; then
RESULT=$( /usr/bin/defaults read "/Library/Java/JavaVirtualMachines/${i}/Contents/Info.plist" CFBundleGetInfoString | /usr/bin/awk '{print $2}' )
RESULT=${RESULT//+/-}
fi
fi
done
/bin/echo "<result>$RESULT</result>"
So with my Smart group which is similar to yours I still get devices with a blank field in the group
I need a way to say IF you contain numbers AND are less than 12.0.1 for the criteria
My EA code
#!/bin/sh
OpenJDKVersion=`/Library/Java/JavaVirtualMachines/jdk-12.0.1.jdk/Contents/Home/bin/java --version | sed 2,3d | cut -d ' ' -f 2`
# If the variable is empty then
if [ -z "$OpenJDKVersion" ]; then
echo "<result>$(printf "OpenJDKVersion isn't installed")</result>"
else
echo "<result>$(printf "${OpenJDKVersion}")</result>"
fi
This will get you anything 12.0.1 or higher: ^1[2-9].[0-9].[1-9]
A couple of caveats:
- only looks for a single digit in second and third decimal place (can add bracketed criteria for more places)
- if third place starts with a zero, it will not pick it up (i.e. 12.1.0)
Couple that with this for the blank: ^s*$
And that should get you what you want. Test it, of course.
@stevewood wish all software makers adhered to semantec versioning, that would make regex a lot easier.
EDIT: @mm2270 thanks for the heads up, Freudian slip...fixed typo.
Just posted this yesterday in another group. I have a script that does the opposite of the request — it generates a regex string identifying a specific version string or higher. But you can still create a smart group and either set its operator to "does not match regex" or use the smart group as an exclusion when scoping to get the same results.
There's more detail at the link above.
@donmontalvo Your post confused me for a moment because of the word "symantec" in it. I thought, 'wait, Symantec has their own versioning that everyone should be using?'
Until I realized you meant "semantic". Kind of changes the meaning a bit. :)
Was that an auto-corrupt moment there, or was that just a habit spelling that came through?
And my regex-fu was off. I just use @talkingmoose script to create the regex now. ;-)
^(1[0-1]|[1-9]).([0-9]).([0-9])|(12.0.[0-1])$
@stevewood
Similer pls advice in diffrent scenarios like V14.54.00
smanti v34.54.00
CID:12.23.45.32 STD:3.4.5 ID:2.3.4
Not sure I follow. I am no regex guru, more a regex newbie, so I don't know that I can help with those. Sorry.
@mani2care See @talkingmoose's post above for what you need: https://www.jamf.com/jamf-nation/discussions/32562/regex-for-less-than-number-in-smart-group#responseChild201504
@stevewood thanks got it
can try this script and catalina not working can able to help.
https://github.com/TravellingTechGuy/manageSecureTokens/blob/master/manageSecureTokens.sh
Typically DS Error
type errors are because the domain cannot be reached. I believe you need to be on a network that can connect to the domain controller to run that script. I haven't looked at that script. Make sure you're on the network, either on the acutal network or connected via VPN.
A different approach that some might be interested in, is to not use regex
at all. While regex
can be very powerful, it is also very fragile. Any change to the data you are parsing can and will break your regex
, which is why it is best suited for static data sets, or unstructured data that produces somewhat static format messaging.
zsh
has a built in called if-at-least
which you could easily edit in an EA and have it track "latest" versions
% ff_vers=$(mdls /Applications/Firefox.app -name kMDItemVersion -raw)
% echo $ff_vers
81.0
% autoload is-at-least
% if is-at-least 80.0 ${ff_vers}
if> then echo "Firefox meets minimum version"
then> fi
Firefox meets minimum version
While having to write a bunch of EAs is a good idea or not, Spotlight + is-at-least
will probably need way less engineering effort and get around the fragility of regex
. It is also super easy to maintain in comparison, and reduces risks of bugs because you are relying on Jamf's regex
to never break, while zsh
and Spotlight probably have a much lower risk of breaking.
I do think the real answer though is application state management, which I filed a FR for
The original question was how to use Regex to find devices less than a certain version. All the answers gave 'greater than' results.
Fortunately this is easily achieved by using the 'greater than' regex but saying in the Smart Group criteria to return 'does not match regex' this therefore inverts the results and returns a list of 'less than' rather than 'greater than' answers.
I love it when @tlarkin posts new ways of doing things, seems like a good candidate for an EA template, assuming it works with version strings that don't adhere to semantic versioning guidelines.
The problem with either mdls/regex is that Open JDK includes the version in the path. So whether someone has one version installed, or multiple versions installed, the mdls/regex would need to be updated to work every time. I'm sure with enough logic an EA can be written to only look at the major version (X.x.x) and spit out the version. But then you'd need multiple major versions, if the goal is to keep that major version up to date and not roll back.
I only got started with regex a couple years ago, but most of the time I use https://regex101.com or https://regexr.com to cobble together strings. When I create a string, I try to keep the string as visually clear as possible so others on our team can look at it and have a fairly easy time understanding it.
This string coupled with matches regex will identify computers that have 12.0.1 or higher, all the way to 99.9.9.
^(12\\.0\\.[1-9]|12\\.[1-9]\\.[0-9]|1[3-9]\\.[0-9]\\.[0-9]|[2-9][0-9]\\.[0-9]\\.[0-9])&
Just posted this yesterday in another group. I have a script that does the opposite of the request — it generates a regex string identifying a specific version string or higher. But you can still create a smart group and either set its operator to "does not match regex" or use the smart group as an exclusion when scoping to get the same results.
There's more detail at the link above.
@talkingmoose - thanks William. The link doesn't seem to go to your script any more but I found it in your Github repository. I cannot thank you enough. Not only does it figure out the regex but it shows you the regex growing as it works through it. It really helped me set up a smart group for zoom version less than 5.10.0
@talkingmoose - thanks William. The link doesn't seem to go to your script any more but I found it in your Github repository. I cannot thank you enough. Not only does it figure out the regex but it shows you the regex growing as it works through it. It really helped me set up a smart group for zoom version less than 5.10.0
Thanks for the nice words, @dlondon. :-)
Not sure why that link is going where it’s going, but for future visitors looking for something like it, I’ll add the link here:
Match Version Number or Higher
Reply
Related topics
CustomerInfo is nullicon
SDKsRandomly and false-zero-Entitlements returned from purchaseProduct:withCompletionicon
SDKsWeb SDK Purchase custom metadata is always null in the event details and related webhook eventicon
SDKsEntitlementInfo is null.icon
General QuestionsError Fetching Offerings Post-Flutter Upgrade: Null Type Cast Exceptionicon
General Questions
Most helpful members this week
- Chubs
44 likes
- ktrojano
18 likes
- ThomM
17 likes
- mattjerome
15 likes
- AJPinto
13 likes
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.
Scanning file for viruses.
Sorry, we're still checking this file's contents to make sure it's safe to download. Please try again in a few minutes.
OKThis file cannot be downloaded
Sorry, our virus scanner detected that this file isn't safe to download.
OKCookie policy
We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.
Cookie settings
We use 3 different kinds of cookies. You can choose which cookies you want to accept. We need basic cookies to make this site work, therefore these are the minimum you can select. Learn more about our cookies.