c# - 获取 'memberof' 为一组的用户

标签 c# .net active-directory

我有一个有效的解决方案,但我很确定有一种资源密集度较低的方法,因为当前的解决方案涉及执行查询以获取组成员,然后进行查询以获取每个用户的信息。

这是我的代码:

DirectoryEntry root = new DirectoryEntry( "LDAP://server:port" );
DirectorySearcher searcher = new DirectorySearcher( root );
searcher.Filter = "(&(ObjectClass=Group)(CN=foo-group))";

var members = (IEnumerable)searcher.FindOne()
              .GetDirectoryEntry()
              .Invoke( "members" );

Dictionary<string , string> results = new Dictionary<string , string>();

foreach( object member in members ) {
   DirectoryEntry de = new DirectoryEntry( member );
   results.Add( de.Properties[ "SAMAccountname" ][ 0 ].ToString(), de.Properties[ "cn" ][ 0 ].ToString() );
}

理想情况下,我希望能够执行单个查询来获取组中的每个用户,过滤要加载的属性,然后显示它们。所以像这样

DirectoryEntry root = new DirectoryEntry( "LDAP://server:port" );
DirectorySearcher searcher = new DirectorySearcher( root );
searcher.PropertiesToLoad.Add( "cn" );
searcher.PropertiesToLoad.Add( "SAMAccountname" );
searcher.Filter = "(&(ObjectClass=user)(memberof=foo-group))";

foreach( var user in searcher.FindAll() ) {
    //do whatever...
}

不幸的是,由于某种原因,这不起作用。

最佳答案

如果可以使用 System.DirectoryServices.AccountManagement:

var context = new PrincipalContext(ContextType.Domain, "YOUR_DOMAIN_NAME");
using (var searcher = new PrincipalSearcher())
{
    var groupName = "YourGroup";
    var sp = new GroupPrincipal(context, groupName);
    searcher.QueryFilter = sp;
    var group = searcher.FindOne() as GroupPrincipal;

    if (group == null)
        Console.WriteLine("Invalid Group Name: {0}", groupName);

    foreach (var f in group.GetMembers())
    {
        var principal = f as UserPrincipal;

        if (principal == null || string.IsNullOrEmpty(principal.Name))
            continue;

        Console.WriteLine("{0}", principal.Name);
    }
}

我有一些 VB 代码也可以用旧方法来完成,但是使用 AccountManagement 肯定更简单。


这是我所指的 VB 代码(同样它不是很漂亮但很实用):

Public Function GetUsersByGroup(de As DirectoryEntry, groupName As String) As IEnumerable(Of DirectoryEntry)
    Dim userList As New List(Of DirectoryEntry)
    Dim group As DirectoryEntry = GetGroup(de, groupName)

    If group Is Nothing Then Return Nothing

    For Each user In GetUsers(de)
        If IsUserInGroup(user, group) Then
            userList.Add(user)
        End If
    Next

    Return userList
End Function

Public Function GetGroup(de As DirectoryEntry, groupName As String) As DirectoryEntry
    Dim deSearch As New DirectorySearcher(de)

    deSearch.Filter = "(&(objectClass=group)(SAMAccountName=" & groupName & "))"

    Dim result As SearchResult = deSearch.FindOne()

    If result Is Nothing Then
        Return Nothing
    End If

    Return result.GetDirectoryEntry()
End Function

Public Function GetUsers(de As DirectoryEntry) As IEnumerable(Of DirectoryEntry)
    Dim deSearch As New DirectorySearcher(de)
    Dim userList As New List(Of DirectoryEntry)

    deSearch.Filter = "(&(objectClass=person))"

    For Each user In deSearch.FindAll()
        userList.Add(user.GetDirectoryEntry())
    Next

    Return userList
End Function

Public Function IsUserInGroup(user As DirectoryEntry, group As DirectoryEntry) As Boolean
    Dim memberValues = user.Properties("memberOf")

    If memberValues Is Nothing OrElse memberValues.Count = 0 Then Return False

    For Each g In memberValues.Value
        If g = group.Properties("distinguishedName").Value.ToString() Then
            Return True
        End If
    Next

    Return False
End Function

和用法:

Dim entries = New DirectoryEntry("LDAP://...")
Dim userList As IEnumerable(Of DirectoryEntry) = GetUsersByGroup(entries, "GroupName")

关于c# - 获取 'memberof' 为一组的用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9603777/

相关文章:

c# - 从 pid 获取窗口标题

c# - NLog 控制台应用程序

C#:更改事件目录用户密码时出现代码错误

c# - 验证与焦点丢失

c# - .NET 中的生产者/消费者模式

c# - 在 C# 中是一个 for(;;) 安全的,它到底做了什么?

c# - 给定用户的 SID,我如何获得他们的 userPrincipalName?

asp.net-mvc-3 - MVC3 自定义 MembershipProvider 和 Active Directory

c# - 如何通过名称获取 C#.Net 程序集?

c# - Linq to SQL 奇怪的 SQL 翻译