Noobie needs a script to bind to AD

mikeyr
New Contributor

JAMF nation

I will be assigning our Mac devices to the various sites specified in our JSS.
We then have a script to name the machine. A dedicated script will be run for machines under each site. I then need to have these machines bind themselves to our AD domain.

I'd be most grateful with help achieving the following:

  • A script to bind machines to Active Directory. The script will be cloned and scoped respective to their site designation.
  • The script needs to enable me to set the following variables:f76d9f52bc3b4fea8b29236dee704a0d
    ed694e9aaa334734ba6c7a9c61cce33d

  • Create mobile account at login

  • Specify a preferred domain serve (via IP address)
  • Allow administration by- groupA, userB
  • Allow authentication from any domain in the forest
  • Use UNC path from Active Directory to derive network from home location
  • Network protocol to be used: smb
  • Default user shell: /bin/bash

Any help with this would be amazing!! Many thank yous in advanced.

6 REPLIES 6

teodle
Contributor

The JSS has a section under "Computer Management" where you can configure Directory Bindings with a very user-friendly GUI tool that will do everything you want it to do.

Then run your Directory Binding at imaging or as a post-enroll policy.

bpavlov
Honored Contributor

JSS -> Settings Gear -> Click on the Directory Binding button under Computer Management
Create a new directory binding and fill out the information accordingly.
To actually use the directory binding you've just created, you can do so in 3 ways:
1. Casper Imaging > Create new configuration and choose whether to use a directory binding
2. Computers > Policy > Create a new policy and choose a directory binding to apply
3. Computers > Configuration Profile > Create a new configuration profile and pick a directory binding.

I personally like option 2 the best because it gives you flexibility. Option 3 with the configuration profile I do not trust simply because if the configuration profile gets dropped then you lose the binding. Also, if you need to do troubleshooting you then need to worry about getting rid of the profile on the computer. It adds extra layers of complexity.

ruschg
New Contributor II

@mikeyr would you mind sharing your naming script your use for your different sites prior to binding?

teodle
Contributor

agree that Config Profiles aren't a good place for Directory Bindings. I use Bindings at imaging and also with a policy that has a custom trigger. Binding is something you do once and forget about, generally, because OU workstation groups don't have any bearing on Casper Groups for the most part.

In rare cases we move computers from one major division to another but then they can just get the new bindings through the custom trigger upon re-deploy.

snovak
Contributor
man dsconfigad

should be quite helpful.

for the administrators part, I usually do a

/usr/sbin/dseditgroup -o edit -n . -a "$1"@domain.com admin

If you don't want to write it yourself, here's what I got:

#!/bin/bash
#
# 020_joinDomain.sh- AD joining script - covers all OS revisions that use native binding
# Sam Novak - May 2016
#############
# Variables #
#############
TEST=DOMAINJOINER
TESTPASS=DOMAINJOINERPW

export PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin

# Get the machine name
HOSTNAME=`/usr/sbin/scutil --get ComputerName`

# Uppercase it
HOSTNAME=$(/bin/echo $HOSTNAME | /usr/bin/tr '[:lower:]' '[:upper:]')

# Make sure the hostname is set
/usr/sbin/scutil --set HostName $HOSTNAME.domain.com
/usr/sbin/scutil --set LocalHostName $HOSTNAME
/usr/sbin/scutil --set ComputerName $HOSTNAME

# Get the machine model
AD_MODEL=$(/usr/sbin/system_profiler SPHardwareDataType | /usr/bin/grep "Model Name")
AD_MODEL=${AD_MODEL:18}
MODEL_TEST=`/bin/echo $AD_MODEL | /usr/bin/grep -E ^Mac[Bb]ook*`

# variables for a variety of AD commands
BASIC="-add domain.com -username $TEST -computer $HOSTNAME -force -password $TESTPASS"
ADVANCED="-mobileconfirm disable -protocol smb  -useuncpath disable -sharepoint disable"
MAP="-uid employeeID -nogid -noggid -authority enable -alldomains disable"
ADMIN="-nogroups -packetsign allow -packetencrypt allow"
REMOVE="-remove -username remover -password removeee -force"

# Disable mobile account creation by default
MOBILE="-mobile disable -passinterval 1"


#############
# Functions #
#############


DOMAINLog() {
    /usr/bin/syslog -s -k Facility local7 Level info Message "$1"
}

# Removes the local domain binding
ADunbind()
{
    /usr/sbin/dsconfigad ${REMOVE} 2> /dev/null
    DOMAINLog "$HOSTNAME unbound from the domain"
}

