2012-03-02 66 views
0

我希望改善下面的性能,並返回每個用戶的GUID。改進遞歸Active Directory功能

我已經轉換並修改了code found here,用於遞歸搜索組以獲取所有成員及其詳細信息並將它們添加到類集合中。不過,我還需要捕獲用戶的經理詳細信息,以便爲每個用戶調用兩次AD。這似乎並不高效,因爲許多用戶將擁有相同的經理。從集合類中獲取不同的管理器詳細信息並僅調用這些信息似乎是合乎邏輯的,然後將它們替換爲集合中出現的任何位置。但我不知道這樣做的最佳方式 - 對於所有這些仍然是相當新穎的)

我也希望能夠獲取用戶的GUID,我試圖直接作爲屬性訪問它集合,但它不返回任何東西。

這是我的代碼,我真的很感謝任何意見/建議:) - 或者我一般指出的任何壞習慣! ;)

我使用VS2005和.Net我使用按照JPBlancs的建議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 

代碼,而這個工程,它比我原來的要慢得多,我會實現它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 

回答

1

你可以看看Finding users that are members of two active directory groups。您會發現一種方法,使用LDAP_MATCHING_RULE_IN_CHAIN在一個查詢中從組中遞歸收集用戶。

就th GUID而言,不要忘記列出您希望查詢返回的屬性。要小心,據我所知,GUID將返回INT數組中。

dsLookFor.PropertiesToLoad.Add("objectGUID") 
+0

感謝JPBlanc,這是真正有用的,所以如果我有這個權利,我可以用它來與可能無法在該組中,但任何數量的嵌套子組內直接是一組返回的所有用戶?對不起,如果這聽起來很明顯,但我仍然很新! – SWa 2012-03-04 19:20:58

+0

是的你是對的。 – JPBlanc 2012-03-05 04:06:17

+0

感謝您的回答JPBlanc,但是除非我沒有正確實施這個(很可能;)!!)我已經在上面發佈了我的代碼,你會介意快速查看一下,看看我是否做了任何明顯錯誤的事情? – SWa 2012-03-05 14:23:11