13

So I have a question regarding recursive groups in active directory. I have a little method that checks if a user id is in a group or not. Works great. Found out today that it doesn't check recursive group membership and I'm not too sure how (or if) there is a way to do that. Here's what I have so far for non-recursive:

public static bool CheckGroupMembership(string userID, string groupName, string Domain)
{
  bool isMember = false;

  PrincipalContext ADDomain = new PrincipalContext(ContextType.Domain, Domain);
  UserPrincipal user = UserPrincipal.FindByIdentity(ADDomain, userID);

  if (user.IsMemberOf(ADDomain, IdentityType.Name, groupName.Trim()))
  {
    isMember = true;
  }

  return isMember;
}

I've seen some things about a directory searcher or something but I'm somewhat new to working directly with AD and while I understand the concepts, some other things are still a little lost on me.

Thanks!

Seril
  • 499
  • 4
  • 9
  • 22

2 Answers2

34

You can also check by using the recursive option of GroupPrincipal.GetMembers.

public static bool CheckGroupMembership(string userID, string groupName, string Domain) {
    bool isMember = false;

    PrincipalContext ADDomain = new PrincipalContext(ContextType.Domain, Domain);
    UserPrincipal user = UserPrincipal.FindByIdentity(ADDomain, userID);
    GroupPrincipal group = GroupPrincipal.FindByIdentity(ADDomain, groupName);

    if ((user != null) && (group != null)) {
        isMember = group.GetMembers(true).Contains(user);
    }

    return isMember;
}
Steve Young
  • 532
  • 1
  • 7
  • 13
  • 1
    GetMembers is much faster than IsMember – sartoris May 27 '15 at 23:53
  • VERY COOL. Been searching for over an hour, and this is by far the best method I've seen! – David P Jul 31 '15 at 17:10
  • 5
    Just a note, if you have a *huge* AD both suggested methods are the slowest things ever. Not blaming the answers, just alerting about the fact that in such situations a solution might need some compromises... – Wasp Sep 23 '16 at 08:34
  • For me the better solution since this only gets the real members whereas GetAuthorizationGroups (accepted answer) return members can get tricky "The returned set may also include additional groups that system would consider the user a member of for authorization purposes." (Microsoft) – Marc Wittmann Feb 13 '17 at 11:46
15

Here is a solution using System.DirectoryServices.AccountManagement Namespace. It's a kind of recursive solution. In Find Recursive Group Membership (Active Directory) using C#, I give a recursive solution that also works with distribution groups.

/* Retreiving a principal context
 */
Console.WriteLine("Retreiving a principal context");
PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, "WM2008R2ENT:389", "dc=dom,dc=fr", "jpb", "PWD");


/* Look for all the groups a user belongs to
 */
UserPrincipal aUser = UserPrincipal.FindByIdentity(domainContext, "user1");
PrincipalSearchResult<Principal> a =  aUser.GetAuthorizationGroups();

foreach (GroupPrincipal gTmp in a)
{
  Console.WriteLine(gTmp.Name);    
}
Community
  • 1
  • 1
JPBlanc
  • 70,406
  • 17
  • 130
  • 175
  • Are you sure this will return distribution groups too? – Ray Cheng Oct 26 '16 at 19:23
  • No, this is writen : _In Find Recursive Group Membership (Active Directory) using C#, I give a recursive solution that also works with distribution groups_. Here it's for security groups. – JPBlanc Oct 27 '16 at 05:37