2017-05-31 41 views
0

目標:創建一個簡單的VB.NET應用程序,以便使用基本篩選器(僅限於預定義屬性)掃描GlobalCatalog,並將結果寫入文本文件。通過System.DirectoryServices(VB.NET)掃描GlobalCatalog會引發偶然錯誤

方法:以下現有代碼 - 這個「作品」,但偶爾拋出一個異常:「System.DirectoryServices.SearchResultCollection.ResultsEnumerator.MoveNext():更多數據可用」

一些瀏覽使我認爲(可以糾正),該問題是由嘗試通過DirectorySearcher檢索大量記錄(在我的案例中大約爲400k)引起的,儘管結果是分頁的,並且該解決方案可能是將現有的System.DirectoryServices方法切換爲一些利用System.DirectoryServices.Protocols。見this SO thread導致this article。然而,我發現的所有回覆,包括上面的鏈接和其他來自廣泛搜索的迴應,都只在C#中提供代碼片段,而且似乎只查詢單個記錄(例如,基於特定的distinguishedName或登錄名檢索屬性)

我需要使用VB.NET儘快且儘可能高效地檢索一噸記錄。我喜歡DirectoryServices方法,因爲它使我能夠輕鬆處理GlobalCatalog,而無需提供域或密碼 - 我可以直接跳到搜索器並開始指定過濾器和屬性。它通常有效 - 但我需要它每次工作。

任何人都可以建議我如何適應這個代碼來規避偶爾的異常,並以最好的方式撤回我需要的所有數據?

Imports System.DirectoryServices 

Public Sub ScanGlobalCatalog() 

    Dim searcher As DirectorySearcher = ActiveDirectory.Forest.GetCurrentForest.FindGlobalCatalog.GetDirectorySearcher 

    Try 
     With searcher 
      .Filter = "(&(|(objectClass=user)(objectClass=group))(proxyAddresses=*))" 
      .PageSize = 1000 
      .SearchScope = SearchScope.Subtree 
      .CacheResults = False 
      .PropertiesToLoad.Add("sAMAccountName") 
      .PropertiesToLoad.Add("distinguishedName") 
      .PropertiesToLoad.Add("displayName") 
      .PropertiesToLoad.Add("proxyAddresses") 
     End With 

     For Each result As SearchResult In searcher.FindAll() 
      Dim properties As ResultPropertyCollection = result.Properties 
      Dim sAMAccountName As ResultPropertyValueCollection = properties("sAMAccountName") 
      Dim distinguishedName As ResultPropertyValueCollection = properties("distinguishedName") 
      Dim displayName As ResultPropertyValueCollection = properties("displayName") 
      Dim proxyAddresses As ResultPropertyValueCollection = properties("proxyAddresses") 

      ' Check/process/write each property to the output file... 
     Next 
    Catch ex As Exception 
     ' Do something... 
    End Try 
End Sub 
+0

CHeck如果'searcher'有'resultsize'屬性,並且嘗試發送一個maxint或者任何實際的「unlimited」等價物。 – Vesper

回答

0

維斯帕謝謝!

添加如圖所示,它似乎並沒有被更多的發生(我相信.SizeLimit設置爲0,等同於「無限」,但再一次,開放給那些比我更多的知識校正...)

With searcher 
    .Filter = "(&(|(objectClass=user)(objectClass=group))(proxyAddresses=*))" 
    .PageSize = 1000 
    .SizeLimit = 0 
    .SearchScope = SearchScope.Subtree 
    .CacheResults = False 
    .PropertiesToLoad.Add("sAMAccountName") 
    .PropertiesToLoad.Add("distinguishedName") 
    .PropertiesToLoad.Add("displayName") 
    .PropertiesToLoad.Add("proxyAddresses") 
End With 

已經在15分鐘的時間間隔內將腳本作爲服務運行了最近20個小時左右,並且我可以在事件日誌中看到5或6個「失敗」 - 但是,之前這會導致致命終止(該服務只會停止);現在它只是報告異常並再次嘗試下一次迭代。

的失敗都聚集在一起,並且在同一服務(連續相同小時/小時半的時間內「運行」)已經不間斷運行和無差錯的大約15小時了,領導讓我懷疑那些失敗可能正好在服務器上進行某種維護或某些記錄更新中讀取,這是拋出異常。再次歡迎對此行爲有任何見解或意見。

但是我可以忍受這種偶然的例外,只要腳本一般運行良好,並且在出現時不會永久性失敗。

再次感謝Vesper的建議!