So I'm trying to get something going with enumerating AD group membership recursively. At the moment I have...
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "mine.domain.com");
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, "myADGroup");
if (grp != null)
{
foreach (Principal p in grp.GetMembers(true))
{
Console.WriteLine(p.Name);
}
}
This all works great, of course. It lists every user who is a member of the group and all the users who are members of groups nested within, however many nesting levels deep that may be. Which is great.
What I really need is to know what group in this little nesting the user came from.
GRP-MainProject
-- GRP-Producers
-- GRP-Artists
-- UserA
Running my current query against GRP-MainProject will return UserA - how should I go about returning the user and the fact that it was GRP-Artists which he inherited membership of GRP-MainProject from?
UserA is a member of about 40 groups or so, in case that matters. Edit - worth mentioning the user could have membership of the group from multiple nested groups.
Any thoughts would be appreciated.
Try something like this maybe:
Declare Static List of Group Objects (simple class of GroupPrincipal, integer level, and parent GroupPrincipal)
public class SomeDirTraverser
{
private static List<GroupObj> _groups = new List<GroupObj>();
public List<string> GetMembershipWithPath(string groupname)
{
List<string> retVal = new List<string>();
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupname);
if (grp != null)
{
BuildHList(grp, 0, null);
foreach (UserPrincipal usr in grp.GetMembers(true))
retVal.Add(GetMbrPath(usr));
}
return retVal;
}
private void BuildHList(GroupPrincipal node, int level, GroupPrincipal parent)
{
PrincipalSearchResult<Principal> rslts = node.GetMembers();
_groups.Add(new GroupObj() { Group = node, Level = level, Parent = parent });
foreach (GroupPrincipal grp in rslts.Where(g => g is GroupPrincipal))
BuildHList(grp, level + 1, node);
}
private string GetMbrPath(UserPrincipal usr)
{
Stack<string> output = new Stack<string>();
StringBuilder retVal = new StringBuilder();
GroupObj fg = null, tg = null;
output.Push(usr.Name);
foreach (GroupObj go in _groups)
{
if (usr.IsMemberOf(go.Group))
{
output.Push(go.Group.Name);
fg = go;
while (fg.Parent != null)
{
output.Push(fg.Parent.Name);
tg = (from g in _groups where g.Group == fg.Parent select g).FirstOrDefault();
fg = tg;
}
break;
}
}
while (output.Count > 1)
retVal.AppendFormat("{0} ->", output.Pop());
retVal.Append(output.Pop());
return retVal.ToString();
}
}
public class GroupObj
{
public GroupPrincipal Group { get; set; }
public int Level { get; set; }
public GroupPrincipal Parent { get; set; }
}
This one looks like it should give you what you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With