Skip to main content

I am needing a script that can be added to our summer update configuration that will delete every user with the exception of admins. Anyone had any luck doing this? I have tried using Tom Larkin's script and it seems to remove the home directories from /Users how ever the accounts are still populated in SystemPreferences>Accounts. Any ideas?



https://discussions.apple.com/message/12165862#12165862



dscl . -delete /Users/


dscl . list /Users | grep -v "_"


#!/bin/bash

UserList=`/bin/ls /Users | /usr/bin/grep -v "Shared"`

for u in $UserList ; do

if [[ `/usr/bin/dscl . read /Groups/admin GroupMembership | /usr/bin/grep $u -c` == 1 ]]

then /bin/echo "Admin account detected skipping..."

else /usr/bin/dscl . delete /Users/$u && /bin/rm -rf /Users/$u

fi

done

That looks like it should work. The only reason it would not (that I can see) is if the home folders do not have the same name as the actual user account. E.g., if the short name is nextyoyoma but the home folder is named charlie, this would not delete the directory entry for the user.



If you go to terminal and run:



dscl . list /Users | grep "insert username"



EDIT: My brain totally skipped over the first two lines before the shebang. Those probably won't do anything, but it would be a good idea to take that out. In other words, the script really starts at:



#!/bin/bash



you shouldn't get any output if the script worked correctly. If you get no output, try a quick restart and see if the entries go away. If you get the username output, the script didn't work for some reason. You can try:



sudo bash -x /path/to/script to see the result of every line and maybe find out what is going wrong.


I ran the script again with as you suggested and it does indeed successfully remove the home folder for each user, however even after a restart the names of the deleted users are still populated in the Accounts prefPane. When you choose to remove one the OS does NOT prompt you to delete their home folder nor ask if you want to save it as a dmg. It just simply deletes. I have tried removing a few plists for SystemPreferences as well, still no change in the accounts prefpane.


dscl . list /Users gives me a list of the same users populated in the Accounts prefpane as well.


are these local users or are they active directory/open directory accounts?



btw, running the script again will not accomplish anything if there are no home folders in the /Users/ folder. The reason is that the script relies on the list of users found in that folder to know what to delete.


these are AD users


Ok, I can tell you that is most likely the problem. I don't know enough about active directory to tell you what to do at this point, but I believe this script is only deleting users in the local domain.


Ok, I can tell you that is most likely the problem. I don't know enough about active directory to tell you what to do at this point, but I believe this script is only deleting users in the local domain.


You know and thats ok, the main goal behind this is to free up space and clutter! I appreciate your help. Ill leave this thread open incase someone know how to remove those accounts from the Accounts prefpane. Again thank you!


The "dscl . delete /Users/username" command should remove it from the Accounts prefpane.



My script builds a list of users with UniqueID's higher than 1000 (this way it's only looking at cached AD users). It then checks for home directories older than 21 days and then removes the account and home directory for that user. It also only deletes users who are members of our students group in AD.



#!/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:]')" =~ "your student AD group" ]]; 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

Works like a charm thank you. I need to learn more about awk!


Hey everyone,



What Chad Brewer outlined is what I use personally when trying to scope out data in scripts by checking a UID of a user account. If it is a mobile AD account, it will create a local account and give it a UID of greater than 1,000.



If you don't use the mobile account option in your AD binding, you can also have dscl look at the LDAP path of your server and do the same thing.



My opinion (not fact) is that any sort of local admin that is used for internal IT use should be hidden and have a UID of under 500 so whenever you need to add/move/modify users/groups you can do so with out touching your local internal IT admin accounts.



thanks,
Tom


When I run Tom's script from JSS I get the following errors in policy log. It does however remove the non-admin mobile accounts and home directory from my test machines. Is this a problem with script or am I missing something?



Script Result: <dscl_cmd> DS Error: -14009 (eDSUnknownNodeName)
delete: Invalid Path
<dscl_cmd> DS Error: -14009 (eDSUnknownNodeName)
delete: Invalid Path


Hey Rick,



