Adobe Remote Update Manager HUD notification

Adminham
New Contributor III

Decided to share a setup I've created to easily keep our Adobe installs up to date (because packaging with Adobe CCP once a year is enough!).
For our labs, we package our Adobe install with RUM enabled, which allows use the RemoteUpdateManager command line tool. Great! but it's not the most polished tool..

Enter Adobe-RUM-Interface.sh, combined with LoginWindow_MessageHUD.sh to give a notification that updates are running.
credit to @jmahlman for his initial Adobe-RUMWithProgress script, which I have built on here.

In a single policy with startup & recurring triggers I've added the following scripts:

Before
LoginWindow_MessageHUD.sh
script parameters:
$4 (title) "MAINTENANCE"
$5 (image) "adobe"
$6 (description) "Updating Adobe Apps..."

#!/bin/bash
# JamfHelper Loginwindow HUD

# Varibles
lastreboot=`uptime | awk '{print "Last reboot was: " $3 " " $4  }' | sed -e 's/.$//g'`
heading="$4"      # This shows up above the image in a bigger bolder font than the description field
image="$5"        # Options are as follows [ install | sync | update | alert ] each give you a diffrerent image (nothing is maintenance)
description="$6"  # This shows up below the image in a smaller lighter font than the heading field
iconpath="/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/"

# Default settings if none is passed through the variable
if [ "$4" == "" ]; then
    title="MAINTENANCE"
fi

if [ "$5" == "" ]; then
    iconpath="/System/Library/CoreServices/Installer.app/Contents/Resources/Installer.icns"
fi

if [ "$6" == "" ]; then
    description="Please do not login or reboot"
fi


# Case statement to assign specific graphic.
case $image in
            sync )
                icon="Sync.icns"
                ;;
            info )
                icon="ToolbarInfo.icns"
                ;;
            alert )
                icon="AlertStopIcon.icns"
                ;;  
            adobe )
                iconpath=""
                icon="/Applications/Utilities/Adobe Application Manager/core/Adobe Application Manager.app/Contents/Resources/AdobeApplicationManager.icns"
                ;;  
esac


# Script contents

# create local LaunchAgent with all parameters for message display
# this is required, as security restrictions forbid jamfhelper from running anywhere but locally

defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "Disabled" -bool false
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "KeepAlive" -bool false
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "Label" -string nz.ac.edu.loginwindowHUD
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "LimitLoadToSessionType" -string LoginWindow
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "ProgramArguments" -array
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "ProgramArguments" -array-add -string "/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "ProgramArguments" -array-add -string "-windowType"
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "ProgramArguments" -array-add -string "hud"
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "ProgramArguments" -array-add -string "-lockHUD"
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "ProgramArguments" -array-add -string "-windowPosition"
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "ProgramArguments" -array-add -string "lr"
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "ProgramArguments" -array-add -string "-title"
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "ProgramArguments" -array-add -string "$title"
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "ProgramArguments" -array-add -string "-description"
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "ProgramArguments" -array-add -string "$description"
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "ProgramArguments" -array-add -string "-icon"
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "ProgramArguments" -array-add -string "$iconpath$icon"
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "ProgramArguments" -array-add -string "-startlaunchd"
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "QueueDirectories" -array
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "RunAtLoad" -bool false
defaults write /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist "WatchPaths" -array

launchctl load -Fw -S LoginWindow /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist
launchctl start nz.ac.edu.loginwindowHUD
#remove plist after being used
rm -rf /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist

# debugging
echo "Title = $4"
echo "Description = $6"
echo "Image = $5"
echo "Icon Path = $iconpath"
echo "Icon Path + Icon = $iconpath$icon"


exit 0

After
Adobe-RUM-Interface.sh
script parameters:
$4 (silentinstall) "YES"

