.net 获取属于组的用户

tnkciper  于 2023-02-10  发布在  .NET
关注(0)|答案(4)|浏览(166)

我得到了一个可行的解决方案,但是我非常肯定有一个资源密集度较低的方法,因为当前的解决方案涉及到执行查询以获取组成员,然后执行查询以获取每个用户的信息。
下面是我的代码:

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

不幸的是,出于某种原因,这并不奏效。

t1rydlwq

t1rydlwq1#

如果可以使用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代码,也可以用旧的方法来做,但这肯定是更简单的帐户管理。
下面是我提到的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")
izj3ouym

izj3ouym2#

using System.DirectoryServices;

DirectoryEntry objEntry = new DirectoryEntry(Ldapserver, userid, password);
DirectorySearcher personSearcher = new DirectorySearcher(objEntry);
personSearcher.Filter = string.Format("(SAMAccountName={0})", username);
SearchResult result = personSearcher.FindOne();

if(result != null)
{
    DirectoryEntry personEntry = result.GetDirectoryEntry();
    PropertyValueCollection groups = personEntry.Properties["memberOf"];
    foreach(string g in groups)
    {
        Console.WriteLine(g); // will write group name
    }
}

我最初使用的方法与您发布的方法非常相似,运行整个公司的AD并获得结果大约需要12分钟。切换到这种方法后,大约需要2分钟。您需要使用我编写ldapserver的ldapserver地址以及用户ID和密码,用户名是您要查找的人的SAMAccountName。

zxlwwiss

zxlwwiss3#

如果选中HERE,则可以执行以下操作:

DirectoryEntry group = new DirectoryEntry("LDAP://CN=foo-group,DC=Cmp,DC=COM");
foreach(object dn in group.Properties["member"] )
    //do whatever
pw9qyyiw

pw9qyyiw4#

使用GroupPrincipal方法FindByIdentity会更短,它还提供了多种方法来识别IdentityType组:

using (var context = new PrincipalContext(ContextType.Domain, "YOUR_DOMAIN_NAME")
        {
            var userPrincipals = GroupPrincipal
                .FindByIdentity(context, IdentityType.SamAccountName, "GROUP_ACCOUNT")
                .GetMembers(true) // recursive
                .OfType<UserPrincipal>();
            ...
        }

相关问题