By default dscl looks to the local path for users. So, any mobile account or local account that exists in the local BSD database will be found with my previous script I wrote there. If you the accounts you are trying to remove aren't mobile accounts or local you would have to pump in the full LDAP path into the dscl command.



Does that help you?



thanks,
Tom


Hey Tom,



They are mobile accounts and per my post the script did remove the non-admin accounts and home directories but the error in the log concerned me. I did some looking around and it appears the two errors were generated from the local admin and mobile admin as the script identifies them and the error relates to Missing Group Identifiers but I verified on other system that they aren't missing by doing
dscl . -read /Groups/admin GroupMembership and both accounts show as part of admin Group Membership. So definitely not a problem with Group Identifier that I can tell. If I make the admin accounts hidden which I agree with you they should be, I don't get the error.


tom, that last post was confusing. dscl uses the path you specify, not any specific path by default. when you use "." to point to the local default node, that's where it will operate. you could use 'dscl /Search' to use any path in the host's search path without specifying the directory node. in this case, that's not necessary, as any mobile account (if it really is mobile) will show up as a normal account in the local node. if you're looking to remove non-local directory accounts, i'd say you shouldn't do it from a client.



a more robust way to do this is to query only the local directory service for these users and grab the homedirs from these account records. iterating over a file listing of /Users is flawed. i have something that does this already and will post in a bit. trying to get to work at the moment…


I'm trying to get this script to work to delete mobile accounts older than 2 days. I know I'm probably missing something stupid, in my testing (Lion), it's deleting all mobile accounts regardless of age.



Can anyone help me figure out what I'm doing wrong? I took out the AD check line from cbrewer's script above.



#!/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 -not -name "*.*" -mtime +2 | grep "$a"

if [[ $? == 0 ]]; then
dscl . delete /Users/"$a" #delete the account
rm -r /Users/"$a" #delete the home directory
fi

done


The script outputs showing only the account older than 2 days being deleted, but when I look at users folder and system prefs, the mobile account created only 1 hour old was also deleted?


why not use the built in stuff to delete accounts?
look under Managed Preferences aka MCX on your management page and check out the mobile account time to live


We use MCX expiry for Snow Leopard, it's not working in Lion 10.7.4 in my testing.



I have a case in with Apple on it. If anyone has MCX account clearing working in Lion I'd prefer that?


Sally, what happens when you just run "find /Users -type d -maxdepth 1 -mindepth 1 -mtime +2" from terminal? If your script output only shows the accounts older than 2 days, I'm not sure how it would be deleting other accounts as well. You sure some other process didn't remove the account?


cbrewer,



Thanks for replying. I think you helped me find the issue. When I run
"find /Users -type d -maxdepth 1 -mindepth 1 -mtime +2"



It only returns the one mobile account older than 2 days (teststudent). My other test account was just added to this computer today (test) wasn't returned.



But, when I run the script, both accounts were again deleted. It seems like the issue is the similarity of names on my test accounts.



When I run the script, what's returned is
"deleting home dir and account for following users... /users/teststudent and then another line for /users/teststudent"



I logged in with a 3rd account (not similar in name) and ran the script again, and it left the 3rd test student account this time properly. Our students follow a convention that I don't think in production this would be an issue for us but will continue to test.


Im attempting to use cbrewer's script on a 10.10 machine. I get the message that "Deleting account and home directory for the following users..." but no accounts are removed. Has anyone else ran into that?


@ShawnIT I Just gave it a try on 10.10 and had no issues. You sure the computer you are using it on has user accounts that meet the criteria? It'll echo out "Deleting account and home directory for the following users..." even if there's no accounts to actually remove.


@cbrewer][/url I can run the dscl . list /Users UniqueID | awk '$2 > 1000 {print $1}' line in terminal and it returns about 30 users. Im sure I am just making a simple type somewhere. Here is what I copied and pasted into my editor.



#!/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

@ShawnIT Unless your users are members of a group called "bls students", I'd remove or change that line. That was an example from my environment.


@cbrewer Wow I am sorry about that I looked at that on and off for hrs today. Its been that kind of day for me everyting has been backwards for me. Works perfect! Thanks for you help!!


Reply