# Binds back to AD
ADbind()
{
    /usr/sbin/dsconfigad ${BASIC} ${MOBILE} ${ADVANCED} ${MAP} ${ADMIN} -ou OU=Macintosh Deployment,OU=Computers,DC=domain,DC=com
    /usr/sbin/dsconfigad -preferred ldap.domain.com 2> /dev/null
    DOMAINLog "$HOSTNAME bound to the domain"
}

####################
# Actual scripting #
####################

if [ "$MODEL_TEST" != "" ]; then
        MOBILE="-mobile enable"
fi

ADunbind
ADbind

##################################
# 090_Util_updateADAttributes.sh #
#######################################################
# The following sections update attributes on the    #
# AD object for this workstation and makes sure they  #
# are accurate for the current system                #
#######################################################
# serial number
SERIAL=$(/usr/sbin/system_profiler SPHardwareDataType Hardware | /usr/bin/grep Serial)
SERIAL=${SERIAL:30:12}

# Model
MODEL=$(/usr/sbin/system_profiler SPHardwareDataType Hardware | /usr/bin/grep Identifier)
MODEL=${MODEL:24}

# Processor Model
PROC_MOD=$(/usr/sbin/system_profiler SPHardwareDataType Hardware | /usr/bin/grep "Processor Name")
PROC_MOD=${PROC_MOD:22}

# Processor Speed
PROC_SPE=$(/usr/sbin/system_profiler SPHardwareDataType Hardware | /usr/bin/grep "Processor Speed")
PROC_SPE=${PROC_SPE:23}

# Processor Core Count
PROC_COR=$(/usr/sbin/system_profiler SPHardwareDataType Hardware | /usr/bin/grep "Number of Cores")
PROC_COR=${PROC_COR:29}

# RAM
RAM=$(/usr/sbin/system_profiler SPHardwareDataType Hardware | /usr/bin/grep "Memory")
RAM=${RAM:14}

