Thursday, September 25, 2014

Syncing Nested Groups to Google Apps using GADS

We use GADS (Google Apps Directory Sync) to sync our Active Directory structure with our Google apps setup. We wanted to start syncing groups, however the users we wanted to be part of the group were nested within other groups. One way we could resolve this would be to sync all the intermediary groups, but in our case that would create a lot of groups that we really wouldn't need. The solution we came up with has two parts:

1) In Active Directory create a special LDAP filter and assign it to one of the group's extensionAttribute values

2) In GADS sync the group as a Dynamic group, using the extensionAttribute to perform the query to find the users

Lets say we have a security group group called cool-users. cool-users doesn't have any users, but the security groups rad-dudes and awesome-guys are members of it and THOSE groups have users. We want to sync this to Google Apps as cool-users@contoso.com but we don't want to create groups for rad-dudes and awesome-guys and just want all the users to be a part of cool-users@contoso.com.

For step one, the query we needed to craft was as follows:

 (&(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=cool-users,OU=Groups,DC=contoso,DC=com))  

For those not super familiar with LDAP search syntax this is a query that looks for an object that is a user and is a member of the group identified by the distinguished name CN=cool-users,OU=Groups,DC=contoso,DC=com The weird looking bit (memberOf:1.2.840.113556.1.4.1941) is the magical part that does it's own search to find the all members of the group (including nested ones). For further reading check out http://msdn.microsoft.com/en-us/library/aa746475(v=vs.85).aspx and look for LDAP_MATCHING_RULE_IN_CHAIN.

With our rule made we now need to assign it to the group, which we COULD do a number of different ways (such as editing the object directly with object editor), but we have a few objects we want to sync like this, so we opted to do it programmatically via powershell using the following script:

 Get-ADGroup -LDAPFilter "(&(objectClass=group)(cn=*-users))" -SearchBase "OU=Groups,DC=contoso,DC=com" |  
 ForEach-Object {  
   $EXT1 = "(&(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=" + $_.name + ",OU=Groups,DC=contoso,DC=com))"  
   Set-ADGroup $_ -Replace @{extensionAttribute1=$EXT1}  
 }  
What this does is grab any groups that end in -users in the OU=Groups,DC=contoso,DC=com OU and sets extensionAttribute1 to the proper search string. It might not be a bad idea to run this as a scheduled powershell task every so often so that new groups and any renamed groups get the correct search string.

Now that our groups are set properly, we can configure GADS to use them. Open GADS, head for the groups tab and add a search rule that looks like the following:

We're going to find any groups that match *-users in our Groups OU and sync them to Google Apps, but we're going to make them Dynamic and use extensionAttribute1 as the object property that contains the search that has all of our users. Run a test of your sync and voila! You should have the groups syncing all the users that belong to it!

One word of caution would be that using LDAP_MATCHING_RULE_IN_CHAIN to search in this manner can be computationally expensive, so it's possible that your sync could take noticeably longer to run. It's best to make use of filters and only use this method on necessary groups. I hope you find this useful!

4 comments:

  1. This is fantastic.

    I don't have the Exchange Schema installed in my domain so I don't have the extensionAttribute1+ fields. So I just used the "info" field and still had the same results.

    Thank you so much for this post

    ReplyDelete
  2. How about moving user between groups IN AD? Will they be also moved in Google Apps Groups?

    ReplyDelete
  3. The picture is broken! oh no! I really need this. Can you fix the screenshot?

    ReplyDelete