Logout script run through Policy not working 100%

bmak
Contributor
Contributor

Hi People,

I'm new to casper and have been going through this forum to get a better idea of how policies and scripts work but I'm having a problem with the below mentioned script (which I found here and and have modified it to work in our environment)

When I copy it to a workstation and run it through terminal as sudo it all works.
But when I create a policy and have the script copied via Casper Admin only the MCX removal files portion of the script is working. The deleting of the home directories doesn't work.

I'm hoping someone can shed some light on this for me.

Thanks in advance for view and assisting!

# Loop through users with homes in /Users; exclude any accounts you don't want removed (i.e. local admin and current user if policy runs while someone is logged in)

for username in `ls /Users | grep -v admin | grep -v Shared`
do
echo "Removing user profile: $username"
# dscl . delete /Local/Default/Users/$username
rm -rf /Users/$username
done

# Remove MCX files
echo "Removing MCX files"
rm -rf "/Library/Managed Preferences"

2 ACCEPTED SOLUTIONS

franton
Valued Contributor III

We've had similar issue with our public access computers. Try this script and see if it works for you. This version will need you to change part of the script to your local admin account name (or delete the entry). The script will also allow you to specify an account name to not delete via the script addition menu in the JSS.

#!/bin/bash

# Clear all non local admin accounts script
# Author: r.purves@arts.ac.uk

# All present user accounts except specified local admin account will be wiped!
# This script is meant to be run at startup as root

# Script is meant to be called by a Casper policy
# specifying the local user account name in parameter 4.

# Specified local admin account name

LocalAdminAct=$4

# Backup IFS and set it to linefeed on return chars instead of space.

OIFS=$IFS
export IFS=$'	
'

# Am I running as root user? If not, quit!

if [[ "$( /usr/bin/whoami )" != "root" ]]; then echo "Must be run as root user" >> $LogFile ; exit 1; fi

# Recursively find all user folders

for Account in `ls /Users`
do

# Exclude localized file, shared, guest and local admin accounts.

if [ $Account == .localized ] || [ $Account == Shared ] || [ $Account = Guest ] || [ $Account = **localadminaccount** ] || [ $Account == $LocalAdminAct ]
then
continue
fi

# Clean up and delete account

dscl . delete /Users/$Account > /dev/null 2>&1

rm -rf /Users/$Account

# End the loop here

done

# Let's set IFS back to the way it was

export IFS=$OIFS

# All done!

exit 0

View solution in original post

franton
Valued Contributor III

The script is meant to be run at logout. On our public access computers, we have it to tidy things up.

The *localaccountname* is just a placeholder for you to replace with whatever local admin account name you have.

If you wish to specify another account to keep on each computer, you specify it in the policy itself. Add the script to the policy as normal, you'll notice places to type in stuff. Make sure the account name you want to keep goes in no.4 ;) Alternatively delete that section of the script.

As for currently logged in users ... tricky. Thankfully i've done some work that way. The code you need is something like:

# Add this line to the variables section of the script
loggedinuser=($( who | grep "console" | cut -d " " -f 1 ))

You can then change that *localaccount* bit to something like this

if [ $Account == .localized ] || [ $Account == Shared ] || [ $Account = Guest ] || [ $Account = $loggedinuser ] || [ $Account == $LocalAdminAct ]

Obviously this is highly untested code on my part. Please be careful with it.

View solution in original post

10 REPLIES 10

dkucmierz
Contributor

I would guess that the user that is logging out is not getting the home directory deleted. I believe the logout hook gets executed before the user is completely logged out... which would lock you from deleting the home directory.

bmak
Contributor
Contributor

dkucmierz
Is their a way around that so that the user that logs out will have the home directory deleted?
Or am I stuck with the current user who logs out will their profile will remain there till the logout script is triggered again
and the then that home directory is being deleted.
hmmmmm

franton
Valued Contributor III

We've had similar issue with our public access computers. Try this script and see if it works for you. This version will need you to change part of the script to your local admin account name (or delete the entry). The script will also allow you to specify an account name to not delete via the script addition menu in the JSS.

#!/bin/bash

# Clear all non local admin accounts script
# Author: r.purves@arts.ac.uk

# All present user accounts except specified local admin account will be wiped!
# This script is meant to be run at startup as root

# Script is meant to be called by a Casper policy
# specifying the local user account name in parameter 4.

# Specified local admin account name

LocalAdminAct=$4

# Backup IFS and set it to linefeed on return chars instead of space.

OIFS=$IFS
export IFS=$'	
'

# Am I running as root user? If not, quit!

if [[ "$( /usr/bin/whoami )" != "root" ]]; then echo "Must be run as root user" >> $LogFile ; exit 1; fi

# Recursively find all user folders

for Account in `ls /Users`
do

# Exclude localized file, shared, guest and local admin accounts.

