目标:创建一个简单的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
CHeck如果'searcher'有'resultsize'属性,并且尝试发送一个maxint或者任何实际的“unlimited”等价物。 – Vesper