问题描述
我希望改善以下各项的性能,并返回每个用户的GUID。
I'm hoping to improve the performance of the below as well as return the GUID of each user.
我已经转换并修改了,用于递归搜索组以获取所有成员及其详细信息并将其添加到类集合中。但是,我还需要捕获用户经理的详细信息,因此我要为每个用户两次调用AD。这似乎效率不高,因为许多用户将拥有同一位管理员。从集合类中获取唯一的经理详细信息并仅调用它们,然后在集合中的任何地方替换它们,这似乎是合乎逻辑的。不过,我不知道执行此操作的最佳方法-还是所有这些都还很陌生;)
I've converted and modified the code found here for searching through groups recursively to get all the members and their details and adding them to a class collection. However I also need to capture the user's managers details so I'm calling the AD twice for each user. This doesn't seem efficient as many of the users will have the same manager. It would seem logical to get the distinct manager details from the collection class and call only these, then replace them wherever they occur in the collection. I don't know the best way to do this however - still fairly new to all this ;)
我也希望能够获得用户的GUID,我尝试直接访问它作为集合的一个属性,但是它不返回任何内容。
I'd also like to be able to get the user's GUID, I've tried accessing it directly as a property of the collection, but it doesn't return anything.
这是我的代码,我非常感谢任何评论/建议:)-或我一般指出的任何不良习惯! ;)
Here's my code, I'd really appreciate any comments/suggestions :) - or any bad habits I have in general pointing out! ;)
我正在使用vs2005和.Net 2.0
I'm using vs2005 and .Net 2.0
Public Class ADCLass
''' <summary>
''' Calls recursive function to return users in group
''' </summary>
''' <param name="DistListAlias">CN for the Group</param>
''' <returns>Collection of class holding user details</returns>
''' <remarks></remarks>
Public Function GetDistListUsers(ByVal DistListAlias As String) As Collection(Of ADMembers)
Dim path As String = "LDAP://DC=systems,DC=Private"
Dim filter As String
Dim filterFormat As String = "(cn={0})"
Dim sAMAccountFilter As String
filter = String.Format(filterFormat, DistListAlias)
Dim properties As PropertyCollection = GetPropertiesForEntry(path, filter)
sAMAccountFilter = "(|(ObjectClass=Group)(objectCategory=user))"
Dim groupMembers As Collection(Of ADMembers) = New Collection(Of ADMembers)
If Not IsNothing(properties) Then
Dim sAMAccountTypes As Collection(Of Integer) = New Collection(Of Integer)
groupMembers = GetUsersInGroup(properties, groupMembers, sAMAccountFilter)
End If
Return groupMembers
End Function
#Region "GetUsersInGroup"
''' <summary>
''' Recursive function to list all users in group and sub group
''' Returns the sAMAccountName for the Managers
''' </summary>
''' <param name="Properties">Group Properties</param>
''' <param name="groupMembers">Collection fo Users</param>
''' <param name="filter"></param>
''' <returns>Collection of class holding user details</returns>
''' <remarks></remarks>
Private Function GetUsersInGroup(ByVal Properties As PropertyCollection, ByVal groupMembers As Collection(Of ADMembers), ByVal filter As String)
Dim pathFormat As String = "LDAP://{0}"
Dim memberIdx As String = "member"
Dim sAMAccountNameIdx As String = "sAMAccountName"
Dim sAMAccountTypeIdx As String = "sAMAccountType"
Dim personnelNumberIdx As String = "extensionAttribute4"
Dim TelNo As String
Dim prop As Object
Dim managerID As String
Dim manColl As PropertyCollection
If Not IsNothing(Properties(memberIdx)) Then
'Loop through found Members
For Each prop In Properties(memberIdx)
Dim distinguishedName As String = prop.ToString
Dim path As String = String.Format(pathFormat, distinguishedName)
Dim childProperties As PropertyCollection = GetPropertiesForEntry(path, filter)
If Not IsNothing(childProperties) Then
'Check that this is a user
If childProperties(sAMAccountTypeIdx).Value = 805306368 Then
'GetManager ID
managerID = childProperties("manager").Value.ToString
manColl = GetPropertiesForEntry(String.Format(pathFormat, managerID), filter)
managerID = manColl(sAMAccountNameIdx).Value.ToString
'Get Phone Number, if telephone number is null, check mobile, if null
'return ""
If Not IsNothing(childProperties("telephoneNumber").Value) Then
TelNo = childProperties("telephoneNumber").Value.ToString
Else
If Not IsNothing(childProperties("mobile").Value) Then
TelNo = childProperties("mobile").Value.ToString
Else
TelNo = ""
End If
End If
'Add the Properties to the class collection
groupMembers.Add(New ADMembers(childProperties(sAMAccountNameIdx).Value.ToString, _
childProperties("cn").Value.ToString, _
managerID, _
childProperties("Title").Value.ToString, _
TelNo, _
childProperties("mail").Value.ToString))
Else
'Found a group - recurse
GetUsersInGroup(childProperties, groupMembers, filter)
End If
End If
Next
End If
Return groupMembers
End Function
#End Region
#Region "GetPropertiesForEntry"
''' <summary>
''' Gets properties for given user in AD
''' </summary>
''' <param name="path">Distinguished AD name</param>
''' <param name="filter"></param>
''' <returns>Property collection for given user</returns>
''' <remarks></remarks>
Private Function GetPropertiesForEntry(ByVal path As String, ByVal filter As String) As PropertyCollection
Dim rootEntry As New DirectoryEntry(path)
Dim searcher As New DirectorySearcher(rootEntry)
With searcher
.Filter = filter
.PageSize = 5
.ServerTimeLimit = New TimeSpan(0, 0, 30)
.ClientTimeout = New TimeSpan(0, 10, 0)
End With
Dim result As SearchResult = searcher.FindOne
Return result.GetDirectoryEntry.Properties
End Function
#End Region
End Class
代码I正在按照JPBlancs的建议使用,虽然此方法有效,但比我原来的要慢得多,我是否不正确地实施它?
Code I am using as per JPBlancs's suggestion, whilst this works, it is much slower than my original, am I implementing it incorreclty?
Public Sub GetPropertiesForEntry()
Dim rootEntry As New DirectoryEntry("LDAP://DC=d1,DC=d2")
Dim searcher As New DirectorySearcher(rootEntry)
With searcher
.Filter = "(&(memberof:1.2.840.113556.1.4.1941:=CN=grp1,OU=Messaging Groups,OU=Groups,DC=d1,DC=d2)(objectCategory=user))"
.SearchScope = SearchScope.Subtree
.PropertiesToLoad.Add("cn")
.PageSize = 100
.ServerTimeLimit = New TimeSpan(0, 0, 30)
.ClientTimeout = New TimeSpan(0, 10, 0)
End With
Dim results As SearchResultCollection = searcher.FindAll()
For Each result As SearchResult In results
Debug.Print(result.Properties("cn").Item(0).ToString)
Next
End Sub
推荐答案
可以看看在一个查询中从一组中递归收集用户。
Can you have a look to Finding users that are members of two active directory groups. You'll find a method using LDAP_MATCHING_RULE_IN_CHAIN to collect recursively users from a group in one query.
就GUID而言,不要忘记列出您要查询返回的属性。注意,据我所记得,GUID将以INT数组返回。
As far as th GUID is concerned don't forget list the attribute you want the query to return. Be careful, as far as I remember the GUID will return in an INT array.
dsLookFor.PropertiesToLoad.Add("objectGUID")
这篇关于改进递归Active Directory功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!