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
No related posts.
Find more like this: AD Integration, Directory Services, Mac, Scripting , Active Directory, Admin, Directory Service, Mac, Open Directory, Scripting






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…
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?
@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.