Self Service policy to display a list of Static Groups and prompt for Mac serial number to add to one of them

sdagley
Honored Contributor II

I'm looking for a simple way to allow members of my org's Field Support group to enable software in Self Service for any of our managed Macs without actually giving them access to our JSS. I use a Static Group as a target for each installation Policy that isn't scoped to all computers, so what I'm envisioning is a shell script that will run an AppleScript to display a popup listing the available titles, and then prompt for the serial number of the computer to be added to the appropriate Static Group using the Classic API (that's the easy part).

I thought I'd seen something along these lines posted on Jamf Nation before (looking at you @dan-snelson), but darn if I can find it now. Before I re-invent the wheel I figured I'd see if it rang a bell with anyone else. Please post a reference if it does

Thanks!

7 REPLIES 7

dan-snelson
Valued Contributor II

Thanks for the shout-out, @sdagley.

While I haven't tackled your exact use-case — nor seemingly a use-case in its ballpark — the following may prove helpful:
- Your Internal Beta Test Program: Opt-in / Opt-out via Self Service
- Jamf Pro Policy Editor Lite


Proof-of-concept Script

#!/bin/bash

# Proof-of-concept to add computers to a Static Group via the API, based on the computer's serial number
# By: Leslie N. Helou & Dan K. Snelson

jssURL="https://jamfpro.company.com"
jssUser="apiUsernameWithReadWritePrivileges"
jssPass="SuperSecretPassword"
groupName="Group_Name_Without_Spaces"
serialNumber="C03DJ1XYH7WK"

#Submit to Jamf Pro server
echo "Adding Serial Number ${serialNumber} to ${groupName} ..."

/usr/bin/curl -sku ${jssUser}:${jssPass} ${jssURL}/JSSResource/computergroups/name/${groupName} -d "<computer_group><computer_additions><computer><serial_number>${serialNumber}</serial_number></computer></computer_additions></computer_group>" -X PUT -H "Content-Type: text/xml"


exit 0

--
Dan

jcarr
Contributor III

Having the Jamf Pro username and password in the script might not be the best idea.

Have you thought about a Self Service policy that simply executes a command the touch a file in /var/db (e.g. 'touch /var/db/.myconfig1')? Have the policy update inventory and set up an EA that looks for the presence of this file. You could then create a smart group for devices that have this file. You can have as many of these as you have different configs. You could also take it a step further and have a script that checks if the file is present, and if it is removes it, if not places it (so that it acts as a toggle).

Just a thought. Not exactly what you asked, but this may get you the same result.

mm2270
Legendary Contributor II

I think what you're looking for @sdagley is something like this?

#!/bin/bash

APIUSER="apiusername" ## Or replace with $4 to pass in as parameter
APIPASS="apipassword" ## Or replace with $5 to pass in as parameter
JSSURL="https://your.jamf.server.com"

STATIC_COMPUTER_GROUPS=$(curl -H "Accept: application/xml" -su "${APIUSER}:${APIPASS}" ${JSSURL}/JSSResource/computergroups | xmllint --format - | grep -B1 "<is_smart>false</is_smart>" | awk -F'>|<' '/<name>/{print $3}')

SELECTION=$(/usr/bin/osascript << EOD
tell application "System Events"
activate
set GroupList to do shell script "echo "$STATIC_COMPUTER_GROUPS""
set SelectionList to paragraphs of GroupList
choose from list SelectionList with prompt "Choose a group:"
end tell
EOD)

echo "$SELECTION"

## The rest of your script code goes here

The above will pull a list of your static groups from your server using the API, then pass that into an AppleScript call (converting it to a list) so it can be brought up in a dialog for someone to select.

The only thing about my code as is, is that it may not work without running the entire osascript part as the logged in user. Meaning you might have to throw in a launchctl asuser syntax as shown on many other threads to get it to work correctly. But since this is being run from Self Service, it also may just work as is.

sdagley
Honored Contributor II

@dan-snelson Thanks! It may have been your Jamf Pro Policy Editor Lite post I was thinking of, and that will make a good building block to start from.

@jcarr Thanks for the thought, but I specifically need to add a computer to a Static Group to fit into my existing workflow. I have already written multiple scripts to modify group memberships, and I do pass the name and password to access the API as encrypted parameters, but I was looking to steal borrow the code to prompt the user for which group and the machine to add to it.

sdagley
Honored Contributor II

@mm2270 Thanks for the input! I'll have a pre-defined list of potential groups as the ones I want the techs to have access to is a small subset of the complete list. And I'll add the launchctl asuser... to be on the safe side as I don't totally trust the context to be the user even when run from Self Service..

mm2270
Legendary Contributor II

Ok, if you have a predefined list, then it's even easier, since there won't be a need to call anything with the API. Just create an AppleScript defined list, like {"Item One","Item Two","Item Three"} etc. in place of the echo line.

AdamCraig
Contributor III

What may be an easier solution is we have several self service policies scoped to the users on our support team. So they can log into self service on anyones computer and then those options show up for them.

That being said this is my "add/delete computer from static group script"
If you don't want to provide API username or pass as variables then it will prompt the user who runs the self service policies for their jamf credentials. If you're techs are running this it may be a good option.

$4 = jamf static group ID
$5 = additions or deletions (needs to be exactly one of those strings to add or delete computers from the provided static group)
$6 = Jamf API user ID $7 = Jamf API user password
$8 = silent ( any string here will cause the script to not give onscreen alerts for success or failure)

#! /bin/bash

jamfproURL="https://companyname.jamfcloud.com"

default_group="918"

computer_name="$2"
current_user="$3"
silent="$8"



if [ -z $4 ]
    then
        groupid="$default_group"
    else
        groupid="$4"
fi

if [ -z $5 ]
    then
        action="additions"
    else
        action="$5"
fi

if [ -z $6 ]
    then
        APIUser=$(/usr/bin/osascript<<END
        tell application "System Events"
        activate
        set the answer to text returned of (display dialog "Please enter your Jamf Username:" default answer "" buttons {"Continue"} default button 1)
        end tell
        END)
    else
        APIUser="$6"
fi

if [ -z $7 ]
    then
        APIPass=$(/usr/bin/osascript<<END
        tell application "System Events"
        activate
        set the answer to text returned of (display dialog "Please enter your Jamf Password:" default answer "" with hidden answer buttons {"Continue"} default button 1)
        end tell
        END)
    else
        APIPass="$7"
fi

xml="<computer_group><computer_${action}><computer><name>$computer_name</name></computer></computer_${action}></computer_group>"

fullURL="${jamfproURL}/JSSResource/computergroups/id/${groupid}"

echo "Created XML"
echo $xml

echo "Jamf API URL"
echo $fullURL


result=$`curl "$fullURL" -u "$APIUser:$APIPass" -H "Content-Type: text/xml" -X PUT -d "$xml"`

echo "result"
echo "$result"

if [ -z $silent ] ; then
    if [[ "$result" == *"<p>The request requires user authentication</p>"* ]] ; then
        echo "Showing Fail message"
        /usr/bin/osascript -e 'tell app "System Events" to display dialog "Failed to update Static Group. Please check your network connection and try again."'
    else
        echo "Showing success message"
        dialog="${action} for the Static Group probably sucessful."
        cmd="Tell app "System Events" to display dialog "$dialog""
        /usr/bin/osascript -e "$cmd"
    fi
else
    echo "running silent No user notifications"
fi
exit 0