Forced Shutdown script

blackholemac
Valued Contributor III

I wanted to take a moment to post our changes to a script included in the resource kit that has been very useful to us.

The script in question is the timedForcedShutdown.sh script.

My changes remove the extraneous postpone dialog box and adds a $postponeButtonText variable to allow customization of the postpone button.

Now, when the postpone button is pushed by the user, the script does an exit 0 instead of displaying the second dialog box included in version 1.0. That second dialog box caused Terminal to blow an error during my testing of the original 1.0 version. As such, the $postponeAlert variable was removed.

The new version also implements a "safety mechanism" that prevents the script from executing during business hours and scaring folks. You can define the $openbusinessHour
$closebusinessHour variables to set those times.

Finally Version 1.2 builds on the 1.0 version author's assumed desire to offer the sysadmin easy and full customization of the GUI presented to the user. I hope folks find use for this and if the 1.0 author is reading this, thank you for your hard work and hope my changes have been a worthy addition (or subtraction).

#!/bin/sh
####################################################################################################
#
# Copyright (c) 2010, JAMF Software, LLC.  All rights reserved.
#
#       Redistribution and use in source and binary forms, with or without
#       modification, are permitted provided that the following conditions are met:
#               * Redistributions of source code must retain the above copyright
#                 notice, this list of conditions and the following disclaimer.
#               * Redistributions in binary form must reproduce the above copyright
#                 notice, this list of conditions and the following disclaimer in the
#                 documentation and/or other materials provided with the distribution.
#               * Neither the name of the JAMF Software, LLC nor the
#                 names of its contributors may be used to endorse or promote products
#                 derived from this software without specific prior written permission.
#
#       THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY
#       EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
#       WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
#       DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY
#       DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
#       (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
#       LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#       ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#       (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#       SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
####################################################################################################
#
# SUPPORT FOR THIS PROGRAM
#
#       This program is distributed "as is" by JAMF Software, LLC's Resource Kit team. For more
#       information or support for the Resource Kit, please utilize the following resources:
#
#               http://list.jamfsoftware.com/mailman/listinfo/resourcekit
#
#               http://www.jamfsoftware.com/support/resource-kit
#
#       Please reference our SLA for information regarding support of this application:
#
#               http://www.jamfsoftware.com/support/resource-kit-sla
#
####################################################################################################
#
# ABOUT THIS PROGRAM
#
# NAME
#   timedForcedShutdown.sh -- This script is used to enforce a mandatory shut down.
#
# SYNOPSIS
#   sudo timedForcedShutdown.sh
#   sudo timedForcedShutdown.sh <mountPoint> <computerName> <currentUsername> <minutesN>
#       <shutdownAction> <notificationMessage> <shutdownPhrase> <shutdownTitle>
#       <postponeButtonText> <openbusinessHour> <closebusinessHour>
#
# DESCRIPTION
#   This script will help to enforce a mandatory reboot or shut down.
#
#   If no console user is logged in, the script will execute the command
#   stored in the $shutdownAction variable.
#
#   If a console user is logged in, a dialog is displayed informing the user
#   of the number of minutes until shutdown followed by a configurable
#   message stored in $notificationMessage.  The dialog contains two buttons.
#
#   Clicking "Postpone for 2 Hours" will delay the shutdown for two hours when used
#   in combination with cron, launchd or a valid policy on the JSS.
#
#   Clicking "Shut Down" will execute the command stored in the $shutdownAction variable.
#
##########################################################################################
#
# HISTORY   Version: 1.2
#   - Version 1.0 created by Miles A. Leacy IV on May 20th, 2009
#   - Version 1.2 modifications by Brian Martin on September 25, 2012
#
#   Version 1.2 removes the extraneous postpone dialog box and adds a $postponeButtonText
#   variable to allow customization of the postpone button.
#   
#   When the postpone button is pushed by the user, the postpone button now does an exit 0
#   instead of displaying the second dialog box in version 1.0. This second dialog box 
#   caused Terminal to blow an error when executing the script. As such, the $postponeAlert 
#   variable included in version 1.0 was removed.
#
#   Version 1.2 also implements a "safety mechanism" that prevents the script from executing
#   during business hours and scaring folks. You can define the $openbusinessHour
#   $closebusinessHour variables to set those times.
#
#   Finally Version 1.2 builds on Miles Leacy's assumed desire to offer the sysadmin easy 
#   and full customization of the GUI presented to the user.
#
##########################################################################################
#
# DEFINE VARIABLES AND READ-IN PARAMETERS
#
##########################################################################################

