2017-05-31 27 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的建议!