running script through Casper Remote not working , but works fine locally!

jamesdurler
Contributor

hello,

I have written a script which executes a policy and uses terminal notifier to notify the user of an installation.

because terminal notifier cannot run during the login window, i check the currently logged in user, if the user is root (assume we are at the login window) , execute the policy and create a text file on the local machine, otherwise we are logged in and run the policy with terminal notifier.

i then have a while loop which checks the existence of such a file and verifies the user is not root and then displays a terminal notifier window.

Executing the script from terminal on the machine works perfectly fine…. however, as soon as I run the script through terminal it runs the script and nothing happens, its almost like it doesn't execute anything. I may be missing something simple here but I have tried to emulate the conditions locally by executing as root in the terminal.

Has anyone seen anything like this before? I am receiving no error logs when the policy runs, the last message I am left with is Running script……. and then it times out.

here is the code:

#!/bin/bash

#Define policy id + policy name pid="3342" policyName="Garageband 10.0.1"

declare -x TERMINALNOTIFIER="/usr/local/scripts/terminal-notifier.app/Contents/MacOS/terminal-notifier"

currentUser=/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'

#Now perform the installation based on the current user

if [ $currentUser = "root" ]; then #we are at the login window so we can't run terminal notifier

echo "Installation of $policyName began at" $(date) >> /usr/local/scripts/"$pid".txt /usr/sbin/jamf policy -id "$pid" echo "Installation of $policyname Completed at" $(date) >> /usr/local/scripts/"$pid".txt

else

echo "normal user is logged in, so we can use terminal notifier!"

$TERMINALNOTIFIER -message "Currently Installing $policyName" -title "Application Install In Progress" /usr/sbin/jamf policy -id "$pid" && $TERMINALNOTIFIER -message "Installed $policyName" -title "Application Install Successful"

fi

#check for the presence of the policy file as this is only created if policy is ran at the loginwindow #if we see it and the user is not root we can open terminal notifier to inform the user of an app install/installation while [ -f /usr/local/scripts/"$pid".txt ]
do sleep 30 currentUser=/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'

if [ $currentUser != "root"] then #we logged in display a notification #get the last non empty line of the text file we created installProgress=$(awk '/./{line=$0} END{print line}' /usr/local/scripts/"$pid".txt) if [[ $installProgress = *began* ]] then /usr/local/scripts/terminal-notifier.app/Contents/MacOS/terminal-notifier -message "Currently Installing $policyName" -title "Application Install In Progress" else /usr/local/scripts/terminal-notifier.app/Contents/MacOS/terminal-notifier -message "Installed $policyName" -title "Application Install Successful" rm /usr/local/scripts/"$pid".txt exit 0 fi
fi

done

1 ACCEPTED SOLUTION

mm2270
Legendary Contributor III

I've run into this myself when I was working on deploying terminal-notifier. The trick to getting this to work is to get the process ID of the logged in user and use that in a launchctl bsexec command.

Here are the relevant lines you need to incorporate into your script.

## Get the PID of the current user
loggedInPID=$( ps -axj | awk "/^$currentUser/ && /Dock.app/ {print $2;exit}" )

## Display terminal-notifier message
/bin/launchctl bsexec "${loggedInPID}" sudo -iu "${currentUser}" ""$TERMINALNOTIFIER" -message "Currently Installing $policyName" -title "Application Install In Progress""

Note how the entire command from $TERMINALNOTIFIER to the end is enclosed in double quotes and the double quotes within the command, for example around your text strings, are escaped with backslashes.
Those are important details to pay attention to.

Give that a try and see if it works.

View solution in original post

7 REPLIES 7

jamesdurler
Contributor

For some reason calling terminal-notifier via casper remote does not seem to work, but works absolutely fine locally!

jamesdurler
Contributor

done some more digging apparently its because when the script is executed via casper its doing it as root and because that user doesn't have a GUI its falling over. Not sure why I can run it as root at terminal however?

mm2270
Legendary Contributor III

I've run into this myself when I was working on deploying terminal-notifier. The trick to getting this to work is to get the process ID of the logged in user and use that in a launchctl bsexec command.

Here are the relevant lines you need to incorporate into your script.

## Get the PID of the current user
loggedInPID=$( ps -axj | awk "/^$currentUser/ && /Dock.app/ {print $2;exit}" )

## Display terminal-notifier message
/bin/launchctl bsexec "${loggedInPID}" sudo -iu "${currentUser}" ""$TERMINALNOTIFIER" -message "Currently Installing $policyName" -title "Application Install In Progress""

Note how the entire command from $TERMINALNOTIFIER to the end is enclosed in double quotes and the double quotes within the command, for example around your text strings, are escaped with backslashes.
Those are important details to pay attention to.

Give that a try and see if it works.

acdesigntech
Contributor II

+1 -- casper remote is going to run everything as your casper management user elevated with sudo, so it's technically running terminal-notifier.app - you just can't see it. The solution is to run it in the user's context so they can see and react to it.

Careful though, I've had super inconsistent luck getting anything that relies on user context to run through Casper remote. Sometimes it works and sometimes not, ymmv.

jamesdurler
Contributor

hi guys, thanks for this . This seems to make it work, however as @acdesigntech said I've found it to be hit and miss. Big improvement from where i was yesterday however, the script actually executes now ! :D

jacob_salmela
Contributor II

I have been using this for a while and it seems to be working:

#!/usr/bin/python
#-----------IMPORTS----------
import sys,pwd,os
import subprocess
from platform import mac_ver

#----------VARIABLES---------
v, _, _ = mac_ver()
v = float('.'.join(v.split('.')[:2]))

# Use Casper Parameters 4-7
title = sys.argv[4]
subtitle = sys.argv[5]
message = sys.argv[6]
group = sys.argv[7]

#------------------------------     
#-------BEGIN SCRIPT-----------
#------------------------------ 
if (v == 10.9) or (v == 10.10):
    u = os.getlogin()
    if ( u == '_atsserver') or ( u == 'root'):
        print u + " owns the loginwindow--no notification will be sent."
    else:
        print u + " owns the loginwindow--sending notification..."
        pw = pwd.getpwnam(u)
        os.initgroups(u,pw.pw_gid)
        env={"TERM":"xterm","USER":pw.pw_name,"HOME":pw.pw_dir,"SHELL":pw.pw_shell,"LOGNAME":pw.pw_name,"PATH":"/usr/bin:/bin:/opt/bin"};
        os.setgid(pw.pw_gid);
        os.setuid(pw.pw_uid);
        os.execve('/Applications/Hopkins Tech Support.app/Contents/MacOS/notifier',["","-title",title,"-subtitle",subtitle,"-message",message,"-group",group],env);
else:
    print "Notifications not supported version " + str(v)

sean
Valued Contributor

Haven't tried the python version, but if you prefer bash and need an alternative for 10.11

Run as console user