Just to clarify since I'm low on sleep these days,
This does not delete local accounts on the computer since its scoped to users with a UID over 1000 correct?
If I take out the line for
if [[ "$(id $a | tr '[:upper:]' '[:lower:]')" =~ "bls students" ]]; then
And change the days to 30, this should essentially just delete Moblie AD accounts older than 30 days correct?
Also does this leave in place admin AD Mobile accounts?
Gabe Shackney
Princeton Public Schools
Hi Everyone,
I just got notified this thread was updated via email. I was recently doing some workflows around creation date of user accounts with some people who wanted to scrub out local accounts after a certain date. This was all tested in Yosemite, so I do not know how directory services is different in each version of OS X.
To get a user account's creation date you can run this:
dscl . readpl /Users/tlarkin accountPolicyData creationTime | awk -F: '{ print $2 }' | tr -d " " | cut -d "." -f 1
This will return the date the account was created in Epoch time
You can see how old it is with a little math.
todayEpoch=$(date "+%s")
creationDate=$(dscl . readpl /Users/tlarkin accountPolicyData creationTime | awk -F: '{ print $2 }' | tr -d " " | cut -d "." -f 1)
daysOld=$(expr ${todayEpoch} - ${creationDate})
From here you can simply write some logic into your script to see how many days the account has existed, and set your integer for expiration. So, if you wanted to expire accounts every 90 or 180 days you could simply test to see if the value is greater than either of those integers, and then take action.
This is just one way to do it. If these are AD accounts you will have to query the AD record from dscl, and do a bit more math since I think AD uses a different time format and doesn't use standard Epoch time.
Hope this helps,
Tom
@gshackney
You'd definitely want to take out or modify that line. Also, take note that of the -not -name "." part. I'm using that to skip any accounts that have a period in them. You'll probably want to modify that as well.
Also, this will most likely remove admin AD users unless you do something to exempt them.
One thing I'm seeing is if this script runs it keeps the deleted users from logging in again (with an error) until the machine is rebooted.
Otherwise its working perfectly! Thanks!
Gabe Shackney
Princeton Public Schools
Frustrating the Config Profile setting to delete mobile accounts after X days is broken in 10.10.3 - worked great in 10.9.4.
I used the script above for the same bug in 10.8.4 I think it as back in 2012.
Back to testing this script again for use next school year. thankful this post still exists!
My district uses S####### naming schema for the students and a mix of E######## and older user names for the staff. I have modified the script to delete all of the student accounts from the system, it works on both LDAP and AD mobile accounts.
Chris Lastovica
Casper Admin Austin ISD
Austin Texas
#!/bin/sh
userList=`dscl . list /Users UniqueID | awk '$2 > 1000 {print $1}'`
echo "Deleting account and home directory for the following users..."
for a in $userList ; do
find /Users -type d -maxdepth 1 -mindepth 1 -name "S[0-9]*" | grep "$a"
if [[ $? == 0 ]]; then
dscl . delete /Users/"$a" #delete the account
rm -r /Users/"$a" #delete the home directory
fi
done
lastoch This worked for my in my Yosemite 10.10.5 environment. Our University uses the u####### naming scheme for student IDs and this worked charm. It deletes student accounts from Users and Groups as well as the the home directory while leaving staff accounts and admin accounts alone. I simply changed your 'S' to a 'u' to suit my needs. Cheers.
Hey guys I know this hasn't been posted on for sometime, but I am running into an issue that I can't seem to get passed. Our fleet is currently running 10.11, and the script appears to run, displays the echo command but then doesn't show what has been deleted and doesn't appear to be doing anything. I have changed the section where it requires a group membership and I still am not getting any idea what is wrong.
Is there a way to get the top half of this to run on it's own, just to see what it is returning before it gets passed to the deletion section? Is there a to see what the require group needs to look like?
Thanks for the support and sorry for reviving an old post.
@Sean_Ginn Considering there's at least 4 variations of this script posted on the thread, it may be a good idea to post the version you're using so someone can examine it and help out. I suspect some under the hood changes in 10.11 are causing the issue, but I think seeing what you're working with would be best to start with.
@mm2270 Sorry I didn't even think about that posting that. The script that I am using is the first one posted by @cbrewer because I love the idea of being able to remove just student accounts and leaving teacher accounts alone, and doing this based on their group membership. Thank you again for the support.
#!/bin/sh
userList=`dscl . list /Users UniqueID | awk '$2 > 1000 {print $1}'`
echo "Deleting account and home directory for the following users..."
for a in $userList ; do
if [[ "$(id $a | tr '[:upper:]' '[:lower:]')" =~ "bls students" ]]; then
find /Users -type d -maxdepth 1 -mindepth 1 -not -name "*.*" -mtime +21 | grep "$a"
if [[ $? == 0 ]]; then
dscl . delete /Users/"$a" #delete the account
rm -r /Users/"$a" #delete the home directory
fi
fi
done
Quick update...
I was able to get it working by removing
#!/bin/sh
if [[ "$(id $a | tr '[:upper:]' '[:lower:]')" =~ "bls students" ]]; then
...
fi
Any ideas on how to get this working? Right now I have to be restrictive with where this script will go as it can't go on teacher machines. While this isn't a big deal, but i'd like to remove any and all stale student accounts across our district. I have changed out "bls students" for our group name and it doesn't seem to be able to correctly differentiate and just ignores all of the users.
@Sean_Ginn
The line you removed is what checks to see if the user is a member of a certain AD group. In my case "bls students" is what I wanted to check against. If you have a different student AD group, just substitute the name.
@cbrewer Thanks for the response, I was able to gather that information from the earlier posts, but I was running into an issue getting it to run with our current group name, because I am for lack of a better word a complete and total noob when it comes to shell scripting.
I'm pretty good at reading and deciphering most of it and put it to use, but this section totally evaded me and looks a little bit like Swahili. I changed out "bls students" with our AD group name, but it didn't seem to do anything and just displayed the text from the Echo command. So I was able to remove it and it ran like a champ.
Now the issue i'm running into is how to deal with users who aren't mobile accounts, but are forced to create local home directories on the computer when they login with their AD creds. I was able to write a workaround with the following line...
#!/bin/sh
find /Users -type d -maxdepth 1 -mindepth 1 -not -name "*.*" -not -name "Shared" -not -name "hadmin" -mtime +21 -exec rm -rf {} ;
Which will obviously delete their user folders (since these users don't exist in the Users and Groups section of System Preferences) that are older than 21 days, but it doesn't have the beauty of yours where it is able to use dscl to determine the UUID, separate those users into student and teacher account, and only remove the ones that are 21 days old and student accounts.
Is there a way to check both the user folder and system preferences simultaneously, or individually works as well, for LDAP users?
Sorry for a long winded response, I was just really intrigued by all of this and have a lot of questions,
@Sean_Ginn @cbrewer
I am dealing with the same issue. Using AD mobile accounts with a forced local home. I just went through my jump start and this was the one issue no one could help me resolve. All of our students are in the "student" group. If I just replace "bls students" with my "student" group will all work fine or is the local home going to cause me issue beyond my understanding at this early stage?
Thanks, this community is an amazing resource.
Can anyone help me? I work for a school district that allows teachers to checkout laptops from the library when needed. As a result I have several accounts on computers that do not need to be there. So I am trying to find a script that will delete mobile accounts even if they are an admin accounts except for a specified list. Example I want to keep the local admin and esteacher ( mobile admin) and esstudent ( mobile managed account) . Thanks for any help you can give I am VERY NEW to scripting.
@TJ78620 The solution in this thread might work for you.
You'd modify the "KEEP" section with something like this:
KEEP=("/Users/Shared" "/Users/esteacher" "/Users/esstudent" "/Users/[localadmin]")
As well as the age of the accounts in this section:
AGE=122 # Delete /Users/ folders inactive longer than this many days
Thanks Ryan I will give it a try
5 year old thread, but since it's still active I will add the latest version of what I'm using. I think it's a little more robust than what I first posted. I've also considered moving the home directories to an archive directory instead of nuking them.
#!/bin/bash
userList=`dscl . list /Users UniqueID | awk '$2 > 1000 {print $1}'`
echo "Deleting account and home directory for the following users..."
for user in $userList ; do
if [[ "$(id $user | tr '[:upper:]' '[:lower:]')" =~ "my student group" ]]; then
if [[ "$(find /Users -type d -maxdepth 1 -mindepth 1 -not -name "*.*" -mtime +21 | grep "$user")" =~ "$user" ]]; then
dscl . delete /Users/"$user" #delete the account
rm -r /Users/"$user" #delete the home directory
echo "$user"
fi
fi
done
OR if you don't want the AD group lookup part...
#!/bin/bash
userList=`dscl . list /Users UniqueID | awk '$2 > 1000 {print $1}'`
echo "Deleting account and home directory for the following users..."
for user in $userList ; do
if [[ "$(find /Users -type d -maxdepth 1 -mindepth 1 -not -name "*.*" -mtime +21 | grep "$user")" =~ "$user" ]]; then
dscl . delete /Users/"$user" #delete the account
rm -r /Users/"$user" #delete the home directory
echo "$user"
fi
done
This could be useful for a situation where we need keep our loaner computers cleaned up. If i simply didnt want to search for a student group or a specific name would i simply remove "=~ "my student group" and =~ "my student group"
all id be looking to do is delete any account older than x amount of days old.
Running this...
find /Users -type d -maxdepth 1 -mindepth 1 -mtime +1
... does not return the proper list of users whose accounts are older than 24 hours. Running "ls -l /Users" returns a confirmation that the folders have not been modified for several days. After bashing my head against my desk as well as some research, it looks like -mmin is better at this. So this works for our scenario...
#!/bin/sh
# Remove Mobile Accounts.sh
# Removes all mobile accounts from the system
userList=`dscl . list /Users UniqueID | awk '$2 > 1000 {print $1}'`
echo "Deleting account and home directory for the following users..."
for a in $userList ; do
find /Users -type d -maxdepth 1 -mindepth 1 -mmin +$((60*24)) | grep "$a"
if [[ $? == 0 ]]; then
dscl . delete /Users/"$a" #delete the account
rm -r /Users/"$a" #delete the home directory
fi
done
Here's the script I use to clean AD accounts. It started life as something to just delete all AD accounts. When we switched from classroom sets of MacBook Airs to a truer 1-to-1 model of students being assigned a laptop they could take home I modified the script so a student could run it from Self Service and delete any AD account but theirs (we had some teachers that didn't bother to have regular laptop assignments with their class sets resulting in some machines having over 70 users created).
Note that my environment is all >= macOS 10.10, so I use sysadminctl
rather than dscl
and rm
to delete the user accounts.
#!/bin/bash
################################################################################
# DeleteADUsers.sh
#
# Requires Mac OS X 10.10 or newer
# If run as root, deletes all AD accounts
# If user is logged in, asks to verify login ID and will not delete that account
################################################################################
adusers=$(dscl . list /Users UniqueID | awk '$2 > 1000 {print $1}')
currentuser=$(stat -f "%Su" /dev/console)
response="2" # Presume confirmation failure
if [[ "$currentuser" != "root" ]]; then
# If we're not root, ask user to verify their login ID
response=$(/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -title "Verify login ID" -heading "Verify login ID" -description "Please verify that $currentuser is your login ID" -button1 "That's Me" -button2 "Not Me")
if [ "$response" != "0" ]; then
echo "Did not get confirmation from user, no accounts will be deleted"
fi
else
echo "Running as root, so all AD accounts will be deleted"
response="0" # Always set confirmation response when root
fi
if [ "$response" == "0" ]; then
echo "Deleting AD user accounts..."
for user in $adusers ; do
if [ "$user" != "$currentuser" ]; then
/usr/sbin/sysadminctl -deleteUser "$user"
echo "$user deleted"
fi
done
fi
I want to use the above script to delete AD users older than "X" days. I've tried modifying it, but my scripting skills could use a bit more work. The script works pretty well, but I noticed a couple strange behaviors that maybe someone with more knowledge could explain? I ran this script on one of our student lab computers with about 75 accounts. We use AD accounts that create a mobile account on login. Most of these accounts do NOT end up in the Users & Groups pref pane, however about 8 or 9 DID. In summary, if you look at /Users/ there are 75 folders, but only 8 or 9 of them are in U&G list.
All accounts that were in /Users/ but NOT in the U&G pref pane were deleted (except one.... weird part). I could not see anything about that one account that would explain it being left alone (not logged in, etc.)
I ran the script again and this time ALL accounts (except admin, shared) were deleted, the only accounts left were the ones in the U&G, and the straggler that didn't go away the first time... Not sure why this didn't happen on the first run, but did the second.
tl;dr
I want to modify the above script to ONLY delete AD accounts OLDER than "X" days
Thanks in advance!!!
@cbrewer
I feel like an absolute newb here, but I'm trying to make your script delete any mobile accounts; regardless of age. I've changed -mtime +21 to -mtime 0; but still not getting the desired results. We're looking to scope this to loaners for once they are checked in; it will completely wipe the mobile accounts.
Any help would be much appreciated!
Edit: Scratch that. Took out the "-not" flag, and things are nice and dandy. Thanks!
We are running a script similar to the ones above, and it is working as intended. It logs when it ignores a user due to it not being a student account, ignores the current user, ignores a user due to recent activity, and removes a user due to no recent activity. However, I am running into a bizarre problem where sometimes some of my users' home folders are not updating with a modification date/time upon login. During some troubleshooting we have determined that some users' home folders have a modification date/time that is older than their last login when viewed from the last command. Has anyone else seen anything like this before?
@ChrisCox
I've seen what you're seeing, but haven't looked into it too much. For now, we aren't removing user accounts and home directories with this method.