1

I was trying to achieve this using a second account (which is the admin account) and Parental Controls, but it seemed this isn't possible to do so.

I know there are some programs which you can download that help you with this, (Cold Turkey, for example). But, it would be much easier if I could do this using only tools already available on macOS.

3
  • What times? I'll build a script.
    – JBis
    Aug 23, 2018 at 16:10
  • I would like to use the app only between 12:01 pm and 23:59 pm, every week on friday. The rest of the week it should remain blocked. Thank you in advance!
    – John Smith
    Aug 23, 2018 at 16:40
  • 1
    Do you mean "12:00 am and 11:59 pm"?
    – JBis
    Aug 23, 2018 at 18:41

2 Answers 2

3

You can do this with two built in tools:

  • Gatekeeper to allow/disallow access to apps (I've written about it in this post)
  • Launchd to handle the schedule

Gatekeeper

Using Gatekeeper, we can create "rules" that allow you to block/enable apps. Using your example, we can create a list of Apps that is only allowed to run on Fridays:

spctl --add --label "FridayApps" /Applications/SomeApp.app 

The benefit of this, is that you can add multiple apps with the same label and enable/disable them in one single command:

sudo spctl --disable --label "FridayApps"   <---- For Saturday thru Thursday
sudo spctl --enable --label "FridayApps"    <---- For Friday

Launchd

For this you will need a simple script to enable/disable the apps and you need to run this as a daemon (needs sudo privilege) so it has to reside in /Library/LaunchDaemons.

I used the naming convention com.user.FridayApps.plist and FridayApp.sh for the script.

Bash Script:

#!/bin/bash

DOW=$(date +%u)   # Sets the Day of Week; 5 = Friday
TOD=$(date +%T)   # Sets the time of Day
start="12:00:00"  # Sets start time   
end="23:59:00"    # Sets end time

if [ $DOW -eq 5 ]
then
    if [[ "$TOD" > "${start}"  &&  "$TOD" < "${end}" ]]
    then
      /usr/sbin/spctl --enable --label "FridayApps"
    fi
else
    /usr/sbin/spctl --disable --label "FridayApps"
fi

Launchd .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">
<dict>
    <key>Label</key>
    <string>com.user.FridayApps</string>
    <key>ProgramArguments</key>
    <array>
        <string>/User/MyName/script/location/FridayApps.sh</string>

    </array>
    <key>StartCalendarInterval</key>
    <!--  Weekdays are 1 - 5; Sunday is 0 and 7   -->
    <array>
        <dict>
            <key>Weekday</key>
            <integer>5</integer>
            <key>Hour</key>
            <integer>12</integer>
            <key>Minute</key>
            <integer>01</integer>
        </dict>

        <dict>
            <key>Weekday</key>
            <integer>6</integer>
            <key>Hour</key>
            <integer>00</integer>
            <key>Minute</key>
            <integer>00</integer>
        </dict>
    </array>

</dict>
<key>RunAtLoad</key> 
<true/>
</plist>

##Load the `.plist`

sudo launchctl load com.user.FridayApps.plist

How this works

What's happening here is two things:

  • launchd is running a script twice. Once at the time to run it on and another time to turn it off
  • a simple bash script to turn on/off the enabled app. It verfies the date and then runs the appropriate command
9
  • Didn't know you can use gatekeeper. Thanks!
    – JBis
    Aug 23, 2018 at 21:09
  • Theres one minor issue: If the computer is off at the exact second that launchd runs then the person can't use app for the entire day.
    – JBis
    Aug 23, 2018 at 21:11
  • @JBis - true. I forgot to add the RunAtLoad key so the script will automatically run and set the right state upon boot.
    – Allan
    Aug 23, 2018 at 21:24
  • Forgot how that works. Now thinking about it I could change mine. Mind if I copy your calendar intervals?
    – JBis
    Aug 23, 2018 at 21:25
  • Copy away...nothing proprietary here!
    – Allan
    Aug 23, 2018 at 21:26
0

Read the Intro

In the following tutorial you will do the following:

  1. Create a Configuration Profile that will block applications in a certain path
  2. An application that will add and remove the profile depending on the day
  3. A LaunchDaemon that will run the application every interval (5 min)

Create the App

Open this in Script Editor and export it as a read-only application and make sure stay open after run handler is not on

After exporting follow this guide to prevent it from show up in the dock.

   # Block Apps Based on Day By Josh Brown
    # Last Modified: Aug 23 2018
    on run
    if checkDay("Friday") then
        do shell script "sudo profiles remove -forced -identifier com.company.macos.blockapps"
    else
        do shell script "sudo profiles install forced -path /path/to/the.mobileconfig"
    end if
end run

on checkDay(myDay)
    set currentDay to weekday of (get current date)
    if (currentDay as string) is (myDay as string) then
        return true
    else
        return false
    end if
end checkDay

Create the Mobile Config

Use

<key>pathBlackList</key>
                <array>
                    <string>/path/to/an.app</string>
                    <string>/path/to/asecond.app</string>
                </array>

to control which apps to block.

Save the following to a file with the extension .mobileconfig

<?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>PayloadIdentifier</key>
    <string>com.company.macos.blockapps</string>
    <key>PayloadRemovalDisallowed</key>
    <true/>
    <key>PayloadScope</key>
    <string>System</string>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>9c24d6b3-6233-4a08-a48d-9068f4f76cf0</string>
    <key>PayloadOrganization</key>
    <string>Company Name</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
    <key>PayloadDisplayName</key>
    <string>Block Apps In User Folder</string>
    <key>PayloadContent</key>
    <array>
        <dict>
            <key>PayloadType</key>
            <string>com.apple.applicationaccess.new</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>PayloadIdentifier</key>
            <string>MCXToProfile.9c24d6b3-6233-4a08-a48d-9068f4f76cf0.alacarte.customsettings.2476221c-1870-4f3e-8c52-52386029c4cf</string>
            <key>PayloadEnabled</key>
            <true/>
            <key>PayloadUUID</key>
            <string>2476221c-1870-4f3e-8c52-52386029c4cf</string>
            <key>PayloadDisplayName</key>
            <string>Blocks all apps in the ~/ directory./string>
            <key>familyControlsEnabled</key>
            <true/>
            <key>pathBlackList</key>
            <array>
                <string>/path/to/an.app</string>
                <string>/path/to/asecond.app</string>
            </array>
        </dict>
    </array>
</dict>
</plist>

Create the LaunchDaemon

Note: You must be an admin to do this.

Save the following file to /Library/LaunchDaemons/

<?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.PlzUpvoteMy.answer</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/bin/open</string>
            <string>-W</string>
            <string>**/path/to/application.app**</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>StartCalendarInterval</key>
        <!--- Creds to @Allan for Calendar Interval -->
        <!--  Weekdays are 1 - 5; Sunday is 0 and 7   -->
    <array>
        <dict>
            <key>Weekday</key>
            <integer>5</integer>
            <key>Hour</key>
            <integer>12</integer>
            <key>Minute</key>
            <integer>01</integer>
        </dict>

        <dict>
            <key>Weekday</key>
            <integer>6</integer>
            <key>Hour</key>
            <integer>00</integer>
            <key>Minute</key>
            <integer>00</integer>
        </dict>
    </array>
        <key>UserName</key>
        <string>**UserToBlock**</string>
    </dict>
</plist>

Change the permissions with the following command:

sudo chown root:wheel /Library/LaunchDaemons/com.MyName.plist

Load the Daemon

Note: You must be admin to do this.

To start the daemon use this command:

sudo launchctl load /Library/LaunchDaemons/com.MyName.plist 

The program will scan for the apps every 5 seconds and close them if they are running.

To stop the Daemon use this command

sudo launchctl unload /Library/LaunchDaemons/com.MyName.plist 

Applaud Yourself

  1. Applaud yourself

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .