Posted on 03-12-2020 12:12 PM
Is there a way to add an Active Directory user account using a Terminal command? Our normal workflow when on site is to:
- log in as admin
- bind the Mac to AD
- log out of the admin account
- have the user sign into their AD account at the macOS login screen, thus creating their user account and user profile.
If we have a computer outside of our local network and need to add a network user account to a Mac, we have no way to do it. If we connect to the VPN logged into the admin account, we can hit our AD servers. But as soon as we log out of the admin account, or if we try to switch users or go to "login window..." the VPN connection drops and then we cannot add the network user account to the Mac.
So my question is, is there a way to add an AD user account from Terminal? Is there a way we could log in as admin, connect to VPN, bind to AD and then add the user somehow without logging out of the admin account.
We are looking at getting away from AD binding with Jamf connect, but we are not there yet and are trying to find a solution in the meantime.
Solved! Go to Solution.
Posted on 03-13-2020 06:08 AM
I figured it out. While logged into the admin account, connect to VPN. Open Terminal and run the following commmand:
sudo /System/Library/CoreServices/ManagedClient.app/Contents/Resources/createmobileaccount -n [AD_username]
This creates the mobile user account. Now we need to cache the user's password. Back in Terminal:
login
When prompted, enter the AD username and password.
Posted on 03-13-2020 06:08 AM
I figured it out. While logged into the admin account, connect to VPN. Open Terminal and run the following commmand:
sudo /System/Library/CoreServices/ManagedClient.app/Contents/Resources/createmobileaccount -n [AD_username]
This creates the mobile user account. Now we need to cache the user's password. Back in Terminal:
login
When prompted, enter the AD username and password.
Posted on 12-01-2022 11:09 AM
Thanks @JefferyAnderson
Used this to resolve an issue we were having. Tested on macOS 12.3. Adding here for others to reference if needs be.
We are domain joined in our student labs. The issue we were/are having is that students sometimes login to a workstation before our technicians login to the workstation. The first account to login gets the SecureToken and therefore can't be deleted from the system when no other account has a SecureToken and/or the bootstrap hasn't been escrowed. This gives an active directory service account a SecureToken and resolved our problem. We have a script that runs at login that deletes previous active directory accounts (students) which is where the problem started, unable to delete student accounts when they had a SecureToken. Note, these lab machines are not encrypted.
Script to create mobile account and "login" while the workstation is till at a login prompt.
#!/bin/zsh
username=$4
password=$5
# Create mobile account
result=$(expect -c "
spawn /System/Library/CoreServices/ManagedClient.app/Contents/Resources/createmobileaccount -n $username
expect \"SecureToken\"
send -- \"\r\"
expect eof
")
echo $result
# Login to mobile account to grant it a secureToken (First user to login)
result=$(expect -c "
spawn /usr/bin/login
expect \"login:\"
send -- \"$username\"
send -- \"\r\"
expect \"password:\"
send -- \"$password\"
send -- \"\r\"
expect eof
")
echo $result
# Jamf inventory (more for testing)
/usr/local/bin/jamf recon
Script for account deletes at login and information gathering about SecureToken. Some logic in here was borrowed from Jamf Nation, thanks!
#!/bin/zsh
#set -x
clear
# Get the current logged in user
currentLoggedInUser=$(ls -l /dev/console | cut -d " " -f 4)
# List of users that we want to exclude from deletion
usersToKeep=( $currentLoggedInUser $4 )
function secureTokengodmode {
secureToken=$(/usr/bin/dscl . read /Users/godmode | grep "SecureToken")
if [[ "$secureToken" == *"SecureToken"* ]]; then
echo "User: godmode SecureToken status: Enabled"
else
echo "User: godmode SecureToken status: Disabled"
fi
}
function removeAccount {
removeAccountHome=$(dscl . read /Users/$1 | grep "NFSHomeDirectory" | awk '{print $2}')
echo "Removing home folder for $1."
log "Removing home folder for $1."
rm -rf "$removeAccountHome"
sleep 3
if [[ -d "$removeAccountHome" ]]; then
echo "$removeAccountHome failed to delete, skipping."
log "$removeAccountHome failed to delete, skipping."
else
echo "Removing user account for $1."
log "Removing user account for $1."
dscl . -delete "/Users/$1"
sleep 3
fi
}
function log {
timeStamp=$(date)
echo "$timeStamp - $1" >> "/Library/Logs/deleted user accounts.log"
}
# cleanup!
function cleanup {
if [[ -f "$outFile"1 ]]; then
rm "$outFile"1
fi
}
# Logic
secureTokengodmode
# Get a list of all the users with a UniqueID of greater than 1000 and save to a file
outFile=/var/tmp/output
/usr/bin/dscl . list /Users UniqueID | grep -v "^_" | awk '{if($2>1000)print $1}' > "$outFile"1
echo "List of Users to keep: $usersToKeep"
for usersToDelete in $usersToKeep ; do
# Use grep to search for an exact match and if found, remove it from the file
grep -v -Fx "$usersToDelete" "$outFile"1 > "$outFile"2 & mv "$outFile"2 "$outFile"1
done
# Check if the file is empty or not
if [[ -s "$outFile"1 ]]; then
# Read the output file to an array for processing
eval "array=($(<"$outFile"1))"
# Remove the user account and home directory
for removeUser in $array ; do
removeAccount $removeUser
done
cleanup
else
echo "No users to delete at this time."
cleanup
fi
# List remaining users on the workstation
remainingUsers=$(/usr/bin/dscl . list /Users UniqueID | grep -v "^_")
echo "Remaining users:"
echo "$remainingUsers"
log "Remaining users: $remainingUsers"
echo " "
### Secure Token users ###
declare -a secureTokens
declare -a delete
secureTokens=($(fdesetup list -extended | awk '{print $4}'))
#echo ${secureTokens[@]}
delete+=(USER)
delete+=(Record)
#echo ${delete[@]}
for i in ${delete[@]}; do
secureTokens=( "${secureTokens[@]/$i}" )
done
#echo ${secureTokens[@]}
function join { local IFS="$1"; shift; echo "$*"; }
result=$(join , ${secureTokens[@]})
echo "Remaining Secure Token Users: $result"
log "Remaining Secure Token Users: $result"
echo " "
bootstrap=$(profiles status -type bootstraptoken)
if [[ $bootstrap == *"escrowed to server: YES"* ]]; then
echo "Bootstrap Status: Escrowed"
log "Bootstrap Status: Escrowed"
else
echo "Bootstrap Status: Not Escrowed"
log "Bootstrap Status: Not Escrowed"
fi
exit
Perhaps this can be of use to others.
Posted on 03-13-2020 07:08 AM
I ran into a similar problem. I ended up using the command dscacheutil -q user -a name USERNAME
to cache the user's password. I'll have to try the Login option next time I need to do this.
Posted on 04-30-2020 02:16 PM
@Jeffery_Anderson Thanks for the info on this. Have you seen an issue where the user who was created by this command can't log into their account after restart? I'm having that issue now and have tried multiple steps to resolve. I've followed your steps to a T and it hasn't prevented that issue so far. I can create the account fine, but the user can't login after restart. I have to login via local admin first, log out, then log into the user and it works. But not after restart or shutdown. Any thoughts?
Posted on 05-01-2020 09:05 AM
@smitty1923 Do you have Filevault Enabled? because that could cause some of those issues.
I ended up setting up this as a Self Service policy to add a remote user.
https://github.com/theadamcraig/jamf-scripts/blob/master/remote_AD_user_creation.sh
Posted on 08-27-2020 07:42 AM
@Jeffery_Anderson This didn't work for me in 10.14.6. I receive the following error message when using my user name in the admin account;
* user name "[username]" was not found: 0 ((null))
Posted on 03-15-2021 11:29 AM
Have the same issue as Jeffrey. Curious if anyone has preferences on this workaround? I've not tried the Terminal command that @Jeffery_Anderson has cited. Machine is AD bound and we have a ethernet connection that is supposedly hardwired to the network but no dice on logging in the AD user..or any AD user. Stuck with AD for the time being so have to find a workaround vs adding as a "local" user independent of AD credentials.
Posted on 03-15-2021 01:25 PM
@Switchfly_IT It's linked above. but this script is set up as a self service policy and scoped to computers that are being provisioned. Our IT team uses this both on prem and remotely to create mobile AD user accounts. We are transitioning to local accounts with jamf connect, but this has worked great for us in the mean time.
There is a bit in there that adds the account to filevault. remove that if you aren't using FV
https://github.com/theadamcraig/jamf-scripts/blob/master/remote_AD_user_creation.sh
Posted on 05-20-2022 10:33 AM
Hi AdamCraig, do you know if the script is updated? i keep getting an endless spinning in self-service?
thank you
Posted on 05-20-2022 10:45 AM
I haven't used that in production in awhile. But I'm not aware of any OS changes that would break it off the top of my head. I'd try running it locally and see if it works there.
The way I wrote the display dialog prompt may wait on a "Jamf would like to access system events" prompt. but other than that I'm not sure what could be happening.
Posted on 05-20-2022 10:47 AM
I updated the Display Dialog function in case that was causing the infinite spinning
Posted on 05-20-2022 11:44 AM
thank you for getting back to me.
is there any modification needed within the script?
getting this error message:
AD User failed to add. \nVerify GlobalProtect is Connected. \nRecommend restarting the computer and trying this install again. \nIf issues continue run 'Rebind to Domain' from Self Service and then try install again.
Posted on 05-25-2022 11:39 AM
So that means the script couldn't add the user, and most likely the computer could not contact the domain controller. If you're remote and using VPN you'll want to make sure VPN is connected before trying this.