#!/bin/bash
#
#
# Created by John Mahlman, University of the Arts Philadelphia (jmahlman@uarts.edu)
# Previous name: Adobe-RUMWithProgress
# Modified by Hamish Ward
# Name: Adobe-RUM-Interface
#
# Purpose: This script uses CocoaDialog to show which updates are available for Adobe CC and asks
# if they would like to install those updates.  If they choose to install updates it will
# show a progress bar to the user and begin installing updates. The progress bar doesn't change,
# it's only there to show the user that something is actually happening.
#
# If silentinstall is enabled (in $4 script variable), the script will forego CocoaDialog requirement &
# automatically apply avalible updates (with no user interaction required) if no one is logged in. 
# There will be a JAMF notification in the lower right of the screen.
# Adding this functionallity makes this a dual purpose script for our Lab deployment & Self Service in Lab & Staff environments.
# 
#
# Changelog
#
# 9/8/17   - Added link to channel ID list from Adobe
# 8/31/17  - Just some cleaning up
# 8/29/17  - Added a "caffeinate" command when installing updates to stop systems from sleeping during long installs
# 6/19/17  - Removed the "wait" command at the end because it was just causing things to hang
#                   - Added some sleep 0.2 lines to allow the script some time to catch up
#                   - Fixed Dreamweaver channel ID
#                   - Added jamf_bin to determine which jamf binary to use
# 3/23/17  - Added more to "super-echo" to make it nicer for the user to read what's available for updates
# 2/21/17  - Cleaned up script to make it in line with my styling.
# 12/10/17 - hward  - renamed to Adobe-RUM-Interface
#                   - added silentinstall option (installUpdatesSilent function) & logged in user check
#                   - added log file
#
#
#

# VARIABLES
#
currentuser=$( ls -la /dev/console | cut -d " " -f 4 )
icons=/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources
rumlog=/var/tmp/RUMupdate.log # mmmmmm, rum log
CD_APP=/Library/Scripts/edu/tools/CocoaDialog.app
CocoaDialog=$CD_APP/Contents/MacOS/CocoaDialog
oldRUM=/usr/sbin/# this is where RUM used to live pre-10.11
rum=/usr/local/bin/RemoteUpdateManager # post-10.11
jamf_bin=`/usr/bin/which jamf`
logfile=/var/log/AdobeRUM-$(date +%Y%m%d-%H%M).log
silentinstall="$4"

# Redirect stdout ( > ) into a named pipe ( >() ) running "tee"
exec > >(tee -i $logfile)
exec 2>&1

echo "current user: $currentuser"
if [ "$silentinstall" == "yes" ]; then
    echo "silentinstall enabled"
else
    echo "user install"
fi

#######

# Installer function
installUpdates ()
{
    # Let's caffinate the mac because this can take long
    caffeinate -d -i -m -u &
    caffeinatepid=$!

    # create a named pipe
    rm -f /tmp/hpipe
    mkfifo /tmp/hpipe
    sleep 0.2

    # create a background job which takes its input from the named pipe
    $CocoaDialog progressbar --indeterminate --float --icon-file "$icons/Sync.icns" 
        --title "Adobe Remote Update Manager Interface" --text "Downloading and Installing Updates, this may take some time..." 
    --width "500" --height "115" < /tmp/hpipe &

    sleep 0.2
    # associate file descriptor 3 with that pipe and send a character through the pipe
    exec 3<> /tmp/hpipe

    echo -n >&3

    # log to stdout available updates
    echo "$(date) Updates available :"
    echo "$rumlog"

    # trigger RUM updater now
    $rum --action=install

    # now turn off the progress bar by closing file descriptor 3
    exec 3>&-
    rm -f /tmp/hpipe

    # No more caffeine please. I've a headache.
    kill "$caffeinatepid"

    exit 0
}

######

# silent update option
installUpdatesSilent ()
{
    # Let's caffinate the mac because this can take long
    caffeinate -d -i -m -u &
    caffeinatepid=$!

    # log to stdout available updates
    echo "$(date) Updates available :"
    echo "$rumlog"

    # trigger RUM updater now
    echo "$(date) silentinstall"
    $rum --action=install

    # No more caffeine please. I've a headache.
    kill "$caffeinatepid"

    # kill onscreen notification
    killall jamfHelper

    exit 0
}

echolog()
{
echo $1
echo $1 >> $logfile
}

#######

# HUD Notification cleanup
killHUD ()
{
    if [ -e /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist ]; then
        rm -rf /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist
        launchctl unload -Fw -S LoginWindow /Library/LaunchAgents/nz.ac.edu.loginwindowHUD.plist
    fi
}

#############
#  Script   #
#############

# old RUM installed?
if [ -f $oldRUM ] ; then
    rm -rf $oldRUM
fi

# new/current RUM installed?
if [ ! -f $rum ] ; then
    echo "Installing RUM from JSS"
    $jamf_bin policy -event installRUM
    if [ ! -f $rum ] ; then
        echo "Couldn't install RUM! Exiting."
        killHUD
        exit 1
    fi
fi

