通过System.DirectoryServices(VB.NET)扫描GlobalCatalog偶尔会引发错误

通过System.DirectoryServices(VB.NET)扫描GlobalCatalog偶尔会引发错误,vb.net,active-directory,directoryservices,Vb.net,Active Directory,Directoryservices,目标:创建一个简单的VB.NET应用程序,使用基本过滤器扫描GlobalCatalog,并将结果写入文本文件,该过滤器仅限于预定义的属性 方法:下面的现有代码-此“有效”,但偶尔会引发异常:“System.DirectoryServices.SearchResultCollection.ResultsEnumerator.MoveNext():更多数据可用” 一些浏览让我认为(有待纠正)问题是由于试图通过DirectorySearcher检索大量记录(在我的案例中大约为400k)造成的,尽管结果

目标:创建一个简单的VB.NET应用程序,使用基本过滤器扫描GlobalCatalog,并将结果写入文本文件,该过滤器仅限于预定义的属性

方法:下面的现有代码-此“有效”,但偶尔会引发异常:“System.DirectoryServices.SearchResultCollection.ResultsEnumerator.MoveNext():更多数据可用”

一些浏览让我认为(有待纠正)问题是由于试图通过DirectorySearcher检索大量记录(在我的案例中大约为400k)造成的,尽管结果已分页,解决方案可能是将现有的System.DirectoryServices方法转换为使用System.DirectoryServices.Protocols的方法。请参阅导致

然而,我找到的所有响应,包括上面的链接和其他广泛搜索的响应,都只提供C#中的代码片段,并且似乎只查询单个记录(例如,根据特定的区分名称或登录名检索属性)

我需要使用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
谢谢Vesper

如图所示添加,似乎不再发生(我相信将.SizeLimit设置为0等于“无限”,但同样,比我知识更丰富的人可能会进行更正…)

在过去20小时左右的时间里,脚本作为服务以15分钟的间隔运行,我可以在事件日志中看到5或6个“失败”-但是,以前这会导致致命的终止(服务将简单地中断);现在它只报告异常,并在下一次迭代中重试

故障聚集在一起(在相同的小时/半内连续“运行”),并且相同的服务已连续运行约15个小时且无错误,这让我怀疑这些故障可能与服务器上正在执行的某种维护或引发异常的某种记录更新中间读取同时发生。同样,我们欢迎对这种行为有任何见解或意见

但我可以忍受像这样的“偶尔”异常,只要脚本运行正常,并且在出现时不会永久崩溃


再次感谢Vesper的建议

检查
searcher
是否具有
resultsize
属性,并尝试发送maxint或任何实际等效的“unlimited”属性。
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