jamfhelper software update trigger

ImAMacGuy
Valued Contributor II

So I stole the script from https://jamfnation.jamfsoftware.com/featureRequest.html?id=751 and tweaked the wording a bit.

#!/bin/sh

HELPER=`/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -icon /Library/Application Support/JAMF/bin/jamfHelper.app/Contents/Resources/Message.png -heading "Software Updates are Available" -description "Would you like to install updates?  System may need to be rebooted." -button2 "Install" -button1 "Cancel" -cancelButton "1"`


      echo "jamf helper result was $HELPER";

      if [ "$HELPER" == "2" ]; then
         /usr/sbin/jamf policy -trigger SWUJH
         exit 0
      else
         echo "user chose No";   
     exit 1
      fi

I also tweaked the cancel button due to when I was using it in it's default form everything returned "user chose No" and it wouldn't run the trigger.

Now when I select install, the box disappears then immediately reappears and I have to choose install again, and then teh box stays gone, but the trigger never starts the updates.

1 ACCEPTED SOLUTION

acdesigntech
Contributor II

Hey John, I went a few steps further and added some logic into the script to count how many times the user chooses no before the script runs automatically anyway. To me, it gives the user a greater sense of control even if only perceived.

#!/bin/sh

fRunUpdates ()
{

    ## Once the user OKs the updates or they run automatically, reset the timer to 5 
    echo "5" > /Library/Application Support/JAMF/.SoftwareUpdateTimer.txt

    /Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType hud -lockhud -heading 'ISD is updating software on your computer' -description 'We are now updating your Mac System software. These updates should not take longer than 30 to 45 minutes depending on how many updates your Mac needs. If you see this screen for more than 45 minutes please call our Service Desk at X4949. Please do not turn off this computer. This message will go away when updates are complete.' -icon /Library/Application Support/JAMF/EndUserSupport/AGRose.icns > /dev/null 2>&1 &

    ## We'll need the pid of jamfHelper to kill it once the updates are complete
    JHPID=`echo "$!"`

    /usr/sbin/jamf policy -trigger SoftwareUpdate & 
    ## Get the Process ID of the last command run in the background ($!) and wait for it to complete (wait)
    SUPID=`echo "$!"`
    wait $SUPID

    ## kill the jamfHelper. If a restart is needed, the user will be prompted. If not the hud will just go away 
    kill -s KILL $JHPID
    exit 0
}



######### Set variables for the script ############

########## Get the group membership for the client #####################
## Get MAC Address using networksetup
MAC=$( networksetup -getmacaddress en0 | awk '{ print $3 }' | sed 's/:/./g' )

