Bind to OD Script & Add to Computer Group

by on April 6, 2010 » Add more comments.

The following script is what I use to bind machines to Open Directory and it solves the following challenges:

  1. If bound to another OD domain, it removes that binding. If you’re not moving from another domain, you can ignore that part, it won’t hurt that it’s in there.
  2. Adds the computer record to OD. Normally with anonymous binds you have to manually add the computer account. This takes care of that by authenticating as a diradmin. Because of this, keep this script in a safe place.
  3. Fixes the search order if the machine is also bound to AD in a golden triangle (or magic triangle) so that Tiger machines use AD first and Leopard/Snow Leopard machines look to OD first.
  4. Bind machine(s) remotely with tools such as Apple Remote Desktop (ARD), Absolute Manage (LANrev) or LANDesk.

Please be aware this script might not work in all environments. Try to understand how the script works and be prepared to modify for your environment. One issue I frequently find with any type of binding script (OD or AD) is the timing never seems to be perfect. By that I mean that the script runs faster than the directoryservice process can recognize the changes. I try to account for this by putting in “sleep xx” commands in certain places but you may need to play around with this a bit.

What I try to do is follow up the script with a simple “defaults read /Library/Preferences/DirectoryService/SearchNodeConfig “Search Node Custom Path Array” to ensure both OD and AD are in there. If they’re not, I just run the bind script again and it usually gets it the 2nd time.

To download the script, click here.

Or copy/paste:

#!/bin/sh
 
# Patrick Gallagher
# http://www.macadmincorner.com
# Updated 12/11/2009
 
# These variables need to be configured for your env
odAdmin="" #enter your OD admin name between the quotes
odPassword=""  # Enter your OD admin password between the quotes
domain="od.school.edu" # FQDN of your OD domain
oldDomain="oldod.school.edu" # If moving from another OD, enter that FQDN here
oldODip="111.222.333.444" # Enter the IP of your old OD
ADdomain="ad.school.edu" # Enter your AD domain here
computerGroup=computers  # Add appropriate computer group you want machines to be added to, case sensitive 
 
# These variables probably don't need to be changed
computerName=`/usr/sbin/scutil --get LocalHostName`
nicAddress=`ifconfig en0 | grep ether | awk '{print $2}'`
check4OD=`dscl localhost -list /LDAPv3`
check4ODacct=`dscl /LDAPv3/${domain} -read Computers/${computerName} RealName | cut -c 11-`
check4AD=`dscl localhost -list /Active\ Directory`
osversionlong=`sw_vers -productVersion`
osvers=${osversionlong:3:1}
 
# Check if on OD already
if [ "${check4OD}" == "${domain}" ]; then
	echo "This machine is joined to ${domain} already."
	odSearchPath=`defaults read /Library/Preferences/DirectoryService/SearchNodeConfig "Search Node Custom Path Array" | grep $domain`
	if [ "${odSearchPath}" = "" ]; then
		echo "$domain not found in search path. Adding..."
		dscl /Search -append / CSPSearchPath /LDAPv3/$domain
		sleep 10
	fi
else if [ "${check4OD}" == "${oldDomain}" ]; then
	echo "Removing from ${oldDomain}"
	dsconfigldap -r "${oldDomain}"
	dscl /Search -delete / CSPSearchPath /LDAPv3/"${oldDomain}"
	dscl /Search/Contacts -delete / CSPSearchPath /LDAPv3/"${oldDomain}"
	echo "Binding to $domain"
	dsconfigldap -v -a $domain -n $domain
	dscl /Search -create / SearchPolicy CSPSearchPath
	killall DirectoryService
else if [ "${check4OD}" == "${oldODip}" ]; then
	echo "Removing from ${oldODip}"
		dsconfigldap -r "${oldODip}"
		dscl /Search -delete / CSPSearchPath /LDAPv3/"${oldODip}"
		dscl /Search/Contacts -delete / CSPSearchPath /LDAPv3/"${oldODip}"
		echo "Binding to $domain"
		dsconfigldap -v -a $domain -n $domain
		dscl /Search -create / SearchPolicy CSPSearchPath
		killall DirectoryService
