Regex for less than number in Smart Group

Cayde-6
Release Candidate Programs Tester

Does anyone know how I can use a RegEx in a smartgroup for devices less than 12.0.1

19 REPLIES 19

pmendez
New Contributor III

Are you referring less than macOS 12.0.1?

Cayde-6
Release Candidate Programs Tester

@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

Stevie
Contributor

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..

403cb933b494468c89faf14964d6de00

#!/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>"

Cayde-6
Release Candidate Programs Tester

So with my Smart group which is similar to yours I still get devices with a blank field in the group
f2c51b84d25c4f419bdea51ffe582ab0

I need a way to say IF you contain numbers AND are less than 12.0.1 for the criteria

Cayde-6
Release Candidate Programs Tester

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

stevewood
Honored Contributor II
Honored Contributor II

@Cayde-6

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.

donmontalvo
Esteemed Contributor III

@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.

--
https://donmontalvo.com

talkingmoose
Moderator
Moderator

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.

mm2270
Legendary Contributor III

@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?

stevewood
Honored Contributor II
Honored Contributor II

And my regex-fu was off. I just use @talkingmoose script to create the regex now. ;-)

cbd4s
Contributor II

^(1[0-1]|[1-9]).([0-9]).([0-9])|(12.0.[0-1])$

mani2care
Contributor

@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

stevewood
Honored Contributor II
Honored Contributor II

@mani2care

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.

sdagley
Esteemed Contributor II

mani2care
Contributor

@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
1a3f79fde454475d9f3ee9b6d167d1ce

stevewood
Honored Contributor II
Honored Contributor II

@mani2care

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.

tlarkin
Honored Contributor

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

johnatzilch
New Contributor II

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.

donmontalvo
Esteemed Contributor III

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])&

--
https://donmontalvo.com