Reputation: 439
I have currently written a c# script to retrieve users that belong to three separate user groups - it looks like this...
string DomainPath = "LDAP://DC=<dc>,DC=<dc>,DC=org";
DirectoryEntry searchRoot = new DirectoryEntry(DomainPath);
DirectorySearcher search = new DirectorySearcher(searchRoot);
search.Filter = "(&(objectClass=user)(objectCategory=person)(|(memberof=CN=group1,OU=Groups,OU=<ou>,DC=dc,DC=<dc>,DC=org)(memberof=CN=group2,OU=Groups,OU=<ou>,DC=<dc>,DC=<dc>,DC=org)(memberof=CN=group3,OU=Groups,OU=<ou>,DC=<dc>,DC=<dc>,DC=org)))";
search.PropertiesToLoad.Add("samaccountname");
search.PropertiesToLoad.Add("mail");
search.PropertiesToLoad.Add("usergroup");
search.PropertiesToLoad.Add("displayname");
search.PropertiesToLoad.Add("manager");
SearchResult result;
SearchResultCollection resultCol = search.FindAll();
Using this code, I am able to retrieve any properties exposed for this user, including the "manager" record. The manager record is exposed as a DN at this level:
Manager = "CN=MTK93,OU=Users,OU=<ou>,DC=<dc>,DC=<dc>,DC=org"
What is really want is to be able to recursively get all of the user attributes for each manager of the folks returned by the existing query - and then combine them into one dataset...
For example, consider the following hierarchy....
Lisa (manager's manager)
|
| -- Tim (Manager)
| mail = [email protected], usergroup = groupA, manager = Lisa
| |
| |-- Mike
| | mail = [email protected], usergroup = group1, manager = Tim
| |-- Lori
| | mail = [email protected], usergroup = group2, manager = Tim
| -- Katie (another manager)
| mail = [email protected], usergroup = groupB, manager = Lisa
|
|-- John
| mail = [email protected], usergroup = group3, manager = Katie
|-- Larry
mail = [email protected], usergroup = group4, manager = Katie
My query is returning mike, lori, katie, and john because they exist in the groups I am querying for (group1, group2, group3) - but I need Tim and Katie's user record too (because they are managers of someone that belongs to those groups)
The ideal output would look something like this...
Name Mail Group Manager
------------------------------------------------
Mike [email protected] group1 Tim's DN
Lori [email protected] group2 Tim's DN
John [email protected] group3 Katie's DN
Katie [email protected] groupB Lisa's DN
Tim [email protected] groupA Lisa's DN
Note: I do not want Lisa (nobody in the level below her belongs to group1, group2, or group3) or Larry (doesn't belong to group1, group2, or group3)
The recursive nature of this LDAP query is proving to be pretty tough to figure out.
Upvotes: 2
Views: 1303
Reputation: 439
I was able to get the results I needed by taking the following approach:
Remove any duplicates
// class variable
List<ActiveDirectoryUser> recordsToInsert;
// build the query appender
string queryAppender = "";
foreach (string activeDirectoryGroup in activeDirectoryGroups)
{
queryAppender += "(memberof=CN=" + activeDirectoryGroup + ",OU=Groups,OU=<<ou>>,DC=<<dc>>,DC=<<dc>>,DC=<org>>)";
}
// create the ldap query string
var ldapQueryForUsersInDtGroups = "(&(objectClass=user)(objectCategory=person)(|" + queryAppender + "))";
// first get the users that belong to the active directory groups...
recordsToInsert = getEmployeeRecordsFromLdapQuery(ldapQueryForUsersInDtGroups);
// then, query again to make sure we are including the managers for the people returned from the first query
var distinctManagers = (from record in recordsToInsert select record.manager).Distinct();
// build an ldap query to get only the records for the managers we need
// example query string with 2 managers:
// (&(objectClass=user)(objectCategory=person)
queryAppender = "";
foreach (var manager in distinctManagers)
{
queryAppender += "(distinguishedName=" + manager + ")";
}
// ldap query filter for the managers
var ldapQueryForManagers = "(&(objectClass=user)(objectCategory=person)(|" + queryAppender + "))";
// combine the result set with the managers result set
recordsToInsert.AddRange(getEmployeeRecordsFromLdapQuery(ldapQueryForManagers));
// filter off any duplicates.
uniqueRecordsToInsert = recordsToInsert.GroupBy(x => x.employeeId).Select(x => x.First()).ToList<ActiveDirectoryUser>();
Upvotes: 1