if [ $Account == .localized ] || [ $Account == Shared ] || [ $Account = Guest ] || [ $Account = **localadminaccount** ] || [ $Account == $LocalAdminAct ]
then
continue
fi

# Clean up and delete account

dscl . delete /Users/$Account > /dev/null 2>&1

rm -rf /Users/$Account

# End the loop here

done

# Let's set IFS back to the way it was

export IFS=$OIFS

# All done!

exit 0

bmak
Contributor
Contributor

Hi Franton,

Thanks for your version of the script do you run that script as part of a login script or a login script?
I'm still new to scripts and and deciphering your script as in parameter 4 within the Casper JSS script menu I specify the local admin account there.

But under your script what does this mean? [ $Account = *localadminaccount* ]

ALso what is IFS?

Apologies if these questions are quite newb. As I am newb to Casper and scripting.
Hopefully I'll be able to learn more about scripting through this great discussion forum.

Cheers,

Berry

bmak
Contributor
Contributor

Hi Franton,

I've been playing around with your script and it works too well lol
Upon login it runs and deletes all user profiles under /Users except for the named admin in Paramter 4 and the Shared folder. Is there a way I can have it not delete the current user who is logging in?

I'm stuck on that now..

Thank you again for your help so far Frankton!

Cheers,

Berry

franton
Valued Contributor III

The script is meant to be run at logout. On our public access computers, we have it to tidy things up.

The *localaccountname* is just a placeholder for you to replace with whatever local admin account name you have.

If you wish to specify another account to keep on each computer, you specify it in the policy itself. Add the script to the policy as normal, you'll notice places to type in stuff. Make sure the account name you want to keep goes in no.4 ;) Alternatively delete that section of the script.

As for currently logged in users ... tricky. Thankfully i've done some work that way. The code you need is something like:

# Add this line to the variables section of the script
loggedinuser=($( who | grep "console" | cut -d " " -f 1 ))

You can then change that *localaccount* bit to something like this

if [ $Account == .localized ] || [ $Account == Shared ] || [ $Account = Guest ] || [ $Account = $loggedinuser ] || [ $Account == $LocalAdminAct ]

Obviously this is highly untested code on my part. Please be careful with it.

franton
Valued Contributor III

IFS refers to an environment variable inside unix (and bash) called the "internal field separator". By default when passing text back and forth in loops and variables, unix will treat spaces as a new line and so without this change the script will barf big time on any folder/file name that has a space in it.

So the script backs up the standard IFS setting to OIFS. When the script is complete, it restores IFS back to default for compatibility with other unix programs. It's just good practice.

bmak
Contributor
Contributor

Hi Franton,

Thanks for taking the time to explain IFS to me as well as the script nuances and what to do to modify the script to keep the current user. I think I confused myself as I read in the comment (#) that this script is to be run on startup as root and I've mistaken that for login. I'll try it upon logout which is what I originally wanted.

Can you suggest any online resources in terms of scripting for OS X / Casper?

Many thanks for your help and guidance Franton!

bmak
Contributor
Contributor

Thanks again for your help Franton!
I wanted to let you know that the logout script is now working!
I've tested the script and it's all working I've modified it slightly to make it work in our environment.
1 script down X amount to go lol

I really appreciate your help Franton.

Cheers!

tlarkin
Honored Contributor

Hi Everyone,

I think this solution is great, and useful to a lot of Casper users, especially in a lab environment where users need to be scrubbed from machines on a regular basis. I just wanted to chime in and add one small piece of advice when detecting local user accounts. If I were a smart user, and some how was able to move my home folder outside of /Users then this script would break, or if I were a clever System Administrator I may move a user's home folder out of /Users for some reason and totally forget I ever did that. Directory Services under the hood keeps records of all this data in the Berkley database, and each user is assigned a unique ID, or UID. Any local user account created in a normal way will have a UID of 501 to 999. Any network/portable AD/OD/LDAP account will have a UID of 1001 or greater. This has been consistent for OS X since 10.4 for me in many work flows.

So, for example, I use dscl (Directory services command line) to grab all users with UID of greater than 500. This also allows me to hide Admin and Casper user accounts by ensuring their UID is less than 500. That way I never have to deal with pattern matching, or inverted greps to make sure users like guest, shared, or admin get excluded from my scripts.

Example code:

$ dscl . list /Users UniqueID | awk '$2 > 500 { print $1 }'
casperadmin
casperinstall
test
testad
tlarkin

You can use something like this to build arrays of user, and furthermore detect where their home folder is, so for example.

$ dscl . read /Users/tlarkin NFSHomeDirectory | awk '{ print $2 }'
/Users/tlarkin

You can easily alter these methods to automatically detect user account information and accurately detect user attributes from dscl, and now have to assume things, or rely on grep -v.

Hope this helps,
Tom