Sending notifications with Yo Scheduler & Jamf

Backoffice
New Contributor III

Hi all, for anyone who uses Yo, I was wondering if someone could give me the best way to do this. I have pushed out the pkg to all machines complete with images for the notifications .... and from there I have been pushing a script from Jamf to send out the notifications

i.e.

yo_scheduler -t "A Google Chrome update is availible", however, the notification seems to fail on all machines

Is there a better way to do this than I am currently attempting?...

1 ACCEPTED SOLUTION

Asnyder
Contributor III

Try running the full path to the binary.

/Applications/Utilities/yo.app/Contents/MacOS/yo --title test --subtitle 'This is a test.'

I'm not sure where the scheduler part lives

View solution in original post

19 REPLIES 19

danreedphoto
New Contributor III

-t, --title[title text] Required: The main title for the notification. The title is topmost in the notification, with the heaviest fontface, and has a limited length of 34 characters, after which an ellipsis (e.g. '...') is shown.

Asnyder
Contributor III

Try running the full path to the binary.

/Applications/Utilities/yo.app/Contents/MacOS/yo --title test --subtitle 'This is a test.'

I'm not sure where the scheduler part lives

mm2270
Legendary Contributor III

What is yo_scheduler? I know of Yo and use it, but not really sure what the "scheduler" part is, unless you renamed it to that or something?

Incidentally, I ran into the same issues when trying to use Yo initially. It turns out the Yo app (and subsequently the script that calls it) must be run as the user, not under root. If your policy is calling the Yo app at the Recurring Check-in trigger, that is being run by the Jamf LaunchDaemon and runs completely as root, so it doesn't work. I had to come up with a script that can accept passed parameters for the text strings, button labels and such, and craft the command on the fly and run it as the logged in user (if someone is logged in)
I can post the script I use here with some stuff "genericized" for public consumption if it will help.

prbsparx
Contributor II

I'm trying to do this exact same thing right now.

I've gotten as far as being able to get a notification to appear AFTER I run sudo Jamf policy myself... but if I just let Jamf's standard running process run it, it fails.

I made ALOT of tweaks to the existing files:
- Added my own images.
- Changed the product identifier and signed it with my own certificate.
- Updated all the LaunchAgents and Daemons with the new product identifier information.
- Changed the path for where it gets installed.
- Edited the PKG preinstall script so it unloads the LaunchAgents.
- Edited the PKG postinstall script so it loads the LaunchAgents.
- Updated the PathState value to reflect the new Product Identifier

I tried running yo_scheduler as the current GUI user, but that didn't seem to work. I'm testing running it as root now.

If you want to chat on the macadmins slack and see if we can pool our brain power, I'd be glad to "let our powers combine"

mpermann
Valued Contributor II

@mm2270 I'd be interested in seeing the script you're using if you don't mind sharing. Thanks!

kendalljjohnson
Contributor II

@mm2270 You commented on a post I had about doing this and I think I've found a solution with a different tool.

Alerter is a similar tool but allowed me to have a quit button actually quit the app, and waits for user input before proceeding with the script. I've been out of the office a bit lately and haven't had a chance to write up my workflow for others to test out. I'll try and get to it today and post the link here.

My workflow scopes to devices not on a desired version. Then if the app is closed the install proceeds, if it is open a notification pops up with the option to defer or quit the app. The quit button quits the app then triggers the install. When the install is complete a 2nd notification appears saying the update is complete, with the option to re-open the app or simply acknowledge it's complete.

mm2270
Legendary Contributor III

@kendalljjohnson Sure, I'd like to see the workflow once you can post it up. I'm not sure if I'll end up using it, but I'm always interested to see things like that.

@mpermann As for the script I mentioned, below is a version using the generic Yo.app. I actually created a custom Yo build with our name and icon on it that I'm using, but the below should work for the regular Yo app, or you can customize the path to the executable.

#!/bin/bash

## Script parameters
Title="$4"            ## Title for Yo notification (Required)
Msg="$5"              ## Message for Yo notification (Required)
Btn="$6"              ## Custom button name (Optional, but button name should be set if using a button action)
BtnAct="$7"           ## Action for button (Optional)

## Path to the script to run
scriptRunDir="/private/var/scripts/"

## Create the directory to house the script if not present
if [ ! -d "$scriptRunDir" ]; then
    mkdir -p "$scriptRunDir"
fi

## Path to Yo.app or custom version of the tool. Must include path to the executable
Yoapp="/Library/Application Support/JAMF/bin/Yo.app/Contents/MacOS/Yo"

## Check to make sure the app is where it should be or we can't do much
if [ ! -e "$Yoapp" ]; then
    echo "Yo application could not be found in the expected location. Must exit."
    exit 1
fi

## Check to make sure a title and message string were passed to the script
if [[ -z "$Title" ]] || [[ -z "$Msg" ]]; then
    echo "Either the Title or Message strings have been left blank. Please enter a value for Title in $4 and a message value in $5 and try again."
    exit 1
fi

## Get Logged in User name
loggedInUser=$(stat -f%Su /dev/console)

## Get Logged in User UID
loggedInUID=$(id -u "$loggedInUser")

## Make sure someone is logged in or no message display is possible
if [[ "$loggedInUser" == "root" ]] && [[ "$loggedInUID" == 0 ]]; then
    echo "No user is logged in. Skipping display of notification until next run."
    exit 0
fi

## This function runs the temp script as the logged in user
function runScriptAsUser ()
{

/bin/launchctl asuser "$loggedInUID" sudo -iu "$loggedInUser" "/private/var/scripts/Yo_run.sh"

}

