There were a couple of people who helped me with this. Not sure whether to publicly call them out - who gave advice on how to deploy it. I was scared. Who also helped with figuring out which attributes needed modification.
Does this also work with OpenLDAP?
You could possibly use the same approach - though I suspect some of the attributes to change will be different.
Compare dscl output against user accounts.
@lisacherie THANK YOU! This is a huge life saver for me. Deployed it to a our test group of Enterprise Connect users (all logged in and using their systems) and had zero issues. Will continue using it as we migrate more folks to Enterprise Connect.
@perrinbw are you deploying the script via jamf? if so, how do you get the terminal to pop up so i can choose the options?
Thanks
@ant89 There are two versions of the script.
The version I shared does not require interaction, or Rich's version does. Try out each and see which method you prefer. The silent version suited the workflow I had as the process was invisible and non disruptive to end users.
Please test it out before trying - each AD is a bit different and there are macOS dot releases since then.
@lisacherie thank you! the script you provided works in our environment. QQ - Anyway to determine which laptops have mobile accounts? I've created an EA that looks for accounts that have a UID over 1000. but your script does not change the UID. If this script was ran, i have no way of determining if it is still a mobile account or not. Any ideas?
@lisacherie awsome. thank you!
Just started testing this myself - first test was perfect, so that's very encouraging. Thank you @lisacherie !
So, this is probably going to sound dumb, but has anyone used this with High Sierra? With Apple Script editor it is not running and having issues. Most of this is over my head, but I would love to test this out! Any pointers would be great!
It did work with early builds of High Sierra - but you will need to test to ensure there are no differences with your environment and it still works with the current builds.
To run the script you need to use terminal and the following command:
sudo ./scriptname.sh
Good luck - hope it works out for you.
@lisacherie has anyone gotten this or @rtrouton 's version of the script to work using JAMF Helper's Prompt Message feature? It would be nice to deploy this to machines that need AD accounts converted to local that are provisioned with DEP. Thus preventing future keychain and FV2 password sync problems.
The version I wrote was designed to run silently and convert all accounts in one policy run, regardless of whether the user is active at the time. This is a sanitized version some specific lines to that environment were removed, however this version also worked.
I used it successfully with my previous employer, however each AD is different, and there are many OS updates since then, so please test before deployment.
Thank you @lisacherie I am rebuilding a machine to test the script on now.
@lisacherie I was able to use the script to unbind a mac and convert the account from a mobile account to a local account, however I've noticed that I cannot change the password on the local account now. Have you seen this behaviour before?
@rtrouton has updated the version of this he wrote. Please take care to obtain the new version: https://derflounder.wordpress.com/2018/06/16/updated-migrateadmobileaccounttolocalaccount-script-now-available-to-fix-migration-bug
Note the perl version is using a string within a string for the “system” function to execute the dscl command rather than as a command in bash.
At first look the perl version may not be impacted due to the way strings are handled/quoted.
More testing is needed to confirm.
I also had success with this code. It prompts for a desired user to convert via calling a system event. Then if it's not an AD account, it exits. If so, it follows the steps that @lisacherie outlines above. No unbinding from AD in this script. I decided to call that separately so that I can unbind with AD credentials and do these separately as needed. Here's that script:
#!/bin/bash
#Freddie Cox for Knox County Schools
#Edited by Justin Ellis
#Arranged by Ethan Delavan for Jamf environment
#2012
#
#Ask user for the target user to convert
netname=`/usr/bin/osascript <<EOT
tell application "System Events"
activate
set netname to text returned of (display dialog "Please Input Target User Name" default answer "first.last" with icon 1)
end tell
EOT`
#Test to see if the target account is currently logged in.
if [[ "$netname" = `python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");'` ]]; then
#Exit if target user is currently logged in
/usr/bin/osascript <<EOT
tell application "System Events"
activate
display dialog "$netname is logged in, and we shouldn't mess with it now. Log in as admin and try again." with icon 2 buttons {"Cancel"} default button 1 with hidden answer
end tell
EOT
exit 1
fi
accounttype=`/usr/bin/dscl . -read /Users/"$netname" AuthenticationAuthority | head -2 | awk -F'/' '{print $2}' | tr -d '
'`
if [[ "$accounttype" = "Active Directory" ]]; then
mobileusercheck=`/usr/bin/dscl . -read /Users/"$netname" AuthenticationAuthority | head -2 | awk -F'/' '{print $1}' | tr -d '
' | sed 's/^[^:]*: //' | sed s/;/""/g`
if [[ "$mobileusercheck" = "LocalCachedUser" ]]; then
#/usr/bin/printf "$netname has an AD mobile account.
Converting to a local account with the same username and UID.
"
/usr/bin/osascript <<EOT
tell application "System Events"
activate
display dialog "$netname is a Local Cached User via AD. Click to begin conversion" with icon 1 buttons {"Continue"} default button 1 with hidden answer
end tell
EOT
else
#/usr/bin/printf "The $netname account is not a AD mobile account
"
/usr/bin/osascript <<EOT
tell application "System Events"
activate
display dialog "The $netname account is not a Local Cashed User." with icon 2 buttons {"Cancel"} default button 1 with hidden answer
end tell
EOT
exit 1
fi
else
#/usr/bin/printf "The $netname account is not a AD mobile account
"
/usr/bin/osascript <<EOT
tell application "System Events"
activate
display dialog "The $netname account is not an Active Directory account." with icon 2 buttons {"Cancel"} default button 1 with hidden answer
end tell
EOT
exit 1
fi
#Now do the deeds
# Preserve the account password by backing up password hash
shadowhash=$(/usr/bin/dscl -plist . -read /Users/$netname AuthenticationAuthority | xmllint --xpath 'string(//string[contains(text(),"ShadowHash")])' -)
# Remove the account attributes that identify it as an Active Directory mobile account
/usr/bin/dscl . -delete /users/$netname cached_groups
/usr/bin/dscl . -delete /users/$netname cached_auth_policy
/usr/bin/dscl . -delete /users/$netname CopyTimestamp
/usr/bin/dscl . -delete /users/$netname AltSecurityIdentities
/usr/bin/dscl . -delete /users/$netname SMBPrimaryGroupSID
/usr/bin/dscl . -delete /users/$netname OriginalAuthenticationAuthority
/usr/bin/dscl . -delete /users/$netname OriginalNodeName
/usr/bin/dscl . -delete /users/$netname AuthenticationAuthority
/usr/bin/dscl . -create /users/$netname AuthenticationAuthority "${shadowhash}"
/usr/bin/dscl . -delete /users/$netname SMBSID
/usr/bin/dscl . -delete /users/$netname SMBScriptPath
/usr/bin/dscl . -delete /users/$netname SMBPasswordLastSet
/usr/bin/dscl . -delete /users/$netname SMBGroupRID
/usr/bin/dscl . -delete /users/$netname PrimaryNTDomain
/usr/bin/dscl . -delete /users/$netname AppleMetaRecordName
/usr/bin/dscl . -delete /users/$netname PrimaryNTDomain
/usr/bin/dscl . -delete /users/$netname MCXSettings
/usr/bin/dscl . -delete /users/$netname MCXFlags
# Refresh Directory Services
if [[ ${osvers} -ge 7 ]]; then
/usr/bin/killall opendirectoryd
else
/usr/bin/killall DirectoryService
fi
#Pause
sleep 20
#Test for success
accounttype=`/usr/bin/dscl . -read /Users/"$netname" AuthenticationAuthority | head -2 | awk -F'/' '{print $2}' | tr -d '
'`
if [[ "$accounttype" = "Active Directory" ]]; then
/usr/bin/printf "Something went wrong with the conversion process.
The $netname account is still an AD mobile account.
"
/usr/bin/osascript <<EOT
tell application "System Events"
activate
display dialog "Something went wrong with the conversion process. The $netname account is still an AD mobile account." with icon 2 buttons {"Cancel"} default button 1 with hidden answer
end tell
EOT
exit 1
else
/usr/bin/printf "Conversion process was successful.
The $netname account is now a local account.
"
fi
#Update home folder permissions
homedir=`/usr/bin/dscl . -read /Users/"$netname" NFSHomeDirectory | awk '{print $2}'`
if [[ "$homedir" != "" ]]; then
/bin/echo "Home directory location: $homedir"
/bin/echo "Updating home folder permissions for the $netname account"
/usr/sbin/chown -R "$netname" "$homedir"
fi
# Add user to the staff group on the Mac
/bin/echo "Adding $netname to the staff group on this Mac."
/usr/sbin/dseditgroup -o edit -a "$netname" -t user staff
#Echo user info
/bin/echo "Displaying user and group information for the $netname account"
/usr/bin/id $netname
exit 0
Thanks for sharing your script too.
The script in the OP still works last tried 10.13.6 if looking for a silent way to convert all accounts via policy on the Mac in one go.
If wanting to keep the AD bind - can comment out the few rows which remove it.
@ethan.delavan Does your script with work with Macs that are on Mojave?
For Mojave you can also use nomad login if script above is not working
This doesn't work for mobile Open Ldap accounts. I get "The user is not an AD user" error. Any chance this could work with not just AD?