Help! I\'ve been trying to write a function that will confirm a user\'s membership in an Active Directory group, and while it works if the member happens to be in the group,
We had a bit of a poison group in our setup which caused this to fail for some users but not others. The "FirstOrDefault" logic in the other suggested answers MIGHT have helped us dodge the poison group, but that is no guarantee.
We have two suggestions for others with this problem. First check if you have any groups with a forward slash in the group name (the actual group name, not the "pre-windows 2000" name which will replace it with an underscore). If you can rename all such groups that might fix your problem ... it worked for us.
This workaround also was working for us:
///
/// This does a recursive group search for the given user or computer principal.
///
public IEnumerable GetGroups(Principal principal)
{
return GetGroups(null, principal);
}
private IEnumerable GetGroups(HashSet ancestorPrincipalSids, Principal parentPrincipal)
{
try
{
//enumerate this here so errors are thrown now and not later
//if the current group name has a forward-slash, I think this
//will always error here
var groups = parentPrincipal.GetGroups().ToArray();
if (groups == null)
{
return Enumerable.Empty();
}
//keep track of all ancestors in the group hierarchy to this point
//so that we can handle circular references below
var newAncestors = new HashSet(ancestorPrincipalSids ?? Enumerable.Empty());
newAncestors.Add(parentPrincipal.Sid);
return groups
.Concat(groups
.Where(g => !newAncestors.Contains(g.Sid)) //handle circular references
.SelectMany(g => GetGroups(newAncestors, g)));
}
catch
{
return Enumerable.Empty();
}
}