minutesN=5
# Number of minutes to count down before shutdown

shutdownAction="shutdown -h now"
# Change to "shutdown -r now" to reboot
# Change to "shutdown -h now" to shut down

notificationMessage="Please save all open documents and close any open applications prior to a shut down."
# This message will appear in the initial dialog box following the initial warning dialog.

shutdownPhrase="Shut Down"
# This variable should contain either "Shut Down" or "Restart"
# depending on the value of $shutdownAction.  This string will appear
# in the dialog and will determine the name of the button that causes
# $shutdownAction to be executed.

shutdownTitle="LSC Automated Shutdown"
# You can customize this to your organization as you see fit.

postponeButtonText="Postpone for 2 Hours"
# Basically this button could say anything as it causes the script to exit 0 when pushed.

openbusinessHour="6"
closebusinessHour="14"
# You would use military time by hour here, for example 6 = 6 a.m., 18 = 6 p.m.

# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 4 AND, IF SO, ASSIGN TO "minutesN"
if [ "$4" != "" ] && [ "$minutesN" == "" ]; then
    minutesN=$4
fi

# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 5 AND, IF SO, ASSIGN TO "shutdownAction"
if [ "$5" != "" ] && [ "$shutdownAction" == "" ]; then
    shutdownAction=$5
fi

# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 6 AND, IF SO, ASSIGN TO "notificationMessage"
if [ "$6" != "" ] && [ "$notificationMessage" == "" ]; then
    notificationMessage=$6
fi

# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 7 AND, IF SO, ASSIGN TO "shutdownPhrase"
if [ "$7" != "" ] && [ "$shutdownPhrase" == "" ]; then
    shutdownPhrase=$7
fi

# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 8 AND, IF SO, ASSIGN TO "shutdownTitle"
if [ "$8" != "" ] && [ "$shutdownTitle" == "" ]; then
    shutdownTitle=$8
fi

# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 9 AND, IF SO, ASSIGN TO "postponeButtonText"
if [ "$9" != "" ] && [ "$postponeButtonText" == "" ]; then
    postponeButtonText=$9
fi

# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 10 AND, IF SO, ASSIGN TO "openbusinessHour"
if [ "$10" != "" ] && [ "$openbusinessHour" == "" ]; then
    openbusinessHour=$10
fi

# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 11 AND, IF SO, ASSIGN TO "closebusinessHour"
if [ "$11" != "" ] && [ "$closebusinessHour" == "" ]; then
    shutdownTitle=$11
fi

##########################################################################################
#
# SCRIPT CONTENTS
#
##########################################################################################

# exit 0 if the times is during declared business hours
current_hour=`/bin/date +%H`
if [ $current_hour -gt $openbusinessHour -a $current_hour -lt $closebusinessHour ]; then
    exit 0
fi

# If no user is logged in at the console, shut down immediately
consoleUser=`/usr/bin/w | grep console | awk '{print $1}'`
if test "$consoleUser"  == ""; then
    $shutdownAction
fi

function timedShutdown {
button=`/usr/bin/osascript << EOT
tell application "System Events"
    activate
    set shutdowndate to (current date) + "$minutesN" * minutes
    repeat
        set todaydate to current date
        set todayday to day of todaydate
        set todaytime to time of todaydate
        set todayyear to year of todaydate
        set shutdownday to day of shutdowndate
        set shutdownTime to time of shutdowndate
        set shutdownyear to year of shutdowndate
        set yearsleft to shutdownyear - todayyear
        set daysleft to shutdownday - todayday
        set timeleft to shutdownTime - todaytime
        set totaltimeleft to timeleft + {86400 * daysleft}
        set totaltotaltimeleft to totaltimeleft + {yearsleft * 31536000}
        set unroundedminutesleft to totaltotaltimeleft / 60
        set totalminutesleft to {round unroundedminutesleft}
        if totalminutesleft is less than 2 then
            set timeUnit to "minute"
        else
            set timeUnit to "minutes"
        end if
        if totaltotaltimeleft is less than or equal to 0 then
            exit repeat
        else
            display dialog "ATTENTION!!!!    ATTENTION!!!!    ATTENTION!!!!

In an effort to conserve energy during evenings and weekends, this Mac is scheduled to " & "$shutdownPhrase" & " in " & totalminutesleft & " " & timeUnit & ".

" & "$notificationMessage" & " " giving up after 60 buttons {"$postponeButtonText", "$shutdownPhrase"} default button "$shutdownPhrase" with title "$shutdownTitle"
            set choice to button returned of result
            if choice is not "" then
                exit repeat
            end if
        end if
    end repeat

end tell
return choice
EOT`
if test "$button" == "$postponeButtonText"; then
    `exit 0`
else
    $shutdownAction
    exit 0
fi
}

