Hello
Well I thought I would post a script that I have done to get users into Zimbra from Active Directory.
I copied parts from zsync_ad.sh script by Eduardo Gonzalez.
But i needed more info from the AD to get into each Zimbra account.
So its still a little ruff around the edges

and i will post a cleaner (so dont point out the terrible use of awk

) copy as soon as i get around to it.
But essentially it check the AD for a list of users and compares it against Zimbra's users using LDAPSEARCH and adds each NEW user into Zimbra.
Code:
#!/bin/bash
# Zimbra to Active Directory By Dominic Carpenter but concept and parts copied from zsync_ad.sh script by Eduardo Gonzalez so a big thank you to him
# LDAP Search on Active Directory and Zimbra with a sort and strip.
# This does not modify data lready in Zimbra, it only creates if the account is new to zimbra
# To Change the Active Directory search limit (1000) http://www.nordicedge.se/support/kb/questions/236/NSD1122+How+to+change+the+LDAP+search+limit+limitation+of+1000+objects+in+AD+LDS
Domain="YOURDOMAIN.COM" # DNS Name or IP of Active Directory
ADDOMAIN="YOURDOMAIN.COM" # Active Directory Domain (No idea why I added this twice......
DN="OU=Account,DC=YOURDOMAIN,DC=COM" # Search an OU or the base DN
USER_DN="cn=Zimbra,cn=Users,DC=YOURDOMAIN,DC=COM" # Authenticated User to do search
USER_PASS="PASSWORD" # Authenticated User Password
ZM_Domain="localhost" # DNS Name or IP of Zimabra Server
ZMProv="/opt/zimbra/bin/zmprov"
ZMServer="ZMIMBRA.YOURDOMAIN.COM" # Zimbra Server
ZMSearch="ou=people,DC=YOURDOMAIN,DC=COM" # Zimbra Search Path
printf "Looking for Users in Active Directory.... \n"
ldapsearch -x -h $Domain -b $DN -D $USER_DN -w $USER_PASS -LLL "(mail=*)" name | grep name | sed 's/name: //g' | sort > /tmp/ADUsers.txt
ADcount=`cat /tmp/ADUsers.txt | wc -l | sed 's/^[ \t]*//'` # Count AD Users
printf "$ADcount AD Users writen to tmp file ... \n"
# Get User info from Zimbra so we can compare user lists
printf "Quering Zimbra Server... \n"
ldapsearch -h $ZMServer -x -b $ZMSearch '(objectclass=*)' displayName | grep displayName | sed 's/displayName: //g' | sort > /tmp/ZMUsers.txt
ZMcount=`cat /tmp/ZMUsers.txt | wc -l | sed 's/^[ \t]*//'` # Count ZM Users
printf "$ZMcount Zimbra Users writen to tmp file ... \n"
# Generate diff to get unique users
printf "Generating diff file /tmp/Users.txt \n"
diff -u /tmp/ZMUsers.txt /tmp/ADUsers.txt | grep ^+ | grep -v tmp | sed 's/+//g' > /tmp/Users.txt # Clean
rm -f /tmp/ZMUsers.txt /tmp/ZMUsers.txt
IFS="
"
# Loop through the unique users
count=`cat /tmp/Users.txt | wc -l | sed 's/^[ \t]*//'`
printf "starting process lookup on $count users... \n"
for line in `cat /tmp/Users.txt`;do
# Return the results in the following;
# Name of user that is in the loop
# Description of the User
# Strip the CN path of user to extract top OU i.e employees
# The Fax Number (used for id number)
# The email Address
# The Username
# The Telephone Number
# Full Search String returned
# Unhash to see the echo results
searchValues=`ldapsearch -x -h $Domain -b $DN -D $USER_DN -w $USER_PASS -LLL "(name=$line)" mail description telephoneNumber facsimileTelephoneNumber sAMAccountName sn givenName`
Name=`echo $line` # name of user
#Description=`echo $searchValues | grep -w description | awk '{split ($0, a, "description:"); print a[2]}' | awk '{split ($0, a, ":"); print a[1]}' | awk '{sub($NF,"");sub(" ","");print}'| sed 's/^[ \t]*//';exit 0` # Description
CN_path=`echo $searchValues | grep -w OU | awk '{split ($0, a, ","); print a[2]}' | sed 's/OU=//g'` # Get the Group from the OU path i.e. Employees
FAX=`echo $searchValues | grep -w facsimileTelephoneNumber: | awk '{split ($0, a, "facsimileTelephoneNumber:"); print a[2]}' | awk '{print $1}' | sed 's/facsimileTelephoneNumber//g';exit 0` # Fax Number (Employee ID)
Email=`echo $searchValues | grep -w mail: | awk '{split ($0, a, "mail:"); print a[2]}' | sed 's/^[ \t]*//'` # email mail address
Username=`echo $searchValues | grep -w sAMAccountName: | awk '{split ($0, a, "sAMAccountName:"); print a[2]}' | awk '{print $1}'` # get the username
#Telephone=`echo $searchValues | grep -w telephoneNumber: | awk '{split ($0, a, "telephoneNumber:"); print a[2]}' | awk '{print $1}';exit 0` # the Telephone Number
SN=`echo $searchValues | awk '{split ($0, a, "sn:"); print a[2]}' | awk '{print $1}'` # Last Name
GivenName=`echo $searchValues | awk '{split ($0, a, "givenName:"); print a[2]}' | awk '{split ($0, a, "sAMAccountName:"); print a[1]}' | sed 's/^[ \t]*//'` # Two splits because they might have two names (clean this messy code up.... )
Full_String=`echo $searchValues` # full string returned
#echo $Name
#echo $GivenName
#echo $SN
#echo $Description
#echo $CN_path
#echo $FAX
#echo $Email
#echo $Username
#echo $Telephone
#echo $Full_String
#echo # Space the view results
printf "Creating User $Name \n"; # Print something so i know its doing something
#echo $ZMProv createAccount $Email pass
$ZMProv createAccount $Email passwd > /dev/null; # No Pass as authentication is from AD
$ZMProv modifyAccount $Email displayName "$Name"; # Display Name
$ZMProv modifyAccount $Email givenName "$GivenName"; # Last Name
$ZMProv modifyAccount $Email sn "$SN"; # First Name(s)
$ZMProv SetAccountCOS $Email $CN_path; # Set COS based apon the OU that the user sits in. i.e CN=My Name,OU=GroupOU,OU=stuff,DC=Domain,DC=Com the COS is GroupOU and is pre-created in Zimbra
#$ZMProv modifyAccount $Email description $Description;
#$ZMProv modifyAccount $Email Notes $FAX; # <---- check LDAP Schema as this is not working.....
$ZMProv AddAccountAlias $Email $Username"@"$ADDOMAIN; # Account Alias based apon there sAMAccountName
/opt/zimbra/bin/zmmailbox -z -m $Email cf -u 'http://url-to-my-rss-feed/rss.xml' /folder-for-rss-feed # Add RSS Feed to each user
# $ZMProv modifyAccount $Email telephoneNumber $Telephone
# $ZMProv modifyAccount $Email zimbraAccountStatus maintenance # Used for testing so search can locate and delete
# $ZMProv modifyAccount $Email zimbraAccountStatus active,maintenance,locked,closed # Edit for correct Account Status
done