else
	echo "No previous OD servers found, binding to $domain"
	dsconfigldap -v -a $domain -n $domain
	dscl /Search -create / SearchPolicy CSPSearchPath
	sleep 10
	dscl /Search -append / CSPSearchPath /LDAPV3/$domain
	echo "Killing DirectoryService"
	killall DirectoryService
	fi
fi
fi
 
if [ "${check4ODacct}" == "${computerName}" ]; then
	echo "This machine has a computer account on ${domain} already."
else
	echo "Adding computer account to ${domain}"
	dscl -u "${odAdmin}" -P "${odPassword}" /LDAPv3/${domain} -create /Computers/${computerName} ENetAddress "$nicAddress"
	dscl -u "${odAdmin}" -P "${odPassword}" /LDAPv3/${domain} -merge /Computers/${computerName} RealName ${computerName}
	# Add computer to ComputerList
	dscl -u "${odAdmin}" -P "${odPassword}" /LDAPv3/${domain} -merge /ComputerLists/${computerGroup} apple-computers ${computerName}		
 
	# Set the GUID
	GUID="$(dscl /LDAPv3/${domain} -read /Computers/${computerName} GeneratedUID | awk '{ print $2 }')"
	# Add to computergroup
	dscl -u "${odAdmin}" -P "${odPassword}" /LDAPv3/${domain} -merge /ComputerGroups/${computerGroup} apple-group-memberguid "${GUID}"
	dscl -u "${odAdmin}" -P "${odPassword}" /LDAPv3/${domain} -merge /ComputerGroups/${computerGroup} memberUid ${computerName}
fi
 
sleep 25 # Give DS a chance to catch up
 
# Fix DS search order
echo "Checking DS search order..."
if [ "${check4AD}" == "${adDomain}" ]; then
	dsconfigad -alldomains enable
	dscl /Search -delete / CSPSearchPath "/Active Directory/${adDomain}"
	dscl /Search/Contacts -delete / CSPSearchPath "/Active Directory/${adDomain}"
	dscl /Search -append / CSPSearchPath "/Active Directory/All Domains"
	if [ $osvers -eq 4 ]; then
		echo "OS detected as ${osversionlong}"
		echo "Setting AD, then OD to search order..."
		dscl localhost changei /Search CSPSearchPath 2 "/Active Directory/All Domains"
		dscl localhost changei /Search CSPSearchPath 3 /LDAPv3/$domain
		dscl /Search/Contacts -append / CSPSearchPath "/Active Directory/All Domains"
	else if [[ ${osvers} -eq 5 || 6 ]]; then
		echo "OS detected as ${osversionlong}"
		echo "Setting OD, then AD to search order..."
		dscl localhost changei /Search CSPSearchPath 3 "/Active Directory/All Domains"
		dscl localhost changei /Search CSPSearchPath 2 /LDAPv3/$domain
		dscl /Search/Contacts -append / CSPSearchPath "/Active Directory/All Domains"
	fi
fi
	else if [ "${check4AD}" == "All Domains" ]; then
	dscl /Search -append / CSPSearchPath "/Active Directory/All Domains"
	sleep 15
		if [ $osvers -eq 4 ]; then
			echo "OS detected as ${osversionlong}"
			echo "Setting AD, then OD to search order..."
			dscl localhost changei /Search CSPSearchPath 1 "/Active Directory/All Domains"
			dscl localhost changei /Search CSPSearchPath 2 /LDAPv3/$domain
		else if [[ ${osvers} -eq 5 || 6 ]]; then
			echo "OS detected as ${osversionlong}"
			echo "Setting OD, then AD to search order..."
			dscl localhost changei /Search CSPSearchPath 2 /LDAPv3/$domain
			dscl localhost changei /Search CSPSearchPath 3 "/Active Directory/All Domains"
			dscl /Search/Contacts -append / CSPSearchPath "/Active Directory/All Domains"
		fi
	fi
