Script to launch self service from policy

John_Arenz
New Contributor II

Documentation and course materiaal provides this script to Display a message to a user, if they click OK, then open Self Service.

messageToDisplay="$4"
policyToExecute="$5"
policyAction="$6"

buttonClicked=$(osascript << EOF
button returned of (display dialog "$messageToDisplay" buttons {"OK", "Cancel"} default button 1)
EOF)

if [[ "$buttonClicked" == "OK" ]];then
open "jamfselfservice://content?entity=policy&id=$5&action=$6"
fi

However, this fails when the script is run in a policy, due to the JSS running the script as root instead of currentUser. Working with Jamf support we were able to make the modification below, which allows the script to run as intended when deployed via policy.

messageToDisplay="$4"
policyToExecute="$5"
policyAction="$6"
currentUser=$(ls -l /dev/console | awk '{ print $3 }')

buttonClicked=$(sudo -u $currentUser /usr/bin/osascript<<END

tell application "System Events"
activate
set the answer to button returned of (display dialog "$messageToDisplay" buttons {"OK", "Cancel"} default button 1)
end tell
END)

if [[ "$buttonClicked" == "OK" ]];then
sudo -u $currentUser open "jamfselfservice://content?entity=policy&id=$5&action=$6"
fi

5 REPLIES 5

wesleya
Contributor

Nice, I wasn't sure if you could use open with "jamfselfservice://", but I'll file this one away for sure.

dpertschi
Valued Contributor

@John_Arenz Don't fall in love with osascript > System Events; that's going to break in Mojave and generate user consent dialogs.

wesleya
Contributor

Also true! Is that not one that can be OK'd using MDM?

Looks like it's possible, I can't test at the moment though:

https://derflounder.wordpress.com/2018/08/31/creating-privacy-preferences-policy-control-profiles-fo...

cbd4s
Contributor II

I've managed to use the script below under user login for opening self service link. This should work when pushed out as root through policy.

#!/bin/sh

echo ""

## If the script is not run as root, exit and fail the script 
USER_ID=`id -u`

if [ "$USER_ID" -ne 0 ]; then
    echo "You must be root to run the script. Use sudo $0"
    exit 1
fi

## Wait for a user to log in
CONSOLE_USER=`stat -f "%Su" /dev/console`

echo "($(basename "$0")) - Checking user login session every 5 minutes..."
while [ "$CONSOLE_USER" = "root" ] || [ "$CONSOLE_USER" = "" ]
do
    sleep 300
    CONSOLE_USER=`stat -f "%Su" /dev/console`
done
CONSOLE_USERFULL=$(id -F "$CONSOLE_USER")
CONSOLE_HOME=`eval echo ~${CONSOLE_USER}`
console_user_id=`id -u ${CONSOLE_USER}`


echo "($(basename "$0")) - Current logged in user is $CONSOLE_USERFULL($CONSOLE_USER, $console_user_id)"

## Check the LOCKED_SCREEN_STATE every minute until it is empty which means the screensaver is not on and the screen is not locked
LOCKED_SCREEN_STATE=$(/bin/launchctl asuser "$console_user_id" sudo -u "$CONSOLE_USER" /usr/bin/python -c 'import sys,Quartz; d=Quartz.CGSessionCopyCurrentDictionary(); print d' | grep "CGSSessionScreenIsLocked")
echo "($(basename "$0")) - Checking Locked Screen State every 1 minute..."

while [ -n "$LOCKED_SCREEN_STATE" ]
do
    sleep 60
    LOCKED_SCREEN_STATE=$(/bin/launchctl asuser "$console_user_id" sudo -u "$CONSOLE_USER" /usr/bin/python -c 'import sys,Quartz; d=Quartz.CGSessionCopyCurrentDictionary(); print d' | grep "CGSSessionScreenIsLocked")
done

echo "($(basename "$0")) - $CONSOLE_USER logged in and the screen is not locked. Continuing..."

/bin/launchctl asuser "$console_user_id" sudo -u "$CONSOLE_USER" /usr/bin/open "jamfselfservice://content?entity=policy&id=0000&action=view"

exit 0      ## Success
exit 1      ## Failure

Thanks @cbd4s your script worked for what I wanted to do.

I can now have a shell script call Jamf Self Service and trigger the install of a VPP app. However I would like to add one more thing to the process which is to automatically quit Jamf Self Service after it has done this.

Clearly I also need to make sure the script does not quit it too soon i.e. before it has done the install otherwise it might stop or interrupt the install process.

In some cases in a script this is as simple as having first the command do something followed on the next line with an exit command as it will only run the next line after the process of the first line has finished. In this case I do not believe this would work as the Self Service app is forked as a separate process so the script is immediately going to the next line.

So, it would seem to do this properly there needs to be some way to detect the completion of the install and then send a specific command to Self Service telling it to quit. Whilst a sleep and then quit might work most of the time there is the possibility the install might on some occasions take longer than the sleep interval and you would not necessarily want an excessively long sleep for those few occasions.

 

So any ideas from anyone?