timedShutdown
4 REPLIES 4

chuck3000
Contributor

This is awesome. But, I'm wondering if there's a way to set it so that the reboot can be postponed to a time in the future, potentially via a launchd script? Essentially, I'm checking for uptime. If over 7 days, give them a warning and exit. If over 9days, present an alert that the machine is scheduled to be rebooted, but don't reboot, actually schedule it for reboot at a specific day/time (say Saturday at 7pm). With launchd, at least it will reboot even if the computer is asleep at that time.

Here's a draft of what I've been working on taken from portions of this script and a few others I've found. So far, I can do the immediate check and reboot, but I don't know how to feed this to a launchd script? (Oh, and ideally, this should work on 10.9, 10.8 and 10.7 if possible).

thanks all!

#! /bin/sh

# taken from https://jamfnation.jamfsoftware.com/discussion.html?id=4058

timechk=`uptime | awk '{ print $4 }'`
daysup=`uptime | awk '{ print $3 }'`

# Find Current User
############################################################
currentUser=`ls -l /dev/console | awk '{ print $3 }'`

# Checks if anybody is logged in and if not, reboots immediately.

#If no user is logged in at the console, Reboot immediately
#consoleUser=`/usr/bin/w | grep console | awk '{print $1}'`
#if test "$consoleUser"  == ""; then
#sudo jamf policy
#osascript -e 'tell app "System Events" to restart'
#fi

# checks or uptime greater than 9 days and forces reboot.
    if [ $daysup -ge 9 ]; then
        osascript -e 'tell app "System Events" to display alert "'$currentUser' Maximum uptime has been exceeded, your computer will now be rebooted."'
        jamf policy
        softwareupdate -ir
        reboot
    fi
# checks for uptime greater than 7 days and presents alert dialog box
    if [ $daysup -ge 7 ]; then
        osascript -e 'tell app "System Events" to display alert "'$currentUser', Recommended uptime has been been reached. Please reboot soon or your computer will reboot automatically"'
    exit 0
    fi

oligiles
New Contributor

Hello people
I love the idea of this script and it is perfect for what i need however i have a few issues and wandered if anyone can shed some light.
I'm testing on a MBPro 10.9.5 / Casper 9.63
I've uploaded the script to the JSS and configured a policy.
For testing purposes the policy is running Recurring Check-In/Ongoing
I can see it is running as the Notification centre displays the name of the policy. See attached image. I'm hoping this will stop when i set Client-Side Limitations.
The problem occurs when the client hits the time outside the business hours.
1. The only notification i get is in the notification bar2e8c118b561e4430a0746c343735b01a This could easily be ignored, missed or cleared by the user.
2. The option to postpone never comes up so as soon as the policy is in scope and runs, the machine shuts down.

Has anyone seen this behaviour and found a fix?
Could it be something that's changed in OSX 10.9 compared to 10.6/7/8 ?

Any help greatly appreciated.
Thanks

lwindram
Contributor

@chuck3000 This is what I am using to do something similar to what you are looking for. You would need to modify the script slightly to set the restart to a specific time - that wasn't desired behavior for me and it hasn't proven necessary.

By the time a computer is actually shutdown, the user has been notified plenty. Each notification is logged, along with some supporting data.

I built it to work a little differently than most scripts - it builds and launches it's own launchDaemons. To deploy it:

1.) place the script and cocoaDialog
2.) verify existence of both with an EA
3.) make a smart group for computers with both
4.) run a one line bash script that calls the placed script

sh /private/var/uptimeCheck.sh

Hope this helps!

