【问题标题】:Scanning GlobalCatalog via System.DirectoryServices (VB.NET) throws occasional error通过 System.DirectoryServices (VB.NET) 扫描 GlobalCatalog 偶尔会引发错误
【发布时间】:2017-05-31 14:31:27
【问题描述】:

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

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

一些浏览使我认为(有待更正)该问题是由于尝试通过 DirectorySearcher 检索大量记录(在我的情况下大约为 400k)引起的,尽管结果是分页的,并且解决方案可能是使用 System.DirectoryServices.Protocols 切换现有的 System.DirectoryServices 方法。请参阅this SO thread 导致this article

但是,我发现的所有响应,包括上面的链接和其他来自广泛搜索的链接,都只提供 C# 中的代码 sn-ps,并且似乎只查询单个记录(例如,根据特定的 distinctName 检索属性或登录)

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

【问题讨论】:

  • 检查 searcher 是否有 resultsize 属性,并尝试发送 maxint 或任何实际等效的“无限”。

标签: vb.net active-directory directoryservices


【解决方案1】:

感谢维斯帕!

如图所示添加,它似乎不再发生(我相信将 .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

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

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

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

再次感谢 Vesper 的建议!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-14
    相关资源
    最近更新 更多