Timed Restrictions on Macs

New Contributor II

Just putting this here for feedback, and for people to use if needed

We have about 1600 student macs in use, and there are a few kids who will play games in class/message friends/get distracted basically. Sometimes, a configuration profiles is okay, the parents are on board with the restrictions, but we wanted to have restrictions only apply during the school blocks.

The basic logic for this is
1. Check the time every 5 minutes
2. If it's during class time, check to see if the restrictions are applied
3. If they are? Do nothing. If not? Install them
4. If it's outside class time (this includes weekends and school holidays). check to see if the restrictions have been removed
5. They have? Do nothing. They haven't? Remove them

We need a package to install, and this is what's in the package
- restrictions.sh (see below)
- com.SCHOOL.it.restrictions.plist (see below)
- rs_stdout (log the output)
- disabled.txt (name changes based on enable/disable status, this is how it get's checked)
- com.SCHOOL.it.restrictions.mobileconfig (config profile downloaded from JSS to be installed)

install.sh (stored in JSS, ran after the package above has installed):

##Change Directory to the restrictions one added by the package
cd /Applications/SCHOOL/restrictions

##Make management.sh and restrictions.sh executable
sudo chmod a+x restrictions.sh

##Check if /Library/LaunchDaemons exists
##If not, then create it
if [ ! -d "/Library/LaunchDaemons" ]; then
sudo mkdir "/Library/LaunchDaemons"
##Copy plists into it
sudo cp com.SCHOOL.it.restrictions.plist /Library/LaunchDaemons/
##make plists read/writeable (644)
sudo chmod 644 /Library/LaunchDaemons/com.SCHOOL.it.restrictions.plist
##change ownership (chown) of plists to root user and wheel group
sudo chown root:wheel /Library/LaunchDaemons/com.SCHOOL.it.restrictions.plist
##load the plists into current launchd tasks
##Not doing this will mean the computer has to be restarted to load the plists
sudo launchctl load -w /Library/LaunchDaemons/com.SCHOOL.it.restrictions.plist


<?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">


## Check if its holidays
is_holidays() {
    ##Get the current date as a big old number YYYYMMDD
    current=$( date +"%Y%m%d")
    ##Will be set to true if it is the holidays
    ##Example for term 2 break in 2017
    #Start day is July 1 2017, so in YYYMMDD thats 20170701
    #End day is July 16 2017, so in YYYMMDD thats 20170716

    ##Term 2 Break 2017 20170701 - 20170116
    if [[ "$current" -ge 20170701 && "$current" -le 20170716 ]] ; then
            ##Echo the holiday period out to the log file, for debugging
            echo "Winter Holidays 2017"
    ## Check if its a public holiday

    #Example for racing cup 2017
    #On November 1 2017
    ##In YYYMMDD thats 20171101
    ## -eq is the equality check
    #Racing Cup - 20171101
    if [[ "$current" -eq 20171101 ]] ; then
            echo "Racing Cup 2017"
            HOLIDAYS = true

## Check if its during the school day
    ## Get the hour and minute as one string in 24 hour time
    dateHour=$( date +"%H%M")
    current=$( date +"%Y-%m-%d %H:%M")
    #remove leading zero so it isnt processed as an octal
    dateHour=$(expr $dateHour + 0)
    dayOfWeek=$(date +%u)

    #If it isnt a day off, then check if it's during school time
    if ! $HOLIDAYS ; then
        echo "SCHOOL TERM"
        #This compares the HHMM number (no colon) to the numbers for start and end times of a block
        #If between times for block 1, 2, or 3, then school is true, otherwise it's false

        #Check monday to friday
        if [[ "$dayOfWeek" -le 5 ]] ; then

            ##Check if we're during blocks 1, 2, 3, recess, lunch
            ##Example of block 1
            ## Block 1
            ## between 09:05 and 10:41
            if [[ "$dateHour" -ge 905 && "$dateHour" -le 1041 ]] ; then
                ##Echo out the time period for debugging if needed
                echo "Block 1"
                ##Set school to true, as we are in school time



## Check to see if the log is over 2mb
    ##Check to see how big the log file is
    ##If more than 2mb then remove
    actualsize=$(wc -c <"$logfile")
    echo "Log size is $actualsize bytes"
    if [[ $actualsize -ge $maxSize ]]; then
        echo "Log is 2mb or greater. Removing..."
        sudo rm rs_stdout
        sudo touch rs_stdout
        echo "Log Removed."

## Core script. Check if we're in school times (enable) or not (disable)
    echo "$current"
    if $SCHOOL ; then
        echo "Enable_RS"
        if [ -f disabled.txt ]; then
            echo "Currently Disabled..."
            echo "Enabling..."
            ##-I is install
            ##-F is telling it that its from a file
            ##This installs the restriction profiles
            sudo /usr/bin/profiles -I -F com.SCHOOL.it.restrictions.mobileconfig
            ##Change name of enabled/disabled.txt
            sudo mv disabled.txt enabled.txt
            echo "Enabled"
            echo "Already enabled"
        echo "Disable_RS"
        if [ -f enabled.txt ]; then
            echo "Currently Enabled..."
            echo "Disabling..."
            ##-R is Remove
            ##-F is telling it that its from a file
            ##This removes the restriction profile
            sudo /usr/bin/profiles -R -F com.SCHOOL.it.restrictions.mobileconfig
            ##Change name of enabled/disabled.txt
            sudo mv enabled.txt disabled.txt
            echo "Disabled"
            echo "Already Disabled"

    ##This just breaks up the log file into more readable sections
    echo "+----------------+

##Call all the functions

A few notes about all this:
I know it's possibly simpler to open the JSS up to external networks, and have it check in every so often to download a profile, but we don't want students without internet having them put on unfairly, or have them able to be removed if the JSS isn't available (turn wifi off)

Most of this was pieced together from about a dozen articles, mainly the plist and launchd aspects. I spent ages messing around with getting the plist to load correctly, handy app called LaunchControl was really helpful with setting everything up and finding problems. If there's any non-standard approach to the permissions or users, it's definitely not intentional.

The restrictions script is much longer, I've added dates in for school holidays for the next year, as well as known public holidays. I only included one example of each type of holiday here
There's also a check to see if the date is earlier than june 2017 (sometimes the batteries run flat and the time resets. This could be changed to always install restrictions if this happens, but as it happens most often on holidays, I'm staying on the safe side)