#!/bin/bash

############################################################################################################
#
# Script to monitor uptime, and notify user if uptime threshold is approaching.
#
# Author: Luke Windram
# Created: 3/18/15
# Modified: 3/27/15 - moved repetitive tasks into functions, changed countdowns to progress bar cocoaDialog
#
# Credits:
#       scriptLogging functions from [~rtrouton]
#       cocoaDialog countdown timer from jamfnation - post 8360
#
# Dependencies:
#       requires cocoaDialog v 3.0 beta 7 located at variable CD
#
# File Locations:
#   This script should be located at /private/var/uptimeCheck.sh
#   Upon the first instantiation,
#       A permanent LaunchDaemon will be created at variable launchDaemonStd
#   Depending upon conditions met,
#       A temporary LaunchDaemon may be created at variable launchDaemonAccel
#   extensive logging at variable logLocation
#
############################################################################################################

############################################################################################################
#
# NOTES:
#
# 4 conditions can result from this script:
#
# 1.) No Action - if uptime is less than the initialNotification threshold
# 2.) Soft Warning - if uptime is greater than initialNotification threshold but less than (maxUptime-increaseUrgency)
# 3.) Urgent Warning - if uptime is greater than maxUptime-increaseUrgnecy but less than maxUptime
#   a.) notify user
#   b.) place plist to call this script at frequency specified by acceleratedCheckFrequency
# 4.) Warning and Reboot - if uptime is greater than maxUptime.  5 minutes are provided for saving prior to shutdown
#   a.) notify user every thirty seconds
#   b.) hard shutdown
#
# Script needs to be called once after placement to enable continued use.  I deploy as a package with a
# post-install script.
#
# On initial deployment, some devices may be greatly in excess of the maxUptime value.  It is not desirable to shut
# them down with only 5 minutes warning.  In the event that the uptime is greater than maxUptime a 5th condition
# will occur.  It is similar to condition #4, but the countdown occurs over 2 hours.  This condition can only be
# reached once per device.
#
############################################################################################################

############################################################################################################
#                                                                                                          #
#  Variables Section                                                                                       #
#                                                                                                          #
############################################################################################################

############################################################################################################
# User Modifiable Variables
############################################################################################################

# Time conversions reference
# 1 hour = 3600
# 2 hours = 7200
# 4 hours = 14400
# 8 hours = 28800
# 1 day = 86400
# 2 days = 172800
# 3 days = 259200
# 4 days = 345600
# 5 days = 432000
# 6 days = 518400
# 7 days = 604800

# What is the desired initial notfiication uptime (in seconds)
# i.e. at what minimum uptime should Condition #2 be reached
# measured in seconds
initialNotification=345600

# What is the desired maximum uptime before an automated reboot?
# i.e. at what minimum uptime should Condition #4 be reached
# measured in seconds
maxUptime=604800

# With how much time remaining should the warnings become more urgent?
# i.e. how long before maxUptime should Condition #3 be reached
# measured in seconds
# Note that maxuptime will be reduced by this value!  It is not an uptime threshold.
increaseUrgency=86400

# What is the desired frequency for checking uptime?
# i.e. how often should this script run?
# measured in seconds
# Note that value is only applied during the first iteration of the script
# once the script is placed it will bypass creation of this file.  If you
# wish to modify this value for testing, refer to the comments in the
# Pre-Script cleanup and dependency verification section
checkFrequency=14400

# What is the desired frequency for checking uptime once condition 3 is met?
# This should be a fraction of the increaseUrgency value, but not so frequent that the computer becomes diffficult to use.
# measured in seconds
# Note that value is applied every time the script is instantiated
acceleratedCheckFrequency=3600

# Where should script logs be stored?
logLocation="/var/log/uptimeChecker"

#Location of CocoaDialog.app
CD="/private/var/CocoaDialog.app/Contents/MacOS/CocoaDialog"

############################################################################################################
# Fixed Variables - Do not modify!!!!!
############################################################################################################

userName=$(who |grep console| awk '{print $1}')
launchDaemonStd="/Library/LaunchDaemons/com.grcs.uptimeCheck.plist"
launchDaemonAccel="/Library/LaunchDaemons/com.grcs.acceleratedUptimeCheck.plist"

############################################################################################################
# Uptime calculation
############################################################################################################