# GPU
GPU=$(/usr/sbin/system_profiler SPDisplaysDataType | /usr/bin/grep -i chip | /usr/bin/sed -e 's/Chipset Model: //' | /usr/bin/tr -d '
' | /usr/bin/tr -s ' ')
GPU=${GPU:1}

DESCRIPTION="Model: $MODEL Serial: $SERIAL - Processor: $PROC_MOD $PROC_SPE - GPU: $GPU - RAM: $RAM"

COMMENT="$MODEL $SERIAL"

# OS Version
VERSION=$(/usr/bin/sw_vers | /usr/bin/grep ProductVersion)
VERSION=${VERSION:16}

ADRead() {
    # Sending error output to null, since it's a non-critical feature
    /usr/bin/dscl -u $TEST -P $TESTPASS /Active Directory/DOMAIN/All Domains -read Computers/$HOSTNAME$ $1 2>/dev/null
    if [ $? = 1 ]; then
        /usr/bin/dscl -u $TEST -P $TESTPASS /Active Directory/DOMAIN/DOMAIN.com -read Computers/$HOSTNAME$ $1 2>/dev/null
    fi
}

ADAppend() {
    # Sending error output to null, since it's a non-critical feature
    /usr/bin/dscl -u $TEST -P $TESTPASS /Active Directory/DOMAIN/All Domains -append Computers/$HOSTNAME$ $1 "$2" 2>/dev/null
    if [ $? = 1 ]; then
        /usr/bin/dscl -u $TEST -P $TESTPASS /Active Directory/DOMAIN/DOMAIN.com -append Computers/$HOSTNAME$ $1 "$2" 2>/dev/null
    fi
}

ADUpdate() {
    # Sending error output to null, since it's a non-critical feature
    /usr/bin/dscl -u $TEST -P $TESTPASS /Active Directory/DOMAIN/All Domains -change Computers/$HOSTNAME$ $1 "$2" "$3" 2>/dev/null
    if [ $? = 1 ]; then
        /usr/bin/dscl -u $TEST -P $TESTPASS /Active Directory/DOMAIN/DOMAIN.com -change Computers/$HOSTNAME$ $1 "$2" "$3" 2>/dev/null
    fi
}

# Let's sleep a little here, so AD can get up to date
/bin/sleep 10

# Read old OS
OLD_OS=$(ADRead dsAttrTypeNative:operatingSystemVersion)
OLD_OS=${OLD_OS:41}
OLD_OS=${OLD_OS## } # Strip spaces from the front of the text
OLD_OS=${OLD_OS%% } # Strip spaces from the back of the text

if [ "$OLD_OS" == "" ]; then
    # ADAppend the new attribute
    /bin/echo "Adding OS version for the first time"
    ADAppend dsAttrTypeNative:operatingSystemVersion "$VERSION"
elif [ "$OLD_OS" != "$VERSION" ]; then
    # Update OS
    /bin/echo "Updating the OS version"
    ADUpdate dsAttrTypeNative:operatingSystemVersion "$OLD_OS" "$VERSION"
fi

# Read old serial
OLD_SERIAL=$(ADRead dsAttrTypeNative:serialNumber)
OLD_SERIAL=${OLD_SERIAL:31:12}
OLD_SERIAL=${OLD_SERIAL## } # Strip spaces from the front of the text
OLD_SERIAL=${OLD_SERIAL%% } # Strip spaces from the back of the text

if [ "$OLD_SERIAL" == "" ]; then
    # ADAppend the new attribute
    /bin/echo "Adding serial number for the first time"
    ADAppend dsAttrTypeNative:serialNumber "$SERIAL"
elif [ "$OLD_SERIAL" != "$SERIAL" ]; then
    # Update Serial
    /bin/echo "Updating the serial number"
    ADUpdate dsAttrTypeNative:serialNumber "$OLD_SERIAL" "$SERIAL"
fi

# Read old description
OLD_DES=$(ADRead dsAttrTypeNative:adminDescription)
OLD_DES=${OLD_DES:35} # Strip the front of the text
OLD_DES=${OLD_DES## } # Strip spaces from the front of the text
OLD_DES=${OLD_DES%% } # Strip spaces from the back of the text

if [ "$OLD_DES" == "" ]; then
    # ADAppend the new attribute
    /bin/echo "Adding the system description for the first time"
    ADAppend dsAttrTypeNative:adminDescription "$DESCRIPTION"
elif [ "$OLD_DES" != "$DESCRIPTION" ]; then
    # Update Admin description
    # Ex: USED BY SAM NOVAK Model: iMac14,2 Serial: D25MT11XF8J9 - Processor: Intel Core i5 3.2 GHz - GPU: NVIDIA GeForce GT 755M - RAM: 6 GB LOLOLOL
    # Prefix /usr/bin/grep: USED BY SAM NOVAK Model:
    # Prefix /usr/bin/sed : USED BY SAM NOVAK
    # Suffix /usr/bin/grep #1: RAM: 6 GB LOLOLOL
    # Suffix /usr/bin/grep #2: GB LOLOLOL
    # Suffix sed: LOLOLOL
    PREFIX=$(/bin/echo "$OLD_DES" | /usr/bin/grep -o '.{0,40}Model:' | /usr/bin/sed -e "s/ *Model:$//")
    SUFFIX=$(/bin/echo "$OLD_DES" | /usr/bin/grep -o 'RAM: [0-9][0-9]? GB.{0,20}' | /usr/bin/sed -e 's/RAM: [0-9]{0,2} GB *//')
    OUTPUT="$PREFIX $DESCRIPTION $SUFFIX"
    OUTPUT=${OUTPUT## }
    OUTPUT=${OUTPUT%% }
    if [ "$OLD_DES" != "$OUTPUT" ]; then
        /bin/echo "Updating the system description, with prefix and suffix."
        /bin/echo "PREFIX: $PREFIX"
        /bin/echo "SUFFIX: $SUFFIX"
        ADUpdate dsAttrTypeNative:adminDescription "$OLD_DES" "$OUTPUT"
    fi
fi

# Read old comment
OLD_COM=$(ADRead dsAttrTypeNative:comment)
OLD_COM=${OLD_COM:26}
OLD_COM=${OLD_COM## } # Strip spaces from the front of the text
OLD_COM=${OLD_COM%% } # Strip spaces from the back of the text

if [ "$OLD_COM" == "" ]; then
    # ADAppend the new attribute
    /bin/echo "Adding the system comment for the first time."
    ADAppend dsAttrTypeNative:comment "$COMMENT"
elif [ "$OLD_COM" != "$COMMENT" ]; then
    # Update Comment
    # Ex: ASDASDASD iMac14,2 D25MT11XF8J9 ASDASDASD
    # Prefix /usr/bin/grep: ASDASDASD iMac14,2
    # Prefix /usr/bin/sed : ASDASDASD
    # Suffix /usr/bin/grep: iMac14,2 D25MT11XF8J9 ASDASDAS
    # Suffix /usr/bin/sed: ASDASDAS
    PREFIX=$(/bin/echo "$OLD_COM" | /usr/bin/grep -o '.{0,40}i?[Mm]ac[[:alpha:]]{0,10}[0-9]+,[0-9]+' | /usr/bin/sed -e 's/ i{0,1}[Mm]ac[a-zA-Z]*[0-9]{1,2},[0-9]$//')
    SUFFIX=$(/bin/echo "$OLD_COM" | /usr/bin/grep -o 'i?[Mm]ac[[:alpha:]]{0,10}[0-9]+,[0-9]+.{0,40}'  | /usr/bin/sed -e 's/i{0,1}[Mm]ac[a-zA-Z]*[0-9]{1,2},[0-9] [a-zA-Z0-9]{0,12} //')
    OUTPUT="$PREFIX $COMMENT $SUFFIX"
    OUTPUT=${OUTPUT## }
    OUTPUT=${OUTPUT%% }
    if [ "$OLD_COM" != "$OUTPUT" ]; then
        /bin/echo "Updating the system comment with prefix and suffix."
        /bin/echo "PREFIX: $PREFIX"
        /bin/echo "SUFFIX: $SUFFIX"
        ADUpdate dsAttrTypeNative:comment "$OLD_COM" "$OUTPUT"
    fi
fi

# Read old comment (The actual comment field in ADUC)
OLD_COM2=$(ADRead Comment)
OLD_COM2=${OLD_COM2:9}
OLD_COM2=${OLD_COM2## } # Strip spaces from the front of the text
OLD_COM2=${OLD_COM2%% } # Strip spaces from the back of the text

if [ "$OLD_COM2" == "" ]; then
    # ADAppend the new attribute
    /bin/echo "Adding the secondary system comment for the first time."
    ADAppend Comment "$DESCRIPTION"
elif [ "$OLD_COM2" != "$DESCRIPTION" ]; then
    # Update Comment
    # Ex: USED BY SAM NOVAK Model: iMac14,2 Serial: D25MT11XF8J9 - Processor: Intel Core i5 3.2 GHz - GPU: NVIDIA GeForce GT 755M - RAM: 6 GB LOLOLOL
    # Prefix /usr/bin/grep: USED BY SAM NOVAK Model:
    # Prefix /usr/bin/sed : USED BY SAM NOVAK
    # Suffix /usr/bin/grep #1: RAM: 6 GB LOLOLOL
    # Suffix /usr/bin/sed: LOLOLOL
    PREFIX=$(/bin/echo "$OLD_COM2" | /usr/bin/grep -o '.{0,40}Model:' | /usr/bin/sed -e "s/ *Model:$//")
    SUFFIX=$(/bin/echo "$OLD_COM2" | /usr/bin/grep -o 'RAM: [0-9][0-9]? GB.{0,20}' | /usr/bin/sed -e 's/RAM: [0-9]{0,2} GB *//')
    OUTPUT="$PREFIX $DESCRIPTION $SUFFIX"
    OUTPUT=${OUTPUT## }
    OUTPUT=${OUTPUT%% }
    if [ "$OLD_COM2" != "$OUTPUT" ]; then
        /bin/echo "Updating the secondary comment, with prefix and suffix."
        /bin/echo "PREFIX: $PREFIX"
        /bin/echo "SUFFIX: $SUFFIX"
        ADUpdate Comment "$OLD_COM2" "$OUTPUT"
    fi
fi

exit 0

mikeyr
New Contributor

@teodle Apologies for the late reply. Here is an copy of the naming script we are using. We just clone it and change the yourCompanyPrefix to be relevant to site we are scoping the script to. Curtesy of @gavin.pardoe for putting it together for us.

!/bin/bash

Machine Naming Script Oct 2016 - BIRMINGHAM ONLY

Will Set Machine Name Based on Location, Device Model & Last 6 Digits of Serial Number

Get Device Model

deviceType=$(system_profiler SPHardwareDataType | awk -F'"' '/Model Name/{print $0}' | awk '{ print $3 }')

if [[ $deviceType == MacBook ]]; then echo device=NX-
else echo device=DX-
fi

Get Last 6 Digits of Serial Number

serialNum=$(ioreg -c IOPlatformExpertDevice -d 2 | awk -F" '/IOPlatformSerialNumber/{print $(NF-1)}' | rev | cut -c 1-6 | rev)

Set Machine Name

/usr/sbin/scutil --set ComputerName yourCompanyPrefix$device$serialNum
/usr/sbin/scutil --set LocalHostName yourCompanyPrefix$device$serialNum

exit 0