【发布时间】:2012-03-02 14:11:58
【问题描述】:
我希望提高以下性能并返回每个用户的 GUID。
我已经转换和修改了 code found here 以递归地搜索组以获取所有成员及其详细信息并将它们添加到类集合中。但是,我还需要捕获用户的经理详细信息,因此我为每个用户调用了两次 AD。这似乎效率不高,因为许多用户将拥有相同的经理。从集合类中获取不同的管理器详细信息并仅调用它们,然后在集合中出现的任何位置替换它们似乎是合乎逻辑的。然而,我不知道最好的方法——这对这一切来说还是相当新的;)
我还希望能够获取用户的 GUID,我尝试将其作为集合的属性直接访问,但它不返回任何内容。
这是我的代码,我非常感谢任何 cmets/建议 :) - 或者我一般指出的任何坏习惯! ;)
我正在使用 vs2005 和 .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
我根据 JPBlancs 的建议使用的代码虽然有效,但比我原来的要慢得多,我是否执行不正确?
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
【问题讨论】:
标签: vb.net recursion active-directory