# calculate value for lower boundary of urgent threshold
urgentThreshold=$(($maxUptime-$increaseUrgency))

# determine uptime
then=$(sysctl kern.boottime | awk '{print $5}' | sed "s/,//")
now=$(date +%s)
diff=$(($now-$then))
uptime=$diff

############################################################################################################
#                                                                                                          #
#  Functions Section                                                                                       #
#                                                                                                          #
############################################################################################################

############################################################################################################
# Function - Script Logging
############################################################################################################

#call as scriptLogging quotedTextForLog

scriptLogging(){

DATE=$(date +%Y-%m-%d %H:%M:%S)

echo "$DATE" " $1" >> $logLocation
}

############################################################################################################
# Function - appropriately display single v. plural values
############################################################################################################

#call as format number label

format(){
if [ $1 == 1 ]; then
    echo $1 $2
else
    echo $1 $2"s"
fi
}

############################################################################################################
# Function - appropriately display time (uptime or countdown)
############################################################################################################

#call as formatSeconds timeInSeconds

formatSeconds(){

passedSeconds=$1
displayHours=$(($passedSeconds/3600))
passedSeconds=$(($passedSeconds-($displayHours*3600)))
displayMinutes=$(($passedSeconds/60))
passedSeconds=$(($passedSeconds-($displayMinutes*60)))
if [ $displayHours = 0 ]; then
    if [ $displayMinutes = 0 ]; then
        formattedRemainingTime="$(format $passedSeconds " second")"
    else
        formattedRemainingTime="$(format $displayMinutes " minute") $(format $passedSeconds " second")"
    fi
else
    formattedRemainingTime="$(format $displayHours " hour") $(format $displayMinutes " minute") $(format $passedSeconds " second")"
fi

echo "$formattedRemainingTime"

}

############################################################################################################
# Function - display sticky shutdown counter
############################################################################################################

#call as displayCountdown timeSeconds title message

displayCountdown(){

timerSeconds=$1
rm -f /tmp/hpipe
mkfifo /tmp/hpipe
sleep 0.2

"$CD" progressbar --title "$2" --text "Preparing to shutdown this Mac..." 
--posX "right" --posY "top" --width 450 --float 
--icon "hazard" 
--icon-height 48 --icon-width 48 --height 90 < /tmp/hpipe &

## Send progress through the named pipe
exec 3<> /tmp/hpipe
echo "100" >&3
sleep 1.5

startTime=`date +%s`
stopTime=$((startTime+timerSeconds))
secsLeft=$timerSeconds
progLeft="100"

while [[ "$secsLeft" -gt 0 ]]; do
    sleep 1
    currTime=`date +%s`
    progLeft=$((secsLeft*100/timerSeconds))
    secsLeft=$((stopTime-currTime))
    formattedDisplayCounter=$(formatSeconds $secsLeft)
    echo "$progLeft $formattedDisplayCounter $3" >&3
done

}

############################################################################################################
#                                                                                                          #
#  Pre-Script cleanup and dependency verification                                                          #
#                                                                                                          #
############################################################################################################

scriptLogging "* Script Initiated"
scriptLogging "User is $userName"

############################################################################################################
# log pretty uptime
############################################################################################################

formattedUptime=$(formatSeconds $uptime)
scriptLogging "Uptime: $formattedUptime or $uptime seconds  User: $UserName"

############################################################################################################
# Install and load standard check-in plist if it does not exist
#
# Commenting out the the lines below ### will cause the plist to be recreated every time the script runs
# - refer to checkFrequency to determine how often this will occur
#
############################################################################################################

###comment out below line for testing (1 of 2)
if [ ! -e $launchDaemonStd ]; then
    #install plist
    /bin/cat <<EOM >$launchDaemonStd
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    <key>Label</key>
    <string>com.grcs.uptimeCheck.plist</string>
    <key>ProgramArguments</key>
    <array>
    <string>/private/var/uptimeCheck.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>StartInterval</key>
    <integer>$checkFrequency</integer>
    </dict>
    </plist>