# if no user is logged in & silentinstall flag is "yes"
# install all available updates automatically with no UI
if [ "$currentuser" == "root" ]; then
    if [ "$silentinstall" == "yes" ]; then
        echo "no one logged in & silentinstall enabled.."
        # run RUM and output to the log file
        touch $rumlog
        $rum --action=list > $rumlog
        # run updates, if any exist
        if [ "$(grep "Following Updates are applicable" $rumlog)" == "Following Updates are applicable on the system :" ] ; then
        echo "updates found, installing silently.."
            installUpdatesSilent
        else
            echo "no updates to install"
            # kill onscreen notification
            killall jamfHelper
            killHUD
            exit 0
        fi
    else
        echo "silentinstall not enabled, not updating anything."
        killHUD
        exit 1
    fi
else
    echo "user logged in, present UI with available updates.."
fi

# does CocoaDialog Exist?
if [ ! -f $CocoaDialog ] ; then
    echo "Installing Cocoa Dialog from JSS"
    $jamf_bin policy -event installcocoaDialog
    if [ ! -f $CocoaDialog ] ; then
        echo "Couldn't install Cocoa Dialog! Exiting."
        killHUD
        exit 1
    fi
fi

# Not that it matters but we'll remove the old log file if it exists
if [ -f $rumlog ] ; then
    rm $rumlog
fi

#run RUM and output to the log file
touch $rumlog
$rum --action=list > $rumlog

# super-echo!  Echo pretty-ish output to user. Replaces Adobes channel IDs with actual app names
# I think it's silly that I have to do this, but whatever. :)
# Adobe channel ID list: https://helpx.adobe.com/enterprise/package/help/apps-deployed-without-their-base-versions.html
secho=`sed -n '/Following*/,/*/p' $rumlog 
    | sed 's/Following/The Following/g' 
    | sed 's/ACR/Camera RAW/g' 
    | sed 's/AEFT/After Effects/g' 
    | sed 's/AME/Media Encoder/g' 
    | sed 's/AUDT/Audition/g' 
    | sed 's/FLPR/Animate/g' 
    | sed 's/ILST/Illustrator/g' 
    | sed 's/MUSE/Muse/g' 
    | sed 's/PHSP/Photoshop/g' 
    | sed 's/PRLD/Prelude/g' 
    | sed 's/SPRK/Experience Design Beta/g' 
    | sed 's/KBRG/Bridge/g' 
    | sed 's/AICY/InCopy/g' 
    | sed 's/ANMLBETA/Character Animator Beta/g' 
    | sed 's/DRWV/Dreamweaver/g' 
    | sed 's/IDSN/InDesign/g' 
    | sed 's/PPRO/Premiere Pro/g' 
    | sed 's/ESHR/Project Felix/g' `


if [ "$(grep "Following Updates are applicable" $rumlog)" == "Following Updates are applicable on the system :" ] ; then
    rv=`$CocoaDialog yesno-msgbox --float --icon-file "$icons/ToolbarInfo.icns" --no-cancel 
    --title "Adobe Remote Update Manager Interface" --text "Do you want to install the following updates?" --informative-text "$secho Please close any currently open Adobe products"`
    if [ "$rv" == "1" ]; then
        echo "user chose to install updates"
        installUpdates
    elif [ "$rv" == "2" ]; then
        echo "user chose not to install updates"
        killHUD
        exit 0
    fi
else
    echo "no updates available"
    $CocoaDialog ok-msgbox --float --no-cancel --icon-file "$icons/ToolbarInfo.icns" 
    --title "Adobe Remote Update Manager Interface" --text "There are no Adobe Updates available."
    if [ "$rv" == "1" ]; then
        killHUD
        exit 0
    fi
fi

When the policy runs with the above script variables set, the RemoteUpdateManager will check for updates & automatically install them if no one is logged in - displaying a nice HUD message:
781dbadeff934e7eb1e2ad2b5309b65a

Or if a user is logged in - display the available updates & let them choose to install at their discretion:
00f58ce4134a4e22a049b0a76ffb48c9

A requirement for the user logged in scenario is cocoaDialog, so you'll need to also have a policy with trigger to install that on demand.
I have also rolled this into Self Service, which is handy for our techs.

Hopefully this is useful for others, any feedback is welcome.

14 REPLIES 14

jmahlman
Valued Contributor

Oh, very nice addition! I may have to add this into our workflow.

Thanks for the shoutout, I'm glad my crappy little script is being used by others!

mpeski
New Contributor III

Very nice. I'll see if I can use this in our environment as well. Thanks!!

mpeski
New Contributor III

