获取“成员”组的用户

我得到了一个有效的解决方案,但我非常确定资源密集度较低的方法,因为当前的解决方案包括进行查询以获取组成员,然后查询以获取每个用户的信息。

这是我的代码:

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 results = new Dictionary(); 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代码(再次它不漂亮,但它的function):

 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") 
 using System.DirectoryServices; DirectoryEntry objEntry = 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 } } 

我最初使用的方法类似于您发布的方法,大约需要12分钟才能完成整个公司的广告并获得结果。 切换到此方法后,大约需要2分钟。 您将需要使用我编写ldapserver的ldapserver地址以及用户ID和密码,并且用户名是您正在查找的人的SAMAccountName。

如果您在这里查看,您可以执行以下操作:

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