## Use the JSS API to get the Mac's group memberships
JSSGroups=$( curl -s -u username:password https://<casper server>:8443/JSSResource/computers/macaddress/$MAC 
| xpath //computer/groups_accounts/computer_group_memberships[1] 
| sed -e 's/<computer_group_memberships>//g;s/</computer_group_memberships>//g;s/<group>//g;s/</group>/
/g' )

## Set up the software update time if it does not exist already
if [ ! -e /Library/Application Support/JAMF/.SoftwareUpdateTimer.txt ]; then
    echo "5" > /Library/Application Support/JAMF/.SoftwareUpdateTimer.txt
fi

## Get the timer value
Timer=`cat /Library/Application Support/JAMF/.SoftwareUpdateTimer.txt`

## Get the currently logged in user, if any. Also check for updates that require a restart and ones that do not.
UpdatesNoRestart=`softwareupdate -l | grep recommended | grep -v restart`
RestartRequired=`softwareupdate -l | grep restart | grep -v '*' | cut -d , -f 1`
LoggedInUser=`who | grep console | awk '{print $1}'`

################ End Variable Set ################

## Use echo and grep to find known-core (non system) software update groups. If these groups are found, run these installers silently since no restarts are required for these updates. Use an array to see which updates we take account of. The names of the array elements are also trigger names for each update. This way when there's a new software package to keep updated, we add the trigger name into the array, and the update policy to the JSS. Casper does the rest
NonSysCore=( 'SoftwareUplift-FlashPlayer' 'SoftwareUplift-Flip4Mac' 'SoftwareUplift-FontNuke' 'SoftwareUplift-PrintWindow' 'SoftwareUplift-MicrosoftOffice' 'SoftwareUplift-MicrosoftOutlook' )

for (( i = 0; i < ${#NonSysCore[@]}; i++ ))
do
    CheckUpdate=`echo "$JSSGroups" | grep "${NonSysCore[$i]}"`
    if [ "$CheckUpdate" != "" ]; then
        jamf policy -trigger "${NonSysCore[$i]}"
    fi
done

## If there are no system updates, quit
if [ "$UpdatesNoRestart" == "" -a "$RestartRequired" == "" ]; then
    echo "No updates at this time"
    exit 0
fi

## If we get to this point and beyond, there are updates. 
## if there is no one logged in, just run the updates
if [ "$LoggedInUser" == "" ]; then
    /usr/sbin/jamf policy -trigger SoftwareUpdate
else
    ## someone is logged in. prompt if any updates require a restart ONLY IF the update timer has not reached zero
    if [ "$RestartRequired" != "" ]; then
            ## If someone is logged in and they have not canceled 5 times already, prompt them to install updates that require a restart and state how many more times they can press 'cancel' before updates run automatically.
        if [ $Timer -gt 0 ]; then
            HELPER=`/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -icon /Library/Application Support/JAMF/EndUserSupport/AGRose.icns -heading "AG ISD Approved Software Updates are Available for Your Mac" -description "These updates will require you to restart your Mac. If you would like to install these now, click 'Install Updates.' If you would not like to install now, click 'Cancel Updates.' You may choose not to install updates $Timer more times before this computer will automatically install them. These updates require a restart of your Mac: $RestartRequired" -button1 "Install Updates" -button2 "Cancel Updates" -cancelButton "2" -defaultButton 2 -timeout 60`
            echo "jamf helper result was $HELPER";
            ## If they click Install Updates then run the updates
            if [ "$HELPER" == "0" ]; then
                fRunUpdates
            else
            ## If no, then reduce the timer by 1. The script will run again the next day 
                let CurrTimer=$Timer-1
                echo "user chose No"
                echo "$CurrTimer" > /Library/Application Support/JAMF/.SoftwareUpdateTimer.txt
                exit 1
            fi
        else
            ## If Timer is already 0, run the updates automatically, the user has been warned!
            fRunUpdates
        fi
    fi
fi

## Install updates that do not require a restart
if [ "$UpdatesNoRestart" != "" ]; then
    /usr/sbin/jamf policy -trigger SoftwareUpdate 
fi

View solution in original post

226 REPLIES 226

mm2270
Legendary Contributor III

Hi @perrycj Thanks for the feedback and update.
I'll certainly check on that. Its strange since I ran the same script above in my testing with a Mac that needed updates that required a restart and it did restart the Mac at the end. So I'm not clear (yet) why it isn't doing it in your case. The fact that the Restart required? line is showing "no" in your script output would certainly seem like its not picking up or rather not assigning the correct flag.

I'll certainly dig into this to see why that is.

perrycj
Contributor III

@mm2270 Not a problem. Thanks for being responsive and, of course, originally building the script. I will also look into it and see if I can figure it out why the restarts aren't happening. I've tried it on multiple Macs with the same behavior so i know it's not isolated to just a single rogue Mac.

perrycj
Contributor III

@mm2270 Just as a follow up, in my testing I made the change to add the call for restartReq function to decide if updates need a restart or not back near line 520 where it originally was and now I am getting consistent restarts when the update(s) calls for it.

I'll continue to test to see if anything else pops up but otherwise, everything seems to be working as expected.

jhbush
Valued Contributor II

@mm2270 I've been testing this under 10.12.0 and it appears the status indicator for CD isn't working. I'm hoping CD hasn't reached it's EOL.

mm2270
Legendary Contributor III

Hi @jhbush1973 What do you mean by "status indicator"? I admit I haven't run any CD based scripts against 10.12 just yet. I also hope its not at the end of its usefulness. If you let me know specifically what you meant by the above, I'll do some tests with it.

To everyone else, I've been a bit busy and haven't had the chance to finalize things with the script above, but plan on getting on that very soon. I'm hoping we can work out all the kinks and put the finishing touches on it soon so I can update my github repo with the new version. Thanks for everyone's continued interest and contributions to it!

jhbush
Valued Contributor II

@mm2270 sorry for not being more precise in my comments. I'm not seeing the indicator bar that moves across for a software install with CD. I also don't see the indication of what update is installing in that same bar or the countdown for x minutes when it's finished.

mm2270
Legendary Contributor III

Ah, so the progressbar isn't working? Hmm. I'm getting a Sierra Mac ready right now incidentally to test with some other stuff. I'm going to do some progress bar test runs to see what's up. I've been worried for a few years now that cocoaDialog might end up no longer working with one of Apple's major OS releases. This may be it, but I'm keeping my fingers crossed that there's still a way to get it to work.

Thanks for the clarification.

perrycj
Contributor III

@mm2270 and others who have followed this thread.. and just in an effort to keep it updated, we ran in to a situation where a specific update was causing problems for our users. I wanted to find a way to ignore certain updates so this workflow could continue to be used but that I wouldn't have to worry about those potential rogue updates from Apple.

The update in question for our environment was the very recent Safari 10.0 or 10.0.1 update, which for a majority of users was rendering safari useless upon update, if installed with other updates. Strange, I know. 10.0.1 installed by itself to a Mac with Safari 9.x installed, and everything was fine. If the 10.0 update rendered Safari useless, the 10.0.1 update usually fixed it, but not always. We have an enterprise agreement with Apple, so we have an active/open case with them about this.

Using the softwareupdate binary, I was able to add a line to the script to set the ignore updates array before it pulls the list of available updates.

##  Gather available Software Updates and export to a file
echo "Pulling available Software Updates..."
/usr/sbin/softwareupdate --ignore Safari10.0.1ElCapitan Safari10.0ElCapitan Safari10.0.1Yosemite Safari10.0Yosemite
/usr/sbin/softwareupdate -l > /tmp/SWULIST
echo "Finished pulling available Software Updates into local file"

echo "Checking to see what updates are available..."
##  Generate list of readable items and installable items from file

readSWUs=$(awk -F"," '/recommended/{print $2,$1}' /tmp/SWULIST | sed -e 's/[0-9]*K [recommended][ *]//g;s/[restart] */◀ /g' | sed 's/    / /g;s/^ *//g')
progSWUs=$(awk -F"," '/recommended/{print $2,$1}' /tmp/SWULIST | sed -e 's/[0-9]*K [recommended][ *]//g;s/[restart] *//g' | sed 's/  / /g;s/^ */ /g')
installSWUs=$(grep -v 'recommended' /tmp/SWULIST | awk -F'\* ' '/*/{print $NF}')

This is around line 850 of the script and near the bottom. It's important to note that it must go before the

/usr/sbin/softwareupdate -l

command pulls the list of the available updates. Also, all you need is the identifier of each update you want to ignore. They must be separated by a space, not a comma or semicolon, or they will not get ignored properly.

The identifiers can be found just by running softwareupdate --list or -l, and taking everything before the first "-". For example:

sh-3.2# softwareupdate --list
Software Update Tool
Copyright 2002-2015 Apple Inc.

Finding available software
Software Update found the following new or updated software:
   * iTunesXPatch-12.5.2
    iTunes (12.5.2), 145964K [recommended]
sh-3.2#

You would just need to put "iTunesXPatch" in the ignore command to ignore this specific update from Apple. Hopefully this helps someone else out and/or is useful to others in some way.

perrycj
Contributor III

@mm2270 just to echo @jhbush1973 , I'm seeing what he saw in 10.12 in terms of progress bars. The updates still install but there is no moving progress bar at all. Just a box that says "Updating are installing".

It seems CD may have met its match with Sierra.

perrycj
Contributor III

@mm2270 and @jhbush1973 .. So progress bars do display correctly in Sierra because when you encounter an update that requires a restart, a progress bar does display, showing progress until the Mac restarts.

And it will show a full blue progress bar when installing updates, however it seems something has changed in Sierra with how it gets the updates and installs them. I suspect it is in how the updates are put into an array by the script for CD to read them. All the commands in the beginning of the script to gather and list the updates still work correctly as of 10.12.1.

I'll keep working on it and if I get it to display progress correctly while installing, I will update this thread.

jhbush
Valued Contributor II

@perrycj I can also confirm the issue you were having with the Safari update rendering Safari useless when run through the software update script.

perrycj
Contributor III

@jhbush1973 Yea it seems it persists with the 10.0.2 update as well.

From Apple, they said if installed with any other updates (whether through this script which uses the softwareupdate binary) or through the app store, that's when the issue would occur.. but even for them in their testing (and mine), it's hit or miss in that situation.

They state if you install it alone (safari update) there should be no issue. They were supposed to fix it with 10.0.2 but that is not the case.

As for this software update script, I have narrowed it down to the arrays that are used for displaying progress. Sierra does not like how they are put together and therefore that's why the progress bars don't display starting with 10.12.x on installing updates. Unfortunately I haven't found a better way to create them yet.

Just to restate, if you do a restart using this script, progress bars do display correctly counting down the time remaining until your Mac restarts which leads me to believe it isn't CocoaDialog that is the problem.

mm2270
Legendary Contributor III

Hey @perrycj and anyone else, I haven't had much time to really look into this issue, so thanks for helping out and continuing to work on it. As soon as I can, I will set up some time to work on it against the latest Sierra update to see what can be done, if anything, to get the progressbar working properly again, assuming you don't figure it out before I do.

I've been concerned that cocoaDialog may continue to show its age and little problems like this would creep in over time, although it seems its more how the script is passing information to CD that's the issue. I'll see what can be done.

perrycj
Contributor III

@mm2270 No worries. There is just a lot of code and a lot of functions so it takes time, as you know.

Thanks for your contributions overall and if I do find a way, I will definitely update this thread.

emily
Valued Contributor III
Valued Contributor III

Hey @mm2270, curious to hear how you have the policy running your script scoped/triggered. :)

emily
Valued Contributor III
Valued Contributor III

Just to follow up, the progress bar isn't working as expected in my testing either. So I'm curious… is there a way to remove the progress bar and do something else without totally breaking the functionality of the script? Like maybe displaying the last echo for softwareupdate or something?

burdett
Contributor II
 

llitz123
Contributor III

From the end of this thread there seems to be some issues with 10.12. Are people still using these scripts successfully or is there something better?
I'm testing the v006 script and it seems to work ok.
What I would like is to have the Managed Software Update window pre-filled with no user interaction, yet the ability to still defer.
So far in my testing I have been unable to make this happen by editing this section:

##  Set the forceEnableUpdates flag below to 'yes' (or any value) to enable it. This option will change the
##  checkbox display to show updates as enabled and non-selectable to the user, meaning they will be forced to
##  an "on" state for all. Leaving this value blank will retain the original functionality, allowing the end
##  user to select the updates they would like to install.

if [[ "$deferralsLeft" -eq 0 ]]; then
    echo "0 deferrals remaining. Updates will be installed now"
    forceEnableUpdates="Yes"
else
    echo "You have $deferralsLeft deferrals remaining"
    forceEnableUpdates=""
fi

I can get the Managed Software Update window pre-filled yet there is no option for defer.
Even without the "defer" button, if I quit the Managed Software Update window with no defer button, the deferralCount drops by one.
Also how long does each defer last and is there a setting to change for length of deferral?
Thanks for any assistance.

mm2270
Legendary Contributor III

Hey @llitz123 Not sure if you got my email response to your email to me, but in case not, I haven't been able to get back to working on this script to fix the issues or make it work with Sierra. I'm hoping I'll get back to this within the next few weeks though.

In the interim, I just wanted to mention that if you're looking to just simply see a list of updates that will be installed with no checkboxes, I think you'd be better served with other scripts that do this. While I did say I may implement a function that would just list the updates with no checkboxes, it sort of goes against the spirit of this script. I originally developed it as a way to emulate some of the older Software Update.app functionality (pre 10.8) for users. It's why I named it "selectable" SoftwareUpdate. If I remove the ability to select anything it's no longer "selectable" is it? :)

That isn't to say I won't do it, but if I do, I may just create a branch of this script and remove the need for cocoaDialog, or at least pare the whole thing down a bit since there is a lot of stuff in it that works around users selecting updates to install that would be bloat in such a script.

llitz123
Contributor III

Thanks @mm2270 . I see what you mean about the reason behind the script you created. I'm actually using the check-boxes in my testing - I was just looking at options for future proof.
I'll update my original thread.
Thanks.

rblaas
Contributor II

I too confirm the progress bar is not working correctly in OS 10.12.5 Not even showing a blue bar.. Only line I got was getting ready to install updates..

this is the log:

Script result: You have 4 deferrals remaining
Current user is: jdoe
Pulling available Software Updates...
Finished pulling available Software Updates into local file
Checking to see what updates are available...
Software Updates are available, and a user is logged in. Moving to initial dialog...
There are some non reboot updates available. Showing selection screen to user
User clicked the "Install No Reboot Updates" button.
User chose to install all non reboot updates. Creating update(s) array and moving to install phase
Restart required?: no
Displaying progress bar window.
Showing individual update progress.
Now installing iTunes (12.6.2)...
Closing progress bar.
Closing all cocoaDialog windows.
Showing updates complete message.
1
Cleaning up SWU list file.

I'd like to point another thing out. As I just installed the 'no reboot' updates the deferral count was still reset to 5. So this could mean that if (and I don't know if that could be the case) there is an non reboot update available every week (or no longer than 5 weeks) The reboot updates can be skipped forever. That would mean that the security updates (which I find far more interesting then others) are never installed / not forced at some point.

So the way I see it the deferral should only be reset to 5 when there are no updates left to install.

Will look into this myself to see if I can add this..

(in my case I was planning on running this script every week)

rblaas
Contributor II

@mm2270 The reason the progressbar is not working is because the softwareupdate output has changed (apparently) in 10.12 .

In 10.12 it does not show the % progress anymore...

I have not yet found a solution for this.

Below the output of the update in 10.12.x

/usr/sbin/softwareupdate --verbose -i RemoteDesktopClient-3.9.3
Software Update Tool
Copyright 2002-2015 Apple Inc.


Downloading Remote Desktop Client Update
Downloaded Remote Desktop Client Update
Installing Remote Desktop Client Update
Done with Remote Desktop Client Update
Done.

bpavlov
Honored Contributor

Anyone who is making use of softwareupdate may want to take into account some changes to softwareupdate and an addition of a new flag. I made a feature request about it here: https://www.jamf.com/jamf-nation/feature-requests/7285/add-softwareupdate-restart-support

maiksanftenberg
Contributor II

I came across this post and the Selectable Update Script what I found very useful.
After testing I found the following error:
line 519: syntax error near unexpected token `<'
line 519: `done < <(echo "${readSWUs}")'

Where exactly is the problem? Thanks

el2493
Contributor III

@maik.sanftenberg I'm not sure which version of the script you're using since there are a bunch of different versions in this thread. Do you actually have a line that reads `done < <(echo "${readSWUs}")' (with a ` at the beginning and a ' at the end)? If so, change it to just done < <(echo "${readSWUs}") and see if that makes a difference.

I also see @dmw3 had the exact same issue in this thread on 7/14/2016 and @mm2270 left some advice about dealing with this issue.

mm2270
Legendary Contributor III

@maik.sanftenberg That script is a bit old at this point, and with all the OS changes since I first put it together, there are bound to be some parts of it that don't work anymore. I have taken a look at the script again recently and will try to brush it off and see if I can make it more viable for current OS versions.

That being said, the most common reason for getting that error is that you tried to run the script like this in Terminal:

sh /path/to/Selectable_SoftwareUpdate.sh

As mentioned a while back on this same thread, don't do that or it overrides the shell interpreter, which needs to stay as /bin/bash There are specific bash elements in the script. If you have trouble running the script directly without using sh in front, then run

chmod +x /path/to/Selectable_SoftwareUpdate.sh

Once it's executable, then just putting the path to the script will work. Remember to put sudo in front of it if testing in Terminal.

Hope that helps.

joethedsa
Contributor II

Hello @lisacherie, @acdesigntech, and others,
I know this discussion hasn't had any comments but there are some great solutions and many have contributed. My observation is seeing scripts using the "jamf policy -trigger <policyname>" command; what does that triggered policy have configured for payloads and or what does it look like?
From what I understand, the core of the script(s) pull up a HUD using jamfhelper as an alert to the enduser there are updates. Updates not requiring restart are installed automagically. If the deferral button is used and there are no more, those updates requiring a reboot is forced. Is the triggered policy the ones that handles this forced reboot?