Bind to OD Script & Add to Computer Group
The following script is what I use to bind machines to Open Directory and it solves the following challenges:
- 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.
- 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.
- 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.
- 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
Related posts:
- Migrate Local User to Domain Account
- Script to Configure the Mac OS X firewall
- Add directory services data to LANDesk inventory
- Can Open Directory be used enterprise wide?
- Add user to admin group with Applescript
- Updated: Send softwareupdate command through ARD
If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.



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?
@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.
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.