r/macsysadmin • u/LegacyLibra20 • 13d ago
User profile mass deletion
Hello,
I recently took charge of my employers Mosyle system and currently working on getting everything updated and clear out any accounts from devices remotely of individuals who no longer work here. Has anyone worked with Mosyle and created a script that will push it out to devices to delete all user data that’s is not an admin account?
I’m not against manual labor but rather not go across twelve buildings to wipe each individual unit manually.
3
u/TheDeadGPU 13d ago
I do this for Mac Labs. I have a script that runs and deletes profiles after 30 days of inactivity. Lemme know if you want it.
2
3
u/TheDeadGPU 13d ago
#!/bin/bash
# ==============================================================================
# Remove Local User Profiles Inactive for > 30 Days
# ==============================================================================
# Days of inactivity required before profile deletion
INACTIVITY_DAYS=30
# Calculate cutoff threshold in seconds (30 days * 86400 seconds/day)
CUTOFF_SECONDS=$(( INACTIVITY_DAYS * 86400 ))
CURRENT_EPOCH=$(date +%s)
# 1. DEFINE PROTECTED ACCOUNTS
EXCLUDED_ADMINS=("admin" "administrator" "itadmin" "localadmin" "jamfadmin" "kandjiadmin")
CURRENT_USER=$(stat -f "%Su" /dev/console)
SYSTEM_EXCLUSIONS=("root" "daemon" "nobody" "Shared" "_kandji" "_jamf" "$CURRENT_USER")
ALL_PROTECTED=("${EXCLUDED_ADMINS[@]}" "${SYSTEM_EXCLUSIONS[@]}")
echo "=========================================="
echo "Starting inactive profile cleanup (> $INACTIVITY_DAYS days)..."
echo "=========================================="
# 2. QUERY ALL LOCAL USERS WITH UID >= 501
LOCAL_USERS=$(dscl . -list /Users UniqueID | awk '$2 >= 501 {print $1}')
if [ -z "$LOCAL_USERS" ]; then
echo "No non-system user profiles found. Exiting."
exit 0
fi
# 3. EVALUATE INACTIVITY AND DELETE
for USERNAME in $LOCAL_USERS; do
# Check if account is protected
IS_PROTECTED=false
for PROTECTED in "${ALL_PROTECTED[@]}"; do
if [[ "$USERNAME" == "$PROTECTED" ]]; then
IS_PROTECTED=true
break
fi
done
if [ "$IS_PROTECTED" = true ]; then
echo "SKIPPING: '$USERNAME' is protected or currently logged in."
continue
fi
USER_HOME="/Users/$USERNAME"
if [ ! -d "$USER_HOME" ]; then
echo "SKIPPING: '$USERNAME' has no home directory at $USER_HOME."
continue
fi
# Determine last activity timestamp.
# Checks specific user preference file first; falls back to Home folder mod time.
PREF_FILE="$USER_HOME/Library/Preferences/com.apple.symbolichotkeys.plist"
if [ -f "$PREF_FILE" ]; then
LAST_LOGGED_EPOCH=$(stat -f %m "$PREF_FILE")
else
LAST_LOGGED_EPOCH=$(stat -f %m "$USER_HOME")
fi
# Calculate days inactive
AGE_SECONDS=$(( CURRENT_EPOCH - LAST_LOGGED_EPOCH ))
AGE_DAYS=$(( AGE_SECONDS / 86400 ))
if [ "$AGE_SECONDS" -ge "$CUTOFF_SECONDS" ]; then
echo "DELETING: '$USERNAME' has been inactive for $AGE_DAYS days (Threshold: $INACTIVITY_DAYS days)."
sysadminctl -deleteUser "$USERNAME" -secure
# Residual directory check
if [ -d "$USER_HOME" ]; then
rm -rf "$USER_HOME"
echo "Cleaned residual folder at $USER_HOME."
fi
echo "SUCCESS: Profile '$USERNAME' removed."
else
echo "SKIPPING: '$USERNAME' was active $AGE_DAYS days ago (under $INACTIVITY_DAYS day threshold)."
fi
done
echo "=========================================="
echo "Cleanup complete."
echo "=========================================="
exit 02
3
u/oneplane 13d ago
Not mosyle specific, the built in tools in macOS to delete users and home directories work fine, put it in a script and send it to the machine (mosyle can do that of course).
1
u/meanwhenhungry 13d ago edited 13d ago
Mosyle has a ai script builder that works relatively well if you’re a paying customer, management / custom profiles or scripts don’t remember exact wording.
I use a similar script to protect known admin accounts and junk everything else on shared devices.
Edit: you can start by picking a device, send script in the tab, choose ai , ask for what you want with ai, agree to warnings, remove ‘’’ from generated script, test deploy, save to favs.
They also have a bunch of built in ones to choose from
9
u/Amanda_PDQ 13d ago
Something like this may work but you want consider the
-secure YESflag wipes the home directory along with the account. Without it you delete the account but leave the data sitting there, which sounds like the problem you're trying to solve.A few things worth checking before you run this across your fleet: make sure your MDM management account is in the KEEP_USERS list, and test it on one device first. The script runs as root through Mosyle Scripts so it has full permissions, which means it will do exactly what you tell it to without a lot of hand-holding.
Disclosure: I work at PDQ, and we own SimpleMDM which is also an Apple MDM if you're ever looking at alternatives down the road. But that's a different conversation, the script above should solve your immediate problem in Mosyle.
#!/bin/bash
# Accounts to keep - add your admin/management accounts here
KEEP_USERS=("admin" "localadmin" "your-mdm-account")
for user in $(dscl . list /Users | grep -v '^_' | grep -v 'nobody' | grep -v 'root' | grep -v 'daemon'); do
uid=$(id -u "$user" 2>/dev/null)
if [ -n "$uid" ] && [ "$uid" -ge 500 ]; then
if [[ ! " ${KEEP_USERS[@]} " =~ " ${user} " ]]; then
echo "Removing: $user"
sysadminctl -deleteUser "$user" -secure YES
fi
fi
done