vb.net - 当用户没有组时,在 Active Directory 中搜索特定组的成员失败
问题描述
以下代码应该遍历活动目录中的所有用户并找到特定组中的每个人。一旦获得用户,它会将他们添加到数据表中,该数据表将成为最终导出到 Excel 的 gridview 的源。
但是,在运行和单步执行时,我注意到它在某个没有组的用户上停止了。我尝试添加一个条件语句来跳过该实例,但它不起作用,当它找到没有组的用户时,代码仍然停止运行。
有人可以告诉我我可以做些什么不同的事情吗?警告:这是我继承的一个遗留站点,对活动目录知之甚少,并且是一个新手 vb 编码器。
Dim entry As DirectoryEntry = New DirectoryEntry("LDAP://DOMAIN.EDU", "USERNAME", "PASSWORD", AuthenticationTypes.Secure)
Dim search As DirectorySearcher = New DirectorySearcher(entry) With {
.Filter = "(&(objectCategory=User)(objectClass=person))",
.PageSize = 4000
}
search.PropertiesToLoad.Add("userPrincipalName").ToString
search.PropertiesToLoad.Add("name").ToString
Dim mySearchResultColl As SearchResultCollection = search.FindAll
Dim results As DataTable = New DataTable
results.Columns.Add("User ID")
results.Columns.Add("Full Name")
Dim CurrRow = 0
For Each sr As SearchResult In mySearchResultColl
Dim dr As DataRow = results.NewRow
Dim de As DirectoryEntry = sr.GetDirectoryEntry
!!!! line below is the problem !!!!
If de.Properties("memberOf") IsNot Nothing AndAlso de.Properties("memberOf").Value.ToString = "CN=MYGROUP,OU=Security Groups,OU=Students,DC=DOMAIN,DC=edu" Then
dr("User ID") = de.Properties("userPrincipalName").Value
dr("Full Name") = de.Properties("name").Value
results.Rows.Add(dr)
de.Close
End If
Next
gvNot.DataSource = results
gvNot.DataBind()
gvNot.Visible = True
gvAgreed.Visible = False
ExportToExcel("notagreed", gvNot)
解决方案
我不确定您所说的“停止”是什么意思,但您可以对其进行更改,使其性能更好并解决您遇到的任何问题。
- 这个循环将永远持续下去,因为您必须检查域中的每个用户。如果您只想要特定组中的用户,那么您可以通过只询问该组的成员来加快速度。您可以通过在
memberOf
属性的查询中添加条件来做到这一点。这样,您只会得到您关心的结果。
(请注意,如果您的林中有多个域,则用于查找成员可能无法按您希望的方式工作。我在这里memberOf
写过。但如果您只有一个域,那就没问题了。)
在循环中,不要
DirectoryEntry
为每个结果创建一个,因为这将迫使它返回 AD 并再次请求对象的属性,即使您已经在搜索结果中获得了所需的内容。因此,请改用SearchResult
对象中的值。
由于实现限制,SearchResultCollection 类在垃圾回收时无法释放其所有非托管资源。为防止内存泄漏,您必须在不再需要 SearchResultCollection 对象时调用 Dispose 方法。
所以你应该把它放在一个Using
子句中。
- 我也不确定你为什么
ToString
在PropertiesToLoad.Add
不使用返回值时调用。你可以删除它。
这一切都在一起:
Dim entry As DirectoryEntry = New DirectoryEntry("LDAP://DOMAIN.EDU", "USERNAME", "PASSWORD", AuthenticationTypes.Secure)
Dim search As DirectorySearcher = New DirectorySearcher(entry) With {
.Filter = "(&(objectCategory=User)(objectClass=person)(memberOf=CN=MYGROUP,OU=Security Groups,OU=Students,DC=DOMAIN,DC=edu))",
.PageSize = 4000
}
search.PropertiesToLoad.Add("userPrincipalName")
search.PropertiesToLoad.Add("name")
Dim results As DataTable = New DataTable
results.Columns.Add("User ID")
results.Columns.Add("Full Name")
Dim CurrRow = 0
Using mySearchResultColl As SearchResultCollection = search.FindAll
For Each sr As SearchResult In mySearchResultColl
Dim dr As DataRow = results.NewRow
dr("User ID") = sr.Properties("userPrincipalName")(0)
dr("Full Name") = sr.Properties("name")(0)
results.Rows.Add(dr)
Next
End Using
gvNot.DataSource = results
gvNot.DataBind()
gvNot.Visible = True
gvAgreed.Visible = False
ExportToExcel("notagreed", gvNot)
我没有看到您CurrRow
在任何地方使用它,但我留下了它以防您在此处未显示的其他代码中使用它。
推荐阅读
- ruby-on-rails - nil:NilClass 的未定义方法“课程”
- javascript - 在 Chrome 扩展中分离像 Font Face Ninja 或 CSS Peeper 这样的面板?
- reactjs - React:useContext,如何从外部组件中检索它?
- jquery - jquery html() 函数调用后返回上一页
- javascript - 用于重试失败调用和取消先前调用的 javascript 模式
- redis - Redis官网的查询教程在哪里?
- excel - 范围值的类型不匹配错误,无法弄清楚原因
- javascript - 如何将 span 元素的内容更改为变量的内容
- excel - 从循环中排除打开的工作簿/特定文件
- android-emulator - 我正在尝试在 Android Studio 上运行一个程序,但是会弹出一个模拟器错误