2013-08-08 27 views
5

Vì vậy, tôi đang cố gắng để có được một cái gì đó đi với liệt kê thành viên nhóm AD đệ quy. Tại thời điểm này, tôi có ...C# - GroupPrincipal.GetMembers (đúng) - nhóm nào?

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); 
    } 
} 

Tất cả điều này đều tuyệt vời, tất nhiên. Nó liệt kê mọi người dùng là thành viên của nhóm và tất cả người dùng là thành viên của nhóm được lồng vào bên trong, tuy nhiên nhiều cấp độ lồng nhau có thể sâu hơn. Điều đó thật tuyệt.

Điều tôi thực sự cần biết là nhóm nào trong số ít người dùng làm tổ này.

GRP-MainProject 
    -- GRP-Producers 
    -- GRP-Artists 
    -- UserA 

Chạy truy vấn hiện tại của tôi chống lại GRP-MainProject sẽ trở lại UserA - làm thế nào tôi nên đi về trả lại người dùng và thực tế là nó là GRP-Nghệ sĩ mà ông thừa hưởng thành viên của GRP-MainProject từ đâu?

UserA là thành viên của khoảng 40 nhóm hoặc hơn, trong trường hợp quan trọng. Chỉnh sửa - đáng nhắc đến người dùng có thể có tư cách thành viên của nhóm từ nhiều nhóm lồng nhau.

Bất kỳ suy nghĩ nào cũng sẽ được đánh giá cao.

+1

Tôi nghĩ rằng bạn đã biết nó trong dòng này foreach (Chính p trong grp.GetMembers (true)) chỉ cần đầu ra grp cùng với p.Name của bạn – Raymund

+0

Khi tôi xuất grp, nó chỉ xuất ra "GRP-MainProject" làm nhóm cho UserA, trong khi tôi cần trả lại GRP-Nghệ sĩ làm nhóm người dùng. Bởi vì giá trị bool cho GetMembers là đúng, đầu ra đệ quy của nó chỉ đếm tất cả người dùng bên trong nó như là trong GRP-MainProject, bất kể thành viên nhóm lồng nhau thực tế. – dotalchemy

Trả lời

2

Hãy thử một cái gì đó như thế này có lẽ:

Khai báo Static Danh sách Nhóm đối tượng (lớp đơn giản của GroupPrincipal, mức số nguyên, và phụ huynh 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; } 
} 

Điều này có vẻ như nó sẽ cung cấp cho bạn những gì bạn muốn.

+0

Điều này có thể hoạt động. Tôi cần phải chơi với nó một chút, như đầu ra chỉ cần được GroupPrincipal -> GroupPrincipal -> UserPrincipal nơi UserPrincipal u == "Joe Blogs" - Tôi sẽ chơi vào ngày mai hy vọng. Cảm ơn. – dotalchemy

+0

Vì vậy, điều này có những điều cơ bản của nó, nhưng cuối cùng nó chỉ bán phá giá memebership nhóm đệ quy. Tôi đang đấu tranh để tìm ra cách để vượt qua một tên người dùng với nó và có nó trả về các đối tượng GroupPrincipal giữ tên người dùng đó liên quan đến tên người dùng này. Mục tiêu cuối cấp cao là trả lời câu hỏi "Người dùng có quyền truy cập vào thư mục này - từ đâu anh ta có được điều này?" – dotalchemy

+0

@dotalchemy ok, tôi hiểu những gì bạn đang tìm kiếm ngay bây giờ. Tôi sẽ cập nhật câu trả lời của mình sau vài phút và xem liệu tôi có thể nhận được câu trả lời gần hơn ở đầu ra – randcd

0

Làm thế nào về:

PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "mine.domain.com"); 
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, "myADGroup"); 
if (grp != null) 
{ 
    foreach (UserPrincipal user in grp.GetMembers(true)) 
    { 
     Console.WriteLine("User: {0}", user.Name); 
     foreach (Principal userGroup in user.GetGroups(ctx)) 
     { 
      Console.WriteLine(" - Member of Group: {0}", userGroup.Name); 
     } 
    } 
} 
+0

Điều này có thể là một ý tưởng tốt nếu bạn bằng cách nào đó có thể thêm một kiểm tra để kiểm tra xem 'userGroup' là một thành viên của' grp' trước khi xuất thông tin ... –