Change AD Domains with FV2 Enabled Users

stevewood
Honored Contributor II
Honored Contributor II

I am in the process of migrating my users from using a mix of OD and AD to a new AD domain. The users are all local users on their machines, and all laptop users have FileVault2 enabled. I would like to do this via Self Service so that the users can move themselves when they are ready.

I have cobbled together a script that works for the migration of the user: removes any current OD or AD bind, deletes the local account with dscl, binds to the new domain, changes ownership of the home folder to the new AD user. The problem I am having is with the FV2 enabled devices. Once you delete the local user account with dscl, the user is not part of FV2 anymore.

I've tried using cocoaDialog to get the user's password and then use fdesetup to add the user, but the user has to exist locally first. That means the user has to login to the machine once before I can add their user to the FV2 creds.

I've thought of a few ways to possibly handle this using a logout policy to set another logout policy, modifying the local user via dscl instead of deleting the user, and decrypting the drive before doing the move.

Has anyone had to do this before, and is there an easier way? With the amount of time I've been working on this I could have probably manually moved everyone, but I'm too stubborn to do that. :-)

Thanks!

34 REPLIES 34

mm2270
Legendary Contributor III

Hey @stevewood][/url][/url - are these AD accounts going to be cached mobile accounts? I'm assuming so since you're talking about FileVault.
If so, take a look at the createmobilaccount binary in the OS. Its designed exactly for the purpose of creating directory service based accounts without needing to physically log in to do it.

/System/Library/CoreServices/ManagedClient.app/Contents/Resources/createmobileaccount -h

That will print out the help page for the tool. You'll see you can use an -n flag to specify the name and a -h flag for the home directory. You can just point it to their existing home directory since you already know what that is.
You could potentially even send the password with the -p flag to cache their password to the new account if you're capturing that with cocoaDialog. You'll need to verify what they enter is correct against AD though, but I assume you were already thinking of doing that.

Once you confirm the account is successfully created in dscl, you should then be able to add them into the FileVault authorized list by utilizing their password Are you also authorizing a local account on the Mac for FV2 that you're using for that purpose, or a Recovery Key?

Edit: Meant to say one more thing,. I can't verify it at the moment, but I believe using the -h flag will allow you to use their existing home folder and not try to create a new one. I would just test that to be sure, but I believe that's how it handles that scenario.

jcurrin
New Contributor III

I wouldn't decrypt the drive. We found it to be problematic.

I might not be grasping the entire process, but what about before deleting the local account. Pull the user info from the new AD server, remove the account, then manually create the account, and then add the user to FV2. Or does the user have to physically log in for FV2 to recognize the user?

mm2270
Legendary Contributor III

To my knowledge the user does not need to physically log in before they can be added in to the FV2 authorized list. The account needs to exist in directory services, or show in dscl, but they should not need to log in first.

But, just to be clear, you can't just create the user with simple dscl commands since that creates a local account, not tied to the AD account. My directions above in using "createmobileaccount" is the way you need to do it, or, they have to log in to the account while connected to the network (which does the same thing as "createmobileaccount")

There may be some additional ways to create the account, but if so, I'm not familiar with them.

stevewood
Honored Contributor II
Honored Contributor II

@mm2270 thank you for that. I had forgotten about "createmobileaccount" and honestly didn't think about using that. I'll start testing that now to see if it will work. I'll post back with results later.

stevewood
Honored Contributor II
Honored Contributor II

@mm2270 I owe you a beer at JNUC! I was able to successfully migrate a user from one AD domain to another on a FileVault encrypted volume and have the user added to FV. I need to clean up the script a bit and once I do, I'll post it here and on Github.

Thanks again Mike!

iJake
Valued Contributor

I'll be real interested to see it!

stevewood
Honored Contributor II
Honored Contributor II

I've posted the scrubbed version of the script to my Github account: http://goo.gl/4y4kD4

I'm also posting here, but the script on Github will get any updates I make. This script will log user names and passwords in a clear text log on the system. If you do not need to troubleshoot, comment out the sections at the top of the script that covering logging.

Any comments are welcome.

#!/bin/sh

# Name:  moveDomains.sh
# Date:  28 May 2014 v1.0
# Updated: 18 Jun 2014 v1.1
# Author:  Steve Wood (swood@integer.com)
# Purpose:  used to move users from one AD domain to a new one, or from OD to AD
# Updates:  v1.1 - set GroupID to static
#   - v1.1 - including message to users using jamfhelper
#           - adding code to check for domain membership
#           - adding logic for FileVault encrypted drives
#   - v1.2 - use of createmobileaccount to get around FileVault
#
# Prerequisites - when adding this to the JSS, make sure to configure Parameter 4 for the local admin user
#                   and Parameter 5 as the local admin user password to add the user to FileVault.  Need
#                   cocoaDialog installed on the local system.
#
# NOTE: you may want to turn off logging (comment out 5 lines under #Globals & Loging) so that no passwords
# are captured.

# Globals & Logging 
LOGPATH='<WHERE YOU STORE LOGS>'  # change this line to point to your local logging directory
if [[ ! -d "$LOGPATH" ]]; then
    mkdir $LOGPATH
fi
set -xv; exec 1> $LOGPATH/movedomainslog.txt 2>&1  # you can name the log file what you want
version=1.2
oldAD='<OLD AD DOMAIN>'  # set this to your old AD domain name
newAD='<NEW AD DOMAIN>'  # set this to the new AD domain name
currentAD=`dsconfigad -show | grep -i "active directory domain" | awk '{ print $5 }'`
CD="/private/var/inte/bin/cocoaDialog.app/Contents/MacOS/cocoaDialog"  ####  set this to the location of cocoaDialog on your systems
osVersion=`sw_vers -productVersion | cut -d. -f1,2`
adminEmail='YOUREMAIL@YOURDOMAIN.COM'  ## enter an email address to receive notification of failure at

## Grab the user's home folder location
userHome=`dscl . read /Users/swood NFSHomeDirectory | awk '{ print $2 }'`

## Because of FileVault, if a system is encrypted it has to be a 10.8 or above machine

ENCRYPTIONEXTENTS=`diskutil cs list | grep -E "$EGREP_STRINGHas Encrypted Extents" | sed -e's/|//' | awk '{print $4}'`

if [[ "$ENCRYPTIONEXTENTS" = "Yes" ]]; then

    if [[ $osVersion = "10.7" ]]; then

        ## If not 10.8 or above we cannot continue. Tell the user this.  Adjust the -description to what you need/want
        /Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType hud -title "Wrong OS Version" -heading "Wrong OS Deteced" -description "In order for us to move you to the new domain, you need to be on OS 10.8 or higher.  Please upgrade via Self Service to Mavericks (10.9) and then re-run the Move Domains item."
        exit 1

    fi
fi

# let the user know what we are doing
#### Change the dialog to what you want to tell your users

banner=`/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType hud -title "Moving Domains" -heading "Moving Domains Header" -description "We are moving your user account to the new authentication domain.  When we are completed, your computer will restart and you can use your new account inforation." -icon <PATH-TO-YOUR-ICON> -button1 "Proceed" -button2 "Not Now" -defaultButton 1 -cancelButton 2 -timeout 60 -countdown` 

if [[ $banner == "2" ]]; then

    echo "User canceled the move."
    exit 1

fi

# Grab current user name
loggedInUser=`/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'`

##### if you do not have OD deployed you can remove the follwing lines
# unbind from LDAP
# sinc there is no easy way to determine if bound to OD, we will just run against our OD for good measure

dsconfigldap -r <YOUR OD DOMAIN>
#####

# unbind from AD
# check to see if we are bound to our current AD or not.  If not we can skip this

if [[ "$currentAD" = "$oldAD" ]]; then

    # remove the config for our old AD
    # you need a user in your AD that has the rights to remove computers from the domain
    # you can also set this to a parameter in the JSS and pass as a variable

    dsconfigad -remove $oldAD -user <networkuser> -pass <networkuserpass>   

fi

# remove the local user from the machine so we get the proper UID assigned in dscl
dscl . delete /Users/$loggedInUser

# bind to new AD
# using a JAMF policy to bind to the new AD

jamf policy -id <policynumber> # can also use a custom trigger for the policy

### verify that the move was successful
checkAD=`dsconfigad -show | grep -i "active directory domain" | awk '{ print $5 }'`

if [[ "$checkAD" != "$newAD" ]]; then

    echo "SOMETHING WENT WRONG AND WE ARE NOT BOUND"

    #####  SEND AN EMAIL TO THE ADMIN  #####
    message1="$loggedInUser attempted to run the moveDomain.sh script and it failed to bind to $newAD."
    echo -e "$message1" | mail -s "Move Domains Script Failure" $adminEmail
    exit 99

fi

# reset permissions
### some of the code below is courtesy of Ben Toms (@macmule)

###
# Get the Active Directory Node Name
###
adNodeName=`dscl /Search read /Groups/Domain Users | awk '/^AppleMetaNodeLocation:/,/^AppleMetaRecordName:/' | head -2 | tail -1 | cut -c 2-`

###
# Get the Domain Users groups Numeric ID
###

domainUsersPrimaryGroupID=`dscl /Search read /Groups/Domain Users | grep PrimaryGroupID | awk '{ print $2}'`

accountUniqueID=`dscl "$adNodeName" -read /Users/$loggedInUser 2>/dev/null | grep UniqueID | awk '{ print $2}'`


chown -R $accountUniqueID:$domainUsersPrimaryGroupID /Users/$loggedInUser


### Check to see if FileVault is enabled.  If it is we will need to grab some info from the user
#### this section will get stored in the log file if left on and will store the end user's password and
#### the admin user's password in clear text.  If not testing, disable logging by commenting out lines
#### under the Globals & Logging section above.

if [[ "$ENCRYPTIONEXTENTS" = "Yes" ]]; then

    # now we need to add the new UID to FV2
    # Use cocoaDialog to get the current user's password
    userPassword=`$CD standard-inputbox --informative-text "Please enter your $newAD password:" --float`
    userPassword=`echo $userPassword | awk '{ print $2 }'`

    # create the plist file:
    echo '<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    <key>Username</key>
    <string>'$4'</string>
    <key>Password</key>
    <string>'$5'</string>
    <key>AdditionalUsers</key>
    <array>
        <dict>
            <key>Username</key>
            <string>'$loggedInUser'</string>
            <key>Password</key>
            <string>'$userPassword'</string>
        </dict>
    </array>
    </dict>
    </plist>' > /tmp/fvenable.plist  ### you can place this file anywhere just adjust the fdesetup line below

## Testing using createmobileaccount

    /System/Library/CoreServices/ManagedClient.app/Contents/Resources/createmobileaccount -n $loggedInUser

    # now enable FileVault
    fdesetup add -i < /tmp/fvenable.plist

fi

### Restart the computer

shutdown -r now

jthurwood
New Contributor III

Hi @stevewood

Ive been using a combination of your script with some others to use Self Service to:

1.Create a new user account using the createmobileaccount syntax

  1. Add the user in Filevault 2 (All of our machines are already encrypted, i just need the new user added to the allowed list

Im struggling to get the latter working. I used your script to create the plist file, then the following command to add the user from the enablelist

sudo fdesetup add -i < /tmp/fvenable.plist

When running this i keep getting this error Error: Authentication of FileVault failed.

Any ideas?

jthurwood
New Contributor III

The script i have created is below

#!/bin/sh
# Create new user for Self Service
# Joe Thurwood 17/09/2014

# Set cocoaDialog location
CD="/private/etc/Ogilvy/Applications/CocoaDialog.app/Contents/MacOS/CocoaDialog"

# Dialog to enter the User name and the create $USERNAME variable
rv=($($CD standard-inputbox --title "Username" --no-newline --informative-text "Enter the name of the new user to add"))

USERNAME=${rv[1]}

if [ "$rv" == "1" ]; then echo "User said OK"
elif [ "$rv" == "2" ]; then echo "Canceling" exit
fi

# Dialog to enter the Password and the create $PASSWORD variable
rv=($($CD secure-standard-inputbox --title "Password" --no-newline --informative-text "Enter the password of the new user to add"))

PASSWORD=${rv[1]}

if [ "$rv" == "1" ]; then echo "User said OK"
elif [ "$rv" == "2" ]; then echo "Canceling" exit
fi

#Create Mobile Account
sudo /System/Library/CoreServices/ManagedClient.app/Contents/Resources/createmobileaccount -n $USERNAME -p $PASSWORD

# create the FileVault plist file: echo '<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Username</key> <string>'$USERNAME'</string> <key>Password</key> <string>'$PASSWORD'</string> <key>AdditionalUsers</key> <array> <dict> <key>Username</key> <string>username</string> <key>Password</key> <string>password</string> </dict> </array> </dict> </plist>' > /tmp/fvenable.plist ### you can place this file anywhere just adjust the fdesetup line below

# now enable FileVault
sudo fdesetup add -i < /tmp/fvenable.plist

stevewood
Honored Contributor II
Honored Contributor II

So, in the plist section, the first username and password strings are supposed to be the machine's local admin user and password. That's why I was passing as Parameter 4 and Parameter 5 from the JSS. So in the policy for the Self Service item, under Parameter 4 you would have the admin name, and under Parameter 5 you'd have the password for that user. Here is a shot of mine:

external image link

The second Username and Password key is the end user's. So, change the plist section to something like this:

# create the FileVault plist file:
echo '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Username</key>
<string>$4</string>
<key>Password</key>
<string>$5</string>
<key>AdditionalUsers</key>
<array>
<dict>
<key>Username</key>
<string>'$USERNAME'</string>
<key>Password</key>
<string>'$PASSWORD'</string>
</dict>
</array>
</dict>
</plist>' > /tmp/fvenable.plist

Try that after making the changes to the script in the policy and adding the Parameter 4 and Parameter 5 info.

jthurwood
New Contributor III

Thanks for a quick response @stevewood I set the parameters in the policy but still got the same error

/usr/sbin/jamf is version 8.73
Executing Policy London Self Service create new user...
[STEP 1 of 2]
Mounting smb://10.86.9.58/CasperShare$ to /Volumes/CasperShare$...
[STEP 2 of 2]
Running script London Create new User from Self Service.sh...
Script exit code: 0
Script result: User said OK
User said OK
2014-09-17 15:49:21.522 createmobileaccount[7416:507] MCXCCacheMCXRecordAndGraph(): vproc_swap_integer(NULL, VPROC_GSK_PERUSER_SUSPEND, &(uid=1662711852), NULL) failed
2014-09-17 15:49:22.051 createmobileaccount[7416:507] MCXCCacheMCXRecordAndGraph(): vproc_swap_integer(NULL, VPROC_GSK_PERUSER_RESUME, &(uid=1662711852), NULL) failed
createmobileaccount built Mar 21 2014 21:19:49
Error: Authentication of FileVault failed.
Unmounting file server...

stevewood
Honored Contributor II
Honored Contributor II

Hmm...And you're entering the local admin user/pass in the $4 and $5 parameters in the JSS, right? I would start with verifying that the local account was actually created on the system, because of the two lines indicating createmobileaccount had failed.

If the account is there, verify that the local admin user/pass is being passed to the script/plist. You can do this by creating the plist but not running the fdesetup portion and then going to /tmp and looking at the plist.

That's where I'd start. Post back what your results are and we can go from there.

jthurwood
New Contributor III

@stevewood

This link might suggest it no longer works in 10.9?

http://www.qaster.com/q/400404868373815296/rtrouton+Ever+get+Error+Authentication+of+FileVault+failed+running+the+inputplist+command

stevewood
Honored Contributor II
Honored Contributor II

If you read what @rtrouton posted in that dialog, if the local admin user is not already enabled for FileVault, then you will not be able to use the local admin to authorize the addition of more users. In that case you'd need to revert to using a recovery key to authorize the addition.

If you do "fdesetup list" from the terminal, is your local admin listed there? If not, you'll need a user that is listed there to add users.

rtrouton
Release Candidate Programs Tester

In 10.8, any admin user could enable a user for FileVault 2 but Apple changed that in 10.9. I've got a post on this available here:

https://derflounder.wordpress.com/2013/10/24/enabling-users-for-filevault-2-with-a-non-enabled-admin...

jthurwood
New Contributor III

Hi @stevewood

Yes the admin user is listed

gblo-cs03960:~ joe.thurwood$ sudo fdesetup list
Password:
joe.thurwood,FB7315EF-A622-41D7-9A19-1F4797D28388
admin,96C88048-BB02-4F81-B95C-F0A3E8924778

What is a bit weird is when i check the policy i see this under the script

London Create new User from Self Service.sh / $computerName $userName admin <password>

Were still using Casper 8until November, but should $computerName $userName not be $userName $password?

jthurwood
New Contributor III

Also i can see the fvenable.plist is being created

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Username</key>
<string>$4</string>
<key>Password</key>
<string>$5</string>
<key>AdditionalUsers</key>
<array>
<dict>
<key>Username</key>
<string>username</string>
<key>Password</key>
<string>**</string>
</dict>
</array>
</dict>
</plist>

stevewood
Honored Contributor II
Honored Contributor II

Ah, but the $4 and $5 are not being expanded. Add single quote to the string:

<key>Username</key>
<string>'$4'</string>
<key>Password</key>
<string>'$5'</string>

So, make that change in the script and try again.

jthurwood
New Contributor III

@stevewood][/url Sooo!

The admin account is now being passed to the fvenable.plist but i'm still getting the same error :-(

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Username</key>
<string>admin</string>
<key>Password</key>
<string>password</string>
<key>AdditionalUsers</key>
<array>
<dict>
<key>Username</key>
<string>vidhu.kapur</string>
<key>Password</key>
<string>password</string>
</dict>
</array>
</dict>
</plist>

/usr/sbin/jamf is version 8.73
Executing Policy London Self Service create new user...
[STEP 1 of 2]
Mounting smb://10.86.9.58/CasperShare$ to /Volumes/CasperShare$...
[STEP 2 of 2]
Running script London Create new User from Self Service.sh...
Script exit code: 0
Script result: User said OK
User said OK
createmobileaccount built Mar 21 2014 21:19:49
Error: Authentication of FileVault failed.
Unmounting file server...

stevewood
Honored Contributor II
Honored Contributor II

What about trying the encryption manually? Since you know the user's name and password, from the terminal try to add the user to FileVault:

fdesetup add -usertoadd <username>

You'll be prompted for the password to unlock the drive, which is the local admin password, and then for the user's password. Does that work?

To reverse, you can simply delete the user from dscl (dscl . delete /Users/<username>).

rtrouton
Release Candidate Programs Tester

If the password is known and the user has admin privileges, there's also the route of going through System Preferences:

  1. Log in at the OS login window as the non-enabled admin account

  2. Open System Preferences and go to the FileVault preference pane

  3. Click the lock to unlock the preference pane and authenticate when prompted.

  4. Click the Enable Users button in the preference pane

  5. The previously non-enabled admin user account will appear with a green checkbox to show that the account has been enabled.

This approach has worked since FileVault 2 was first introduced in Lion and it continues to work in Mavericks.

jthurwood
New Contributor III

Hi @stevewood

It looks like i'm there. enabling the user now although the Policy still fails with these two errors

2014-09-18 09:40:07.653 createmobileaccount[44987:507] MCXCCacheMCXRecordAndGraph(): vproc_swap_integer(NULL, VPROC_GSK_PERUSER_SUSPEND, &(uid=1662711852), NULL) failed
2014-09-18 09:40:08.286 createmobileaccount[44987:507] MCXCCacheMCXRecordAndGraph(): vproc_swap_integer(NULL, VPROC_GSK_PERUSER_RESUME, &(uid=1662711852), NULL) failed

Thank you very much with you help on this, it would have been a struggle with it.

Thanks

jason_bracy
Contributor III

Just wanted to let everyone know That @stevewood's script was very helpful in my Domain Migration Project. We are about ready to kick it off and I thought I'd just add a helpful tip regarding FV enabled users.

Instead of deleting the user via DSCL I have modified the script to get the current userID, the new userID and then perform a DSCL command to change the userID and ownership. This does away with the need for a FV enabled Admin account being installed on the machine prior to migration.

loggedInUserID=`dscl . read /Users/$loggedInUser UniqueID`

Unjoin oldAD, Join newAD

domainUsersPrimaryGroupID=`dscl /Search read /Groups/Domain Users | grep PrimaryGroupID | awk '{ print $2}'`

accountUniqueID=`dscl "$adNodeName" -read /Users/$loggedInUser 2>/dev/null | grep UniqueID | awk '{ print $2}'`

dscl . -change /Users/$loggedInUser UniqueID "$loggedInUUID" "$accountUniqueID"

chown -R $accountUniqueID:$domainUsersPrimaryGroupID /Users/$loggedInUser

Let me know if anyone sees any issues with this approach. So far it has worked well in testing. I was worried that other directory information would not be changed using this method, but it seems that once the UniqueID is set that the AD plugin replaces all of the fields with the info from the new AD forest.

jason_bracy
Contributor III

In case anyone is interested, I have a cleaned version of my Domain Migration Script. I have stripped away any dependancies (including Casper) and have written in variables for most items. I'm happy to receive any feedback - positive or negative :-)

#!/bin/sh

# Name:     moveDomains.sh
# Date:     28 May 2014 v1.0
# Updated:  20 April 2015 v1.3
# Author:   Steve Wood (swood@integer.com)
#           Jason Bracy (bracyj@saic.com)
# Purpose:  used to move users from one AD domain to a new one
# Updates:  v1.1 - set GroupID to static
#   - v1.1  - including message to users using jamfhelper
#           - adding code to check for domain membership
#           - adding logic for FileVault encrypted drives
#   - v1.2  - use of createmobileaccount to get around FileVault
## 
#   - v1.3  - use of dscl to get around FileVault and cocoaDialog requirement
#               Added Casper Variables
#               Added multiple variables to allow use in systems other than Casper
#               Added AppleScript (osascript) version of Dialog, so script is not dependent on Casper
#               Thanks to Steve Wood (swood@integer.com) for the initial script

# NOTE: you may want to turn off logging (comment out 5 lines under #Globals & Loging) so that no passwords
# are captured.

###
# Logging   
###

LOGPATH='/Library/Logs'               # change this line to point to your local logging directory
if [[ ! -d "$LOGPATH" ]]; then
    mkdir $LOGPATH
fi
set -xv; exec 1> $LOGPATH/jssMoveDomains.log 2>&1  # you can name the log file what you want
version=1.2

###
# Let the user know what we are doing
###

## Change the dialog to what you want to tell your users
### I have commented out the dialog, because I am using SelfService for the Migration and have dialog appear there.

## Casper Version ## 
#
# banner=`/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType hud -title "Moving Domains" -heading "Moving Domains Header" -description "We are moving your user account to the new authentication domain.  When we are completed, your computer will restart and you can use your new account inforation." -icon <PATH-TO-YOUR-ICON> -button1 "Proceed" -button2 "Not Now" -defaultButton 1 -cancelButton 2 -timeout 60 -countdown` 
# 
# if [[ $banner == "2" ]]; then
# 
#     echo "User canceled the move."
#     exit 1
# 
# fi

## AppleScript version ##
#
# banner=$(osascript -e 'display dialog "We are moving your user account to the new authentication domain.  When we are completed, your computer will restart and you can use your new account inforation." buttons {"Cancel", "Migrate"} default button "Migrate" with title "Moving Domains" with icon 2')
# 
# if [[ $banner != "button returned:Migrate" ]]; then
# 
#     echo "User canceled the move."
#     exit 1
# 
# fi


###
# Casper Variables
###
# 1=mount point ## Defined by Casper ##
# 2=computer name ## Defined by Casper ##
# 3=username ## Defined by Casper ##

### IF USING CASPER MAKE SURE TO ENTER VARIABLES AS PARAMETERS 4-9 IN POLICY ###
## IF NOT USING CASPER UNCOMMENT THESE LINES AND ENTER REQUIRED INFO ##

# 4="oldAD"                       ## Enter current Domain ex 'ad.company.com'
# 5="newAD"                       ## Enter New Domain ex 'domain.company.com'
# 6="adminEmail"              ## Enter notification email address
# 7="oldADAdmin"              ## Enter Network account with permission to remove computer from old domain
# 8="oldADPass"                   ## Enter Password for Network account with permission to remove computer from old domain
# 9="JSS Bind Policy number"
# 10=
# 11=

###
# Global Variables
###

oldAD=$4
newAD=$5
adminEmail=$6
oldADAdmin=$7
oldADPass=$8

osVersion=`sw_vers -productVersion | cut -d. -f1,2`
currentAD=`dsconfigad -show | grep -i "active directory domain" | awk '{ print $5 }'`
computerName=`scutil --get ComputerName`

## Obtain current logged in user ##
loggedInUser=`ls -l /dev/console | /usr/bin/awk '{ print $3 }'`

# Obtain current logged in users UniqueID
loggedInUserID=`dscl . read /Users/$loggedInUser UniqueID | awk '{ print $2 }'`

## User's home folder location
userHome=`dscl . read /Users/$loggedInUser NFSHomeDirectory | awk '{ print $2 }'`

## Use these if binding to new AD via script instead of Casper Policy ##
# newADAdmin="username"                   ## Enter Network account with permission to join computer to new domain
# newADPass="password"                    ## Enter Password for Network account with permission to join computer to new domain
# newDomainOU="OU=Computers,DC=domain,DC=company,DC=com"  ## Enter container that you want computers joined to
# newDomainGroup="group"              ## Enter group that you want added to Admin bound Macs

### ### ### ### ###


###
# Unbind from AD
###

# check to see if we are bound to our current AD or not.  If not we can skip this

if [[ "$currentAD" = "$oldAD" ]]; then

    # remove the config for our old AD

    dsconfigad -remove "$oldAD" -force -user "$oldADAdmin" -password "$oldADPass"

fi

###
# Bind to new AD
###

## using a JAMF policy

jamf policy -id $9

## using "dsconfigad"

# dsconfigad -add $newAD -username "$newADAdmin" -password "$newADPass" -computer "$computerName" -ou "$newDomainOU" -force
# sleep 5
# 
# dsconfigad -groups "$newDomainGroup" -localhome enable -mobile enable -mobileconfirm disable -useuncpath disable
# sleep 5
# 
# dsconfigad -passinterval30
# sleep 5


### verify that the move was successful
checkAD=`dsconfigad -show | grep -i "active directory domain" | awk '{ print $5 }'`

if [[ "$checkAD" != "$newAD" ]]; then

    echo "SOMETHING WENT WRONG AND WE ARE NOT BOUND"

    #####  SEND AN EMAIL TO THE ADMIN  #####
    message1="$loggedInUser attempted to run the Domain Migration Policy on $computerName and it failed to bind to $newAD."
    echo -e "$message1" | mail -s "Domain Migration Policy Failure" $adminEmail
    exit 99

fi

###
# Reset Permissions
###

### Because we are not deleting the user account, FileVault enabled users will still be able to unlock the drive.
### However, if the users password is different from the old domain to the new domain, the user will need to use their old password at the FV screen.
### They will then be placed at the login screen and when entering the new password will be prompted to sync the keychain and FV password. 

## Get the Active Directory Node Name

adNodeName=`dscl /Search read /Groups/Domain Users | awk '/^AppleMetaNodeLocation:/,/^AppleMetaRecordName:/' | head -2 | tail -1 | cut -c 2-`

## Get the Domain Users groups Numeric ID

domainUsersPrimaryGroupID=`dscl /Search read /Groups/Domain Users | grep PrimaryGroupID | awk '{ print $2}'`

accountUniqueID=`dscl "$adNodeName" -read /Users/$loggedInUser 2>/dev/null | grep UniqueID | awk '{ print $2}'`

dscl . -change /Users/$loggedInUser UniqueID "$loggedInUserID" "$accountUniqueID"

chown -R $accountUniqueID:$domainUsersPrimaryGroupID /Users/$loggedInUser

#####  SEND AN EMAIL TO THE ADMIN  #####
message2="$loggedInUser successfully ran the Domain Migration Policy on $computerName and it is now joined to $newAD."
echo -e "$message2" | mail -s "Domain Migration Policy Success" $adminEmail

### Restart the computer

# shutdown -r now

caffine247
New Contributor III

So I am planning on using a script similar to this in JAMF, but I am struggling with one of the parameters, 9. "JSS Bind Policy number"

Please keep in mind, I was handed the Apple systems role after someone left. So I am catching up really quickly with Casper, but I can't seem to find the information I am looking for.

Can someone assist?

Thank you,

alexjdale
Valued Contributor III

Looks like a trigger policy that would bind the system to the new domain. The script would need the ID number of that policy (which you would need to create) to call it in this section:

## using a JAMF policy

jamf policy -id $9

I've been through this migration process and as a seasoned Casper admin it was very difficult, so I wish you the best of luck.

caffine247
New Contributor III

@alexjdale I have created the Jamf policy to bind to the new AD, how do I find the policy number is my confusion at this time.

Thank you,

mpermann
Valued Contributor II

@fneidhardt when you click on your policy in Casper, in the URL you will see the ID after the "policies.html?id=" part of the URL.

caffine247
New Contributor III

@alexjdale I have created the Jamf policy to bind to the new AD, how do I find the policy number is my confusion at this time.

Thank you,

M0J077
New Contributor II

Hey Everyone, We have been tasked to move all machines to a new domain, we have adapted the above script from @jason.bracy But it seems as though the machine does the migration as expected and changes permissions but it doesn't seem to ask for the user to change the password at first login. We migrate the user with the same PW, then ask the user to change it at first login. It seems like it is still using the mobile profile and PW not the new domain PW.

Anyone experience this or know how to get the mobile profile to see the new domain.

Otherwise the script works great! just need to get past this issue!

jason_bracy
Contributor III

It's been a while since I did this, let me take a look and see where the issue may be.

bjharper
New Contributor II

Been testing this script in combination with a policy that binds the machine to the new AD domain. All seems well except when logging in with my test user, I keep getting keychain errors along the lines of "no keychain found", "no AuthToken", etc. Also, Directory Utility for my same test user is still looking at the old AD domain under the AuthenticationAuthority attribute.

If I run:

dsconfigad -show | grep -I "active directory domain' | awk '{ print $5 }'

it returns the correct (new) AD domain as does:

dscl /Search read /Groups/Domain Users | awk '/^AppleMetaNodeLocation:/,/^AppleMetaRecordName:/' | head -2 | tail -1 | cut -c 2-

which returns the full Active Directory path.

It seems like the machine migration works great, its the user migration piece that I'm either missing something or not setting things up/prestaging correctly. Any help would be most appreciated; been trying to slog my way through this since Friday.

jason_bracy
Contributor III

@bjharper Apple changed how FileVault works in 10.13, so since this script was written back in 2014 I was using 10.9/10.10 at the time. I really haven't gotten my head around how to manage FileVault in the CLI with 10.13. Seems like Apple doesn't want us to do that anymore.

bjharper
New Contributor II

@jason.bracy Based on a few things I found on Der Flounder, looks like Apple made changes to FV on 10.13 and with APFS by adding a 'SecureToken' attribute that's required to be present for an account to be able to unlock a FV encrypted disk.

From Der Flounder: (https://derflounder.wordpress.com/2018/01/20/secure-token-and-filevault-on-apple-file-system/#more-9561)

"As part of Apple File System’s FileVault encryption on mac OS High Sierra, Apple introduced Secure Token. This is a new and undocumented account attribute, which is now required to be added to a user account before that account can be enabled for FileVault on an encrypted Apple File System (APFS) volume. To help make sure that at least one account has a Secure Token attribute associated with it, a Secure Token attribute is automatically added to the first account to log into the OS loginwindow on a particular Mac."

I'm reading more into this to see if this is something that needs to be added to your script. I'll update here if I make any headway with it.