I got it mostly to work in our environment. There are only two things. The first is that it fails on this line at the login screen: exec > >(tee -i $logfile). For now I uncommented it and it works, expect no log for now.

The second thing is that it won't work at the login screen at Macs with FV2 enabled. When a user is logged in it works. Do you have it working at FV2 Macs of didn't you try that?

Adminham
New Contributor III

@mpeski I'm sure there are better methods to log than I put in the scripts I kludge together 😄
We don't use FV2 in our environment, but I'll enable it on a dev box next week & let you know my results..

Adminham
New Contributor III

@mpeski I'm not terribly familiar with the ins & outs of FV2, but there seems to be a different state the Mac gets into after a reboot that isn't LoginWindow (EFI boot authentication?). Credentials were being prompted for a specific user rather than username & password fields (how I had set the LoginWindow to display). In this scenario the HUD script didn't work. After a login & logout (which took me to username & password field prompt), the script worked.

Is this similar to the behaviour you're seeing? Perhaps someone with more experience with FV2 environments can comment on this..

mpeski
New Contributor III

@Adminham This is what I see as well. No pop-up at the login screen, but when a Mac with FV2 on logs on you see the message with the available updates. It's still usable, but it would be nice to find a way it would work with FV2 as well at the login screen. I'll use it for sure the way it is now and if I find some time I'll look if it can be modified so it will work with FV2 as well.

jmahlman
Valued Contributor

I cleaned up the script a tad bit (one line really) and added some new channel IDs since the last marked update on the one above. You can find it here on my github.

monaronyc
Contributor

@jmahlman @Adminham Anyone got this in a script without the use of this CocoaDialog? Because apparently CocoaDialog no longer exists. At least not that I can find. Maybe script this with the use of a JamfHelper? Thoughts?

Adminham
New Contributor III

@monaronyc I'll admit, CC isn't the easiest to find any more.. you can download the source & have a crack at compiling: https://github.com/cocoadialog/cocoadialog
Or grab the compiled binaries from the links posted here: https://github.com/cocoadialog/cocoadialog/issues/108

A JamfHelper only version would be handy - I'll have a play when I get a spare moment 🙂

jmahlman
Valued Contributor

@Adminham Ask and ye shall receive: https://github.com/jmahlman/uarts-scripts/blob/master/Adobe-RUMWithProgress-jamfhelper.sh

Note: I have not updated this script in some time. I don't work there anymore and I have not had time to update scripts that I don't use anymore.

sk8559
New Contributor II

@Adminham We do not use CS CC, All the mac managed by jamf and users have installed the the multipal app's from indvidule sorruces. I have done research and got the RUM packaged and installed on mac systems, But still struck with few question. 1st one - Article says that ARMDC need to be installed and I am not able to understand what is this. 2nd What should be the policy configuration to run the RUM on Mac so that apps can get downloaded and get installed silently. 3. What should be the criteria of smart group for all different adobe apps. Please help

jmahlman
Valued Contributor

@sk8559 TO satisfy the ARMDC version I just ensure that Acrobat and Reader are updated to a new version and then updates moving forward are done via RUM.

The policy that I use to run RUM updates looks like this:
- Trigger: Recurring
- Frequency: Weekly
- Command: /usr/local/bin/RemoteUpdateManager --action=install
- Scope: Smart group "RUM Updates Available"

That smart group reads from an EA to see if RUM updates are available. Here is the EA I made:

#!/bin/bash

rumlog=/Library/Application Support/Company/AdobeRUMUpdatesLog.log  # mmmmmm, rum log
rum=/usr/local/bin/RemoteUpdateManager

# Not that it matters but we'll remove the old log file if it exists
if [[ -f "$rumlog" ]] ; then
    rm "$rumlog"
fi

#run RUM and output to the log file
touch "$rumlog"
$rum --action=list > "$rumlog"

if [[ -f $rum ]]; then
    if [[ "$(grep "Following Updates are applicable" "$rumlog")" ]] ; then
        result="Updates Available"
    else
        result="No Updates"
    fi
else
    result="RUM not found"
fi
/bin/echo "<result>$result</result>"

So the smart group reads if it says "Updates Available" and adds them to the group. If updates are available, we run the RUM update policy, apps that are not opened are silently updated. Open apps are not updated and it will try again in a week. Feel free to change frequency however you'd like.

Stubakka
Contributor II

Testing this out today on a test system

c_archibald
Contributor II

I can get newer downloads via Admin Console than through RUM right now. Sad but true. I was getting to like RUM too.