## This function creates a temp script to run Yo with the parameters and text strings passed to the main script
function createScript ()
{

cat << EOD > /private/var/scripts/Yo_run.sh
#!/bin/bash

$(echo "${contents}")

EOD

/bin/chmod +x /private/var/scripts/Yo_run.sh

runScriptAsUser

}


## Create the script contents based on if a button string was passed and/or a button action was also passed
if [[ ! -z "$Btn" ]] && [[ ! -z "$BtnAct" ]]; then
    echo "Creating notice with button + action"
    contents=""${Yoapp}" -t "${Title}" -n "${Msg}" -b "${Btn}" -B "${BtnAct}" -z "None" -p"
    createScript
elif [[ ! -z "$Btn" ]] && [[ -z "$BtnAct" ]]; then
    echo "Creating notice with button only"
    contents=""${Yoapp}" -t "${Title}" -n "${Msg}" -b "${Btn}" -z "None" -p"
    createScript
elif [[ -z "$Btn" ]]; then
    echo "Creating notice with no custom button"
    contents=""${Yoapp}" -t "${Title}" -n "${Msg}" -z "None" -p"
    createScript
fi

Essentially the only effective way I found to do this was to pipe out to a local script and then have that script run as the user. The script checks the options passed by parameter to it and creates an appropriate script based on whether it's a standard notification with no custom button or one with a custom button and/or with an action attached to that button.

If I ever come up with a better way to do this without needing to create a script to run from locally, I'll post back with a new version.

kendalljjohnson
Contributor II

@mm2270 Here's what I came up with, open to any feedback or suggestions!

Custom Patch Management Workflow

mpermann
Valued Contributor II

@mm2270 thanks for sharing your script! I'm wondering if you've come up with a way to prevent users from changing the Yo alert style from Alerts to Banners or None in System Preferences -> Notifications -> Yo? It appears that you can change it to either Banners or None and you will no longer have a persistent notification which is what I'm trying to achieve. I'm curious if you are seeing the same behavior in your environment or not.

mack525
Contributor II

@mm2270 Great work on this script.. I am running into an issue where the script runs but the listed action does nothing. I've tried running this using our custom Yo build and the generic build just to make sure it was not me.

818c5921a8ee4425b9fe9fa893f0433b

Am i missing anything? any pointers on this would be appreciated. We are now resorted to bugging our users to update.

mm2270
Legendary Contributor III

Hi @mack525. Off the top of my head, I'd say change the "action" parameter string to something like:

open jamfselfservice://content?entity=policy&id=35&action=view

I think the open is needed or Yo may not know how to handle the link on it's own. When you send a Self Service link like that via email, the email application typically knows it's a hyperlink and will instruct the OS to attempt to open it, but with Yo you probably need to be more specific, by using that open command in front of the link.
You also shouldn't need the quote marks, since the entire parameter string should be passed to the Yo application with quotes around it based on how I designed that script.

Give that a try and see if it helps.

mack525
Contributor II

@mm2270 Thank you for the quick response. Tried putting the open but still nothing.

i was actually able to run this through Files and Processes with the below command

/Applications/Utilities/yo.app/Contents/MacOS/yo -t "Microsoft Word" -s "Self Service Updates" -b "Update" -a "jamfselfservice://content?entity=policy&id=35&action=view"

mm2270
Legendary Contributor III

@mack525 Ok, just curious, but did that work for you? Meaning, did it open Self Service and go to the policy description? I ask because in my quick testing, I had some trouble getting Yo to open that link all the way to its end result. It opened Self Service, but the description wasn't coming up for me in the app. Meaning the "view" portion of that URL was being ignored.

I found out that to get it to work, either in Yo, or in a direct command line call, meaning if you run Yo directly in Terminal and use a URL like that, that the & and ? characters need to be escaped. For some reason in an email it's fine to use the URL as is, but with a shell program, they have to be escaped. So something like the following, passed to the parameter, will probably work:

jamfselfservice://content?entity=policy&id=35&action=view

Hope that helps.

mack525
Contributor II

@mm2270 that actually did not work within the script either. Oddly enough i am now getting this strange error.

cf84e103af664389b8945bbdf362cab3

Even though the application is installed.

wildfrog
Contributor II

Barring that, is there a jamfselfservice:// handler which would take the user to the Activity tab of Self Service?

mack525
Contributor II

@wildfrog i dont think a handler is needed. On any JAMF enrolled device with.. you should and we've been able to use the package URLS. Unless i am not understanding you correctly.

mm2270
Legendary Contributor III

@mack525 I'm not sure what may not be working for you, but in case it helps, I've had this running on recurring check-in, set to Ongoing as a test scoped to my 10.14.3 Mac, and it works fine. When I click the button, it opens Self Service to the description of this policy.

07ac25b21c4e4db68737ac1c292b956d

Oh, and that's not a vertical pipe at the end of the string. Just my cursor while I was in the field that got captured in the screenshot.

Looking back at my last post, I realized I forgot to mention you still need the open part of the command. It's not enough to put the URL in there, even when the characters are properly escaped. I guess Yo just doesn't know what to do with those links since they are not the usual things like mailto: or http, www etc.

wildfrog
Contributor II

@mack525 I didn't know if a jamfselfservice command that opened Self Service to the Activity tab - thereby displaying the available updates would suffice. . . if such a command exists.

mm2270
Legendary Contributor III

@wildfrog I don't think that's possible yet. See this Feature Request, which is kind of similar to what you're asking.