Sinaesthetic
Sinaesthetic

Reputation: 12192

How to query Active Directory for all groups and group members?

I'm looking at the DirectoryServices namespace and I'm trying to get a list of all groups in the AD and load them into a listbox.

When I select a group, I want it to fill a text box with the manager's name as well another listbox with all users assigned to that group. I'm having a hard time wrapping my head around the process. Could someone help me out?

If I get a full example of this, I'm fairly sure that I'll understand the bigger picture a lot better. TIA

Upvotes: 3

Views: 20374

Answers (2)

Lance U. Matthews
Lance U. Matthews

Reputation: 16596

I came up with something similar to marc_s using the System.DirectoryServices.AccountManagement namespace:

PrincipalContext context = new PrincipalContext(ContextType.Domain);
GroupPrincipal queryPrincipal = new GroupPrincipal(context);

using (PrincipalSearcher searcher = new PrincipalSearcher(queryPrincipal))
using (PrincipalSearchResult<Principal> allPrincipals = searcher.FindAll())
    foreach (GroupPrincipal groupPrincipal in allPrincipals.OfType<GroupPrincipal>())
    {
        // Process group...

        foreach (UserPrincipal userPrincipal in groupPrincipal.Members.OfType<UserPrincipal>())
        {
            // Process group member...
        }
    }

The UserPrincipal class doesn't appear to expose any members that would allow you to determine if a user is and/or has a manager, but you can still do it by obtaining the DirectoryEntry for the user:

DirectoryEntry userEntry = userPrincipal.GetUnderlyingObject() as DirectoryEntry;

if (userEntry != null)
{
    bool isManager = userEntry.Properties["directReports"].Count > 0;
    bool isManaged = userEntry.Properties["manager"].Count > 0;

    // Perform further processing...
}

You'll need some additional logic, though, to determine if the user is a manager in the group you're currently looking at, rather than some other group. Maybe check the directReports property to see if any of the users contained within are members of the current group.

Upvotes: 2

marc_s
marc_s

Reputation: 754230

If you're running on .NET 3.5 or newer, you can use a PrincipalSearcher and a "query-by-example" principal to do your searching:

// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// define a "query-by-example" principal - here, we search for a GroupPrincipal 
GroupPrincipal qbeGroup = new GroupPrincipal(ctx);

// create your principal searcher passing in the QBE principal    
PrincipalSearcher srch = new PrincipalSearcher(qbeGroup);

// find all matches
foreach(var found in srch.FindAll())
{
     GroupPrincipal foundGroup = found as GroupPrincipal;

     if(foundGroup != null)
     {
        // do whatever you need to do, e.g. put name into a list of strings or something
     }
}

If you haven't already - absolutely read the MSDN article Managing Directory Security Principals in the .NET Framework 3.5 which shows nicely how to make the best use of the new features in System.DirectoryServices.AccountManagement

When you have a given group, you can easily get all its group members by using:

// find the group in question (or load it from e.g. your list)
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "YourGroupNameHere");

// if found....
if (group != null)
{
   // iterate over members
   foreach (Principal p in group.GetMembers())
   {
      Console.WriteLine("{0}: {1}", p.StructuralObjectClass, p.DisplayName);
      // do whatever you need to do to those members
   }
}

Upvotes: 10

Related Questions