Triggering multiple policies that require restart and only restarting once.

AdamCraig
Contributor III

I'm looking to create a policy that will combined multiple patch management policies to happen at the same time to create a better user experience. My current set up is that these individual policies are available in Self Service and have a trigger. Some of these policies require a reboot, and others do not.

So the script will check the version of the various software and then if it is not the required version it will run the trigger.

If I do

#!/bin/sh

jamf policy -trigger bluejeans
jamf policy -trigger office
jamf policy -trigger globalprotect
jamf policy -trigger applesoftwareupdates

and both the globalprotect and applesoftwareupdates policies require reboot. Is there way I can run all these policies and only reboot once without having to create separate policies for the triggers that do not reboot?

1 ACCEPTED SOLUTION

bradtchapman
Valued Contributor II

Why do you have GlobalProtect set to reboot immediately?

Background the process with &, capture the last PID as $!, then wait until it's done. Like so:

jamf policy -trigger bluejeans
jamf policy -trigger office
jamf policy -trigger globalprotect &
jamfPID=$!
wait $jamfPID
jamf policy -trigger applesoftwareupdates

View solution in original post

4 REPLIES 4

mm2270
Legendary Contributor III

This is a good question. I honestly don't know if I have a good answer for you right now though. I assume from what you wrote that the globalprotect and applesoftwareupdates polices both have the Restart Options payload added to them with the "Restart if a package or update requires it" option checked. Yes?

If so, I'm not clear how such a situation would be handled frankly.
I know that when the normal check-in trigger fires off, one thing that I believe the jamf framework does is hold off on some of the final options in each policy until all scheduled policies have run. For example, if each policy has the Update Inventory option checked, it consolidates those all into one final Update Inventory after the last policy has completed, rather than each policy doing it's own one. But, I don't know if it does the same thing with the Restart Options. And anyway, these aren't being called by the check-in trigger, so it likely wouldn't apply in this case.

Let me ask - have you tried running the above scenario and seeing how it plays out? Does the globalprotect triggered policy cause the Mac to reboot before the applesoftwareupdates one can execute or finish?

AdamCraig
Contributor III

Trying the above situation, the computer restarts after the globalprotect policy finishes. Which that is set to reboot immediately and the following policy never runs. and a log is not submitted to jamf for the parent policy (however one is for the global protect policy that finished)

I also tried it with a reboottest policy at the beginning that reboots after 5 minutes. so the user is alerted that the reboot will happen after 5 minutes, then the bluejeans policies runs (i disabled office to speed things up), then the globalprotect policy that reboots the computer immediately.

Seems like the solution may be to have 2 separate policies for everything, one on a trigger that doesn't reboot and a separate policy for self service. But I would rather not do that as we're looking for this to be a monthly process with a number of different updates and maintaining 2 sets of policies will add a lot more room for human error.

bradtchapman
Valued Contributor II

Why do you have GlobalProtect set to reboot immediately?

Background the process with &, capture the last PID as $!, then wait until it's done. Like so:

jamf policy -trigger bluejeans
jamf policy -trigger office
jamf policy -trigger globalprotect &
jamfPID=$!
wait $jamfPID
jamf policy -trigger applesoftwareupdates

AdamCraig
Contributor III

@bradtchapman Thanks I'll try this out!
We've had issues with global protect installs in the past and having them restart seems to have resolved those. Mainly that it frequently doesn't prompt for access to the cert until the user logs out or logs back in. And in our next update we are not only upgrading global protect but switching the vpn portal, which the best way i've found to do that is to remove the plist and install a new one from a .pkg
But from a larger standpoint we frequently have some updates/installs that require a reboot and the ability to trigger them in this way would make it easier for us to roll them all into one big update for a better user experience.

Here is the function I wrote that'll actually be the thing checking these applications to make sure they are at least the correct version. I'll add a variable for if they are rebooting.

#!/bin/sh
checkApplicationVersion(){
    app_name="$1"
    echo "Processing $app_name"
    file_path="/Applications/$app_name"
    expected_version="$2"
    jamf_trigger="$3"
    ## get current version
    current_version=$(mdls -raw -name kMDItemVersion $file_path)

    runUpdate=false
    ## determine if expected
    echo "comparing Expected - $expected_version with Current - $current_version"
    if [[ $expected_version != $current_version ]] ; then
        ## turn them into ints by removing the periods.
        expected_clean=$(echo ${expected_version} | tr -d "." | tr -d "-")
        current_clean=$(echo ${current_version} | tr -d "." | tr -d "-")
        echo "Cleaned versions Expected - $expected_clean , Current - $current_clean"
        ## Get lengths of both variables        
        ## length=${#myvar} 
        expected_len=${#expected_clean}
        current_len=${#current_clean}
        ## if they are different lengths trim trim the longer one so they are the same length

        if (( $expeced_len > $current_len )) ; then
            echo "expected longer than current. This probably shouldn't happen"
            echo "old expected_clean = $expected_clean"
            expected_clean="${expected_clean[@]:0:$current_len}"
        elif (( $current_len > $expected_len )) ; then
            echo "current longer than expected."
            echo "old current cleaned = $current_clean"
            current_clean="${current_clean[@]:0:$expected_len}"
            echo "new current_clean = $current_clean"
        fi
        ## Compare versions. if expected version is greater than current version
        ## If expected version is greater than current version set $runUpdate to True

        if (( $expected_clean > $current_clean )) ; then
            echo "expected version > current version Run Update = True"
            runUpdate=true
        else
            echo "versions match. Expected = $expected_clean , Current = $current_clean"
        fi
    else
        echo "versions match. Passing"
    fi
    ##if runUpdate == True run the jamf policy for upgrades
    if [[ $runUpdate == true ]] ; then
        echo "Beginning Jamf policy"
        jamf policy -trigger $jamf_trigger
    fi
}