Tuesday, March 30, 2021

Clearing User Files on Macs

In some environments, it is desirable to clear all the user created and downloaded content from a Mac when the user logs out. Perhaps there is only one generic account or you're trying to strongly encourage users to only store things on servers or online services like Google Drive. To create this effect in my environment, I wrote a LaunchAgent and a configurable shell script. I've tested this up to MacOS 10.12, a.k.a. Sierra, but it will probably work on newer versions as well.

To start, the "engine" of this system is the following shell script. Place the code in the file /usr/local/bin/clear_local_files.sh and make it executable. You might need to make this directory manually. You can do that with mkdir -p /usr/local/bin && chmod 755 /usr/local/bin. When you finish pasting the following code into your preferred text editor (BBEdit is a great option), you can save the file clear_local_files.sh to that location. Then use chmod +x /usr/local/bin/clear_local_files.sh to make it executable.


#!/bin/sh
#
# This script will clear away a lot of the files that users are likely
# to leave behind on the local disk.  This is meant as a way to encourage
# users to store files on the server, so that they aren't accidentally
# lost when a computer breaks down, is replaced, is upgraded, etc.
#

# The following is a list of directories at the root of the user's home
#   which will be cleared.
# Note:  The lack of Library allows account customizations to stay on the
#   local disk.
# Note:  Some sub-items will be moved back in a following setting.
# Warning:  Never put " in " in this list, as it will cause a syntax
#   error with loops.
clearDirs=( "Desktop" "Documents" "Downloads" "Movies" "Music" "Pictures" "Public" "Sites" )

# The following is a list of items to preserve in the user's home.
# Warning:  Never put " in " in this list, as it will cause a syntax
#   error with loops.
# Warning:  Be careful with spaces, colons, and slashes in file names.
keepDirs=( "Documents/Microsoft User Data" "Movies/iMovie data folders" "Movies/iMovie Events.localized" "Movies/iMovie Projects" "Movies/iMovie Library.imovielibrary" "Movies/iMovie Theater.theater" "Music/iTunes" "Pictures/iPhoto Library.photolibrary" "Pictures/Photos Library.photoslibrary" "Public/Drop Box" "Sites/images" "Sites/index.html" "Sites/Streaming" )

# This should be executed in the home directory of the current user.
cd ~

# Make a place to hide things.
mkdir ~/.backup0

# Move things into that hidden location
for item in "${clearDirs[@]}"
do
        if [ -e "${item}" ];
        then
                mkdir -p .backup0/"${item}"
                mv "${item}"/* .backup0/"${item}"/
        fi
done
        
# Move the things we're preserving out of the hidden location and back where they're supposed to be.
for item in "${keepDirs[@]}"
do
        if [ -e ".backup0/${item}" ];
        then
                mv ".backup0/${item}" "${item}"
        fi
done

# Get rid of anything that has been around too long.
if [ -e ~/.backup9 ];
then
        rm -rf ~/.backup9
fi

# "Age" each hidden backup by one "notch"
for index in {8..0}
do
        # Make sure it exists before moving it, to avoid errors.
        if [ -e ~/.backup${index} ];
        then
                index2=`expr "$index" + 1`
                mv ~/.backup${index} ~/.backup${index2}
        fi
done


exit

The next step is to make this run whenever a user logs out. However, it is easier to make this run at login than logout. A small difference and mostly unnoticable to the end user, so this is what I went with. To do this, I made a LaunchAgent by putting the following code into a file named com.reviewmynotes.clearLocalFiles.plist located at /Library/LaunchAgents.


<plist version="1.0">
<dict>
        <key>KeepAlive</key>
        <false>

        <key>Label</key>
        <string>org.cairodurham.clearLocalFiles</string>

        <key>LowPriorityIO</key>
        <true>

        <key>ProgramArguments</key>
        <array>
                <string>/usr/local/bin/clear_local_files.sh</string>
        </array>

        <key>RunAtLoad</key>
        <true>

        <key>LimitLoadToSessionType</key>
        <array>
                <string>Aqua</string>
        </array>

</true></true></false></dict>
</plist>

Now logout and login. Anything in the locations listed in clearDirs and not listed in keepDirs should be moved into a hidden folder called .backup1. At each login, that folder will be renamed so the number goes up by one. The folder .backup9 will be deleted each time. This gives you a chance to save people from their own mistakes.

This system can be easily deployed via tools like Munki, Jamf, and FileWave.