fi
fi	
 
echo "Finished. Exiting..."
exit 0

Find more like this: Absolute Manage, AD Integration, Directory Services, Mac, Open Directory, Scripting , , , ,


13 Responses to Bind to OD Script & Add to Computer Group

  • Ambrose Neville says:

    Hi Patrick, good post, thanks. We’ve been working on something similar, based on Mike Bombich’s binding script, only in our case we are unbinding Macs from one AD and rebinding to another. The twist in our case is that we have to chown the local Home folders associated with network users on each workstation, so a colleague of mine has worked up the script for that.

    Once we’ve successfully done our unbind-rebind-chown on a decent number of machines, I’ll post up the script if it’s useful?

  • Patrick says:

    @Ambrose

    That would be useful indeed. That is a common scenario. Especially in higher-ed where one business unit might move from a local AD to a central AD. My group did that a few years before I came aboard but that was before any Macs were on AD.

  • Donald says:

    This looks helpful, but from first glance there seems to be some errors with you if / fi structure:

    You have a three consecutive fi’s after the last “killall DirectoryService”, two of which have no corresponding if.

    The line “else if [ “${check4AD}” == “All Domains” ]; then” has no corresponding if.

    You have two fi’s before ‘ echo “Finished. Exiting…” ‘ that have no corresponding if.

    To put it another way: You have only 6 if’s but 11 fi’s.

  • Pingback: Script to remove OD bindings « Der Flounder

  • Bryan says:

    Using your script for our environment, which is working fine for the most part after editing for my environment (although I’m having some issues with my AD binding script, but that’s another story).

    I appreciate the work you’ve done on it and it has saved me many precious hours of time.

  • Bryan says:

    Just a quick note to thank you for the time you spent on this. Has been helpful for us in our environment.

  • Patrick says:

    You’re welcome Bryan. Glad you found it useful.

  • john says:

    Hi there,

    Your code is just what I have been looking for. I have never used applescript before but hope to get this working.

    i load your script into applescript editor and when i compile i get the following error:

    Syntax error
    expected expression but found unknown token

    this is the line and the ‘ character is highlighted:

    computerName=`/usr/sbin/scutil –get LocalHostName`

    I am running OSX 10.6.7 and Applescript version 2.3(118)

    I tried replacing the ‘ character with ” and the compiler got further until it stopped at this line, with the same error message:

    osvers=${osversionlong:3:1}

    The $ character is highlighted

    I would love to be able to get this to work so I would be terribly grateful if you can assist me.

    regards,

    John

  • Patrick says:

    @John,

    This isn’t an applescript. It’s a shell script. It gets run in terminal or to a machine remotely via the ARD ‘Send Unix Command’.

  • Francisco Gomez says:

    Awesome script!

    I was wondering, how can I modify this to unbind and remove the OD server from a host.

  • Francisco says:

    I should really read the entire post. I found the script from the trackback.
    Thanks!

  • Nico says:

    I have deployed this to one test machine and it seems to be about 90% there.

    It unbinds from the old OD and binds it to the new OD. but doesnt seem to get any settings even after a reboot.”I have a welcome message for the new OD”

    But if i go to system prefs and login options the connection is there with a green light. If I remove that connection and add the same one back straight away once i log out the settings are being applied (I have my welcome message)

    Any idea why it doesnt appear to bind correctly?

  • Patrick says:

    @Nico.

    Is the script adding your OD to the authentication search path? There are some cases where I find that step doesn’t happen, I believe because the script is running too fast and previous steps weren’t completed yet. Usually running the script a 2nd time gets it going. You might be able to tweak it and a sleep command in the right place so it can complete.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>