Big Sur: Deleting users after they have logged out

New Contributor

My team and I are trying to move away from DeepFreeze going forward with Big Sur but is kind of stumped on how to do it.

We work in a student lab with 200 macs so ultimately, we want to delete the users profile after the student have logged out. We used DeepFreeze because we granted all student admin privileges (required by the lab policy) and so with DeepFreeze, all user changes was reverted including the creation of the user profile. However, we found the slow updates with DeepFreeze as a company for each Mac OS release annoying so we want to move away from it if possible.

A lot of old threads point to logout hooks, but that has been deprecated. Some have pointed in using Offset, but it doesn't seem to be updated with Big Sur nor do we want to be dependent on a community script that is not properly maintained.

Has anyone successfully created a workflow to delete user profiles after user logs out in Big Sur? Our last resort would be running a script when the lab closes to remove all user profiles, but that would only be a workaround for us.

Any tips/suggestions would be appreciated.



Hello, Have you found a solution to this? I use a script that worked in Mojave. Our students log in with their AD credentials. When they logout, it deletes the home folder. Found that it would delete the contents first then on next logout from a user, it would delete the whole folder. Would specify which admin home directories to keep along with the root. That all being said, it does not work with BigSur. Would be interested if you were able to find a solution.

New Contributor III

I moved my script to the start up trigger. Deletes all users except my local admin accounts  on restart. 

New Contributor III

@dross Could you share how you have done this?

New Contributor III

I run this Script from a policy with the Startup trigger selected and ongoing frequency. 

# Name: remove-non-local-users
# Purpose: Removes all non-local accounts on machines to set Defaults.
# Will spare the 'fsadmin,' 'rduser,' and 'Shared' home directories.
users=`find /Users -type d -maxdepth 1 | cut -d"/" -f3`
# you can edit this to remove only accounts that haven't logged in for x days: add '-mtime +<# of days>' after maxdepth

# Script #
for i in $users; do
if [[ $i = "fsadmin" ]] || [[ $i = "Shared" ]] || [[ $i = "rduser" ]] || [[ $i = "fsa" ]]; then continue
jamf deleteAccount -username $i -deleteHomeDirectory
chmod -Rf 777 /Users/$i
rm -Rf /Users/$i
# Remove the student home directory but leave the account at the end.
#rm -Rf /Users/student



New Contributor III

Thanks, will give it a try!

New Contributor III

This seems to work for us! I modified it slightly for our purposes as below. Since machines rarely reboot, am going to set it to run on recurring checkin. Thanks for sharing!!



#Updated by Ashlar Trystan 2022-02-15
#Script to remove user profiles from public machines
#Originated by dross here:
# Will spare the 'Shared' and "admin" home directories.

#Gather current list of home directories.
#Only scan one level deep and only those that are older than 1 day
# To change the age, update the digit after '-mtime +'

users=`find /Users -type d -maxdepth 1 -mtime +1 | cut -d"/" -f3`

#We perform the deletion here. First, skip a list of local accounts we want to keep.
#Next, we give all users permission to make deletion easier. Can probably do that with less than 777 if we want to be more secure.

if [[ $i = "admin" ]] || [[ $i = "Shared" ]]; then continue
chmod -Rf 777 /Users/$i
rm -Rf /Users/$i

New Contributor III

I am afraid that this didn't work because we are not using the list of user accounts we created in the first part of the script. Instead, we're just deleting all user accounts except those that are "admin" or "shared". We need to invoke the users list as a variable to only delete directories that have not been logged in for more than a day. Going to have to work on it for a bit and will post final version later.

New Contributor III

In the end, this is what worked for us:


# Source:
# This script deletes local accounts that are older than 1 day. 
# The 1 day timeframe can be modified (-mtime +1).

# Behavior Note: We found during testing that if the policy trigger is set as "Recurring Check-In" and execution
# frequency is set as "Once every day" it will take exactly 48 hours from local account creation to delete
# local accounts on -mtime +1

# Runs using Launch Daemon – /Library/LaunchDaemons/
# version .7

DATE=`date "+%Y-%m-%d %H:%M:%S"`

# Don't delete local accounts
currentuser=`ls -l /dev/console | cut -d " " -f 4`

