如何查询所有组和组成员的Active Directory?

时间:2012-02-28 18:20:53

标签: c# .net active-directory

我正在查看DirectoryServices命名空间,我正在尝试获取AD中所有组的列表并将它们加载到列表框中。

当我选择一个组时,我希望它填充一个包含管理员名称的文本框以及另一个列表框,其中所有用户都分配给该组。我很难绕过这个过程。有人可以帮帮我吗?

如果我得到一个完整的例子,我相当肯定我会更好地理解更大的图景。 TIA

2 个答案:

答案 0 :(得分:10)

如果您使用的是.NET 3.5或更高版本,则可以使用PrincipalSearcher和“按示例查询”主体进行搜索:

// 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
     }
}

如果您还没有 - 绝对阅读MSDN文章Managing Directory Security Principals in the .NET Framework 3.5,该文章很好地展示了如何充分利用System.DirectoryServices.AccountManagement

中的新功能

当您拥有一个给定的群组时,您可以使用以下方式轻松获得所有群组成员:

// 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
   }
}

答案 1 :(得分:2)

我使用System.DirectoryServices.AccountManagement命名空间提出了类似于marc_s的内容:

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...
        }
    }

UserPrincipal class似乎没有公开允许您确定用户是否和/或有经理的任何成员,但您仍然可以通过获取DirectoryEntry来获取用户:

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...
}

但是,您需要一些额外的逻辑来确定用户是否是您当前正在查看的组中的经理,而不是其他组。也许检查directReports属性以查看其中包含的任何用户是否是当前组的成员。