EOM
    scriptLogging "$launchDaemonStd placed"

    #set the permission on the file just made.
    chown root:wheel $launchDaemonStd
    chmod 644 $launchDaemonStd
    scriptLogging "$launchDaemonStd permissions set"

    #load plist
    launchctl load $launchDaemonStd
    scriptLogging "$launchDaemonStd loaded"


    #assumes that plist does not exist because script has not run previously!!
    scriptLogging "Initial run condition met"
    if [ $uptime -ge $maxUptime ]; then
        scriptLogging "Uptime in excess of MaxUptime"
        scriptLogging "Uptime = $uptime"
        scriptLogging "MaxUptime = $maxUptime"
        launchctl unload $launchDaemonStd
        scriptLogging "$launchDaemonStd unloaded - cannot run during this countdown"
        #start 2 hour countdown
        scriptLogging "2 Hour Countdown Started"
        displayCountdown 7200 "Maximum Uptime Exceeded!" "until automatic shutdown."
    #upon return from function - force immediate hard shutdown
        scriptLogging "!Performing hard shutdown now!"
        shutdown -h now
    fi
###comment out below line for testing (2 of 2)
fi

############################################################################################################
#                                                                                                          #
#  Script Body                                                                                             #
#                                                                                                          #
############################################################################################################

###########################################################################################################
# Unload and remove accelerated plist (this is only installed to repeat condition #2 more frequently)
###########################################################################################################

if [ -e $launchDaemonAccel ]; then
    launchctl unload $launchDaemonAccel
    scriptLogging "$launchDaemonAccel unloaded"
    rm -f $launchDaemonAccel
    scriptLogging "$launchDaemonAccel deleted"
fi

############################################################################################################
# Condition Testing
############################################################################################################

# Test for Condition #4
if [ $uptime -ge $maxUptime ]; then
    #start 5 minute countdown
    displayCountdown 300 "Maximum Uptime Approaching!" "until automatic shutdown!"
    scriptLogging "!Performing hard shutdown now!"
    shutdown -h now

# Test for Condition #3 and temporarily load additional plist if condition met
elif [ $uptime -ge $urgentThreshold ]; then

    #########################################################################################################
    # place accelerated uptimeCheck plist
    #########################################################################################################

    /bin/cat <<EOM2 >$launchDaemonAccel
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    <key>Label</key>
    <string>com.grcs.acceleratedUptimeCheck.plist</string>
    <key>ProgramArguments</key>
    <array>
    <string>/private/var/uptimeCheck.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>StartInterval</key>
    <integer>$acceleratedCheckFrequency</integer>
    </dict>
    </plist>
EOM2

    #set the permission on the file just made.
    chown root:wheel $launchDaemonAccel
    chmod 644 $launchDaemonAccel
    scriptLogging "$launchDaemonAccel placed"

    #########################################################################################################
    # load accelerated check-in plist
    #########################################################################################################
    launchctl load $launchDaemonAccel
    scriptLogging "$launchDaemonAccel loaded"

    #########################################################################################################
    # notify user
    #########################################################################################################

    remainingTime=$(($maxUptime-$uptime))
    formattedRemainingTime=$(formatSeconds $remainingTime)
    secondsAdj="-v+"$remainingTime"S"
    rebootTime=$(date $secondsAdj +"%A at %r")
    $CD bubble --title "Reboot Urgently Needed" --text "Automatic Shutdown scheduled for $rebootTime" 
    --background-top "FFFF00" --background-bottom "FF9900" 
    --icon "caution" --no-timeout &
    scriptLogging "Urgent Warning Provided - Uptime was $formattedUptime"
    scriptLogging "Shutdown scheduled for $rebootTime"

# Test for Condition #2
elif [ $uptime -ge $initialNotification ]; then
#create temp file
    $CD bubble --debug --title "Reboot Needed Soon!" --text "Computer has been running for $formattedUptime." 
    --background-top "66FF00" --background-bottom "99CC00" 
    --icon "notice" --no-timeout &
    scriptLogging "Soft Warning Provided - Uptime was $formattedUptime"

# else assume Condition #1
else
    scriptLogging "No Action taken  - Uptime was $formattedUptime"
    scriptLogging "uptime: $uptime < threshold: $initialNotification"
fi

scriptLogging "* Script Completed"
exit 0

Daemoch
New Contributor

I'm looking at implementing something very much like this within our organization. Has there been any changes to these, or are they still running pretty much as outlined above?
Current versions are Mac OS 10.13 and Jamf 10.5 so it's been a little while since this was active.