USERLIST=`/usr/bin/find /Users -type d -maxdepth 1 -mindepth 1 -mtime +1`

for a in $USERLIST ; do
    [[ "$a" == "$keep1" ]] && continue  #skip admin
    [[ "$a" == "$keep2" ]] && continue  #skip stlp
    [[ "$a" == "$keep3" ]] && continue  #skip shared
    [[ "$a" == "$keep4" ]] && continue  #skip current user

# Log results
echo ${DATE} – "Deleting account and home directory for" $a >> "/Library/Logs/deleted user accounts.log"
# Delete the account
/usr/bin/dscl . -delete $a  
# Delete the home directory
# dscl . list /Users UniqueID | awk '$2 > 500 { print $1 }' | grep -v Shared | grep -v admin | grep -v admin1 | grep -v .localized
/bin/rm -rf $a

exit 0

This is an interesting script, and a GREAT IDEA.

I've been forcing users with public facing shared devices to use the GUEST account. However, there are some cases where a user needs to utilize an account with Admin privileges.


For example, we have loaner devices that we provide for students and teachers in the library. I make them both use Guest Accounts. 

However, there are some cases where we need to loan a laptop with an Admin account because that user may need Admin privileges — and from my understanding, using your script would keep that local admin account and only delete standards accounts. Are you setting up Standard user accounts on certain machines and having it delete these accounts, then re-creating the Standard user(s) account(s) after they are deleted? I imagine you could set up an account creation payload and create a new user account after one is deleted on a re-occurring trigger basis, but that could get ugly or tricky. 

It would be nice if there was a script could clean account folders or if MacOS could recover after certain folders are cleaned (Desktop folder), Downloads, and maybe the Safari and Chrome browser cache for that user — similar to what CCCleaner or certain apps do on the Windows side, but in script form. 

I've thought about manually deleting the user account every single time the device is used, but that's a pain in the tail-feather. 💩


Thankfully, with Guest accounts, everything is taken care of at logout. I haven't seen a script that could function the way the Guest account does in terms of refreshing the session.


Any advice you or anyone can provide in this collective space of ideas would be greatly appreciated.

New Contributor III

A bit of context:

We manage both a computer lab and a checkout program. In the computer lab, students log in using their university account via AD. The checkout program, however, uses a generic (admin) account.  When computers are returned after checkout, they are wiped and reimaged so there is no issue with any user data being  left on the machines.

In the computer lab, we used Deep Freeze and would give all users admin access. Effectively, this allowed the users to make any changes they liked, and they would revert upon logout. Deep Freeze has always been somewhat painful to manage, and I wanted to find another solution. When Monterey was released, we suddenly found that students did not have admin rights as expected--some issue in the original release that was eventually fixed with a point release prevented rights from being applied. Through this experience, we learned that (after lockdown) students no longer had expectations of having admin rights and we were able to take them away and get rid of Deep Freeze in the process.

This change brought up a new issue for us: keeping the disk clean. It doesn't take long for enough users to log in to fully fill up a disk, and we needed a solution. As the computer lab is only wiped and reimaged a couple times a year, this was a problem.

In regards to the script, we specifically excluded the shared folder since some apps require that things be written/present there, our admin account, and the generic account for the checkout program. So far, this seems to be working very well for us.

I don't want to take credit for the script--we found and adapted someone else's after a lot of experimentation and searching for something that worked. In the end, after several things we tried (both borrowed and in house), this was the one that we found that did what we wanted without any fuss.

In regards to your question: using this script along with normal user logins seems to do the trick with keeping things clean. I suppose you could modify it to target only the contents of folders, but you likely don't want to create a situation in which someone has saved their files to one computer and cannot access it since another user is on it. Likewise, you don't want to be responsible for someone losing their information because they left their only copy on that one machine. For us, it has always been important to make clear that the students have no ability to leave data on the machines.

That is very interesting, and a fascinating backstory. I appreciate you sharing that. What made you not explore a Guest account? In essence, from my experience, at functions the same way.

New Contributor III

I inherited this space, and it was already using AD binding. It would have been very difficult to educate several tens of thousands of students to suddenly change, so it wasn't anything I actually considered until you wrote about it above. To go back in time many years, yours may have been the better solution.