Migrate Local User to Domain Account

by on January 14, 2010 » Add more comments.

If you are migrating your machines to authenticate via Active Directory, you may need to convert your local user accounts and their home folders to an AD user account and retain the home folder. I had a script posted here but that version was Tiger only because it used NI* commands.

The following script is written in bash and can be run by double clicking (it’s a .command) as a user with sudo rights (all admin users have this right by default). It will prompt for your admin password, then present a list of numbered local users. Enter a number from the list for the user you want to migrate, then it will ask for the network ID. It runs in a loop until you select the option for “Finished” which will exit the script.

This should work with Tiger, Leopard or Snow Leopard and can easily be modified to work with OD user accounts (change the check4AD variable to check for OD instead).

To download the script, click here.

#!/bin/sh
Version=1.0
# Modified 1/14/2009
 
# MigrateLocalUserToDomainAcct.command
# Patrick Gallagher
# http://macadmincorner.com
#
 
# This script should not need any modification in most enviornments. 
# If the script does not execute when run, you may need to 'chmod +x /path/to/thisScript' to make it executable
 
clear
 
netIDprompt="Please enter the network ID for this user: "
listUsers="$(/usr/bin/dscl . list /Users | grep -v eccsadmin | grep -v _ | grep -v root | grep -v uucp | grep -v amavisd | grep -v nobody | grep -v messagebus | grep -v daemon | grep -v www | grep -v Guest | grep -v xgrid | grep -v windowserver | grep -v unknown | grep -v unknown | grep -v tokend | grep -v sshd | grep -v securityagent | grep -v mailman | grep -v mysql | grep -v postfix | grep -v qtss | grep -v jabber | grep -v cyrusimap | grep -v clamav | grep -v appserver | grep -v appowner) FINISHED"
FullScriptName=`basename "$0"`
ShowVersion="$FullScriptName $Version"
check4AD=`/usr/bin/dscl localhost -list . | grep "Active Directory"`
osversionlong=`sw_vers -productVersion`
osvers=${osversionlong:3:1}
 
echo "********* Running $FullScriptName Version $Version *********"
 
# If the machine is not bound to AD, then there's no purpose going any further. 
if [ "${check4AD}" != "Active Directory" ]; then
	echo "This machine is not bound to Active Directory.\nPlease bind to AD first. "; exit 1
fi
 
RunAsRoot()
{
        ##  Pass in the full path to the executable as $1
        if [[ "${USER}" != "root" ]] ; then
                echo
                echo "***  This application must be run as root.  Please authenticate below.  ***"
                echo
                sudo "${1}" && exit 0
        fi
}
 
RunAsRoot "${0}"
 
until [ "$user" == "FINISHED" ]; do
 
	printf "%b" "\a\n\nSelect a user to convert or select FINISHED:\n" >&2
	select user in $listUsers; do
 
		if [ "$user" = "FINISHED" ]; then
			echo "Finshied converting users to AD"
			break
		elif [ -n "$user" ]; then
			if [ `who | grep console | awk '{print $1}'` == "$user" ]; then
				echo "This user is logged in.\nPlease log this user out and log in as another admin"
				exit 1
			fi
 
			# Determine location of the users home folder
			userHome=`/usr/bin/dscl . read /Users/$user NFSHomeDirectory | cut -c 19-`
 
			# Get list of groups
			echo "Checking group memberships for local user $user"
			lgroups="$(/usr/bin/id -Gn $user)"
 
 
			if [[ $? -eq 0 ]] && [[ -n "$(/usr/bin/dscl . -search /Groups GroupMembership "$user")" ]]; then 
			# Delete user from each group it is a member of
				for lg in $lgroups; 
					do
						/usr/bin/dscl . -delete /Groups/${lg} GroupMembership $user >&/dev/null
					done
			fi
			# Delete the primary group
			if [[ -n "$(/usr/bin/dscl . -search /Groups name "$user")" ]]; then
  				/usr/sbin/dseditgroup -o delete "$user"
			fi
			# Get the users guid and set it as a var
			guid="$(/usr/bin/dscl . -read "/Users/$user" GeneratedUID | /usr/bin/awk '{print $NF;}')"
			if [[ -f "/private/var/db/shadow/hash/$guid" ]]; then
 				/bin/rm -f /private/var/db/shadow/hash/$guid
			fi
			# Delete the user
			/usr/bin/dscl . -delete "/Users/$user"
 
 
				# Verify NetID
				printf "\e[1m$netIDprompt"
				read netname
				/usr/bin/killall DirectoryService
				sleep 10
				/usr/bin/id $netname
				# Check if there's a home folder there already, if there is, exit before we wipe it
				if [ -f /Users/$netname ]; then
					echo "Oops, theres a home folder there already for $netname.\nIf you don't want that one, delete it in the Finder first,\nthen run this script again."
					exit 1
				else
					/bin/mv $userHome /Users/$netname
					/usr/sbin/chown -R ${netname} /Users/$netname
					echo "Home for $netname now located at /Users/$netname"			
				fi
			break
		else
			echo "Invalid selection!"
		fi
	done
done

Bookmark and Share

No related posts.

Find more like this: AD Integration, Directory Services, Mac, Scripting , , , , , ,

53 Responses to Migrate Local User to Domain Account

  • MIke says:

    Can anyone give *exact* steps for running this in Lion? i.e. – should we run it in a local admin account only? Should the machine already be bound to AD or not? I ran this once (haphazardly since the outcome didn’t matter much) and while the files and folders did migrate, the user had lost permissions to just about everything. Restoring those permissions on all of the folders and in more than too many cases, sub-folders as well, was no fun.

    Kudos to the script author(s) though. This was sorely needed…

  • Timothy says:

    This script worked for me, sort of. It orphaned the existing local admin account and all its content. I was obliged to set perms on the orphaned account and populate them down through that structure, then copy over content from Documents to AD user Documents, Pictures to Pictures, Movies to Movies…. How was this script helpful then?

  • Patrick says:

    @Timothy

    That’s not the normal result of this script. I haven’t used this script in a long time so it’s possible it needs to be updated for Lion. We mainly used it while we were migrating to AD, that’s long done now and all our new deployments start off with AD.

    One thing that stands out is that Lion now has the opendirectoryd process instead of DirectoryService so that bit would need to be updated in this script.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">