用户没有组时,无法在Active Directory中搜索特定组的成员

时间:2019-09-18 21:58:31

标签: 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)

2 个答案:

答案 0 :(得分:1)

我不确定“停下来”是什么意思,但是您可以对其进行更改,使其表现更好,并解决所有问题。

  1. 由于您必须检查域中的每个用户,因此此循环将永远进行。如果只希望特定组中的用户,则可以通过仅询问该组的成员来加快速度。为此,您可以在查询中为memberOf属性添加条件。这样,您只会得到自己关心的结果。

(请注意,如果您的林中有多个域,则使用memberOf查找成员可能无法按照您想要的方式工作。我写了here。但是,如果您只有一个域,那就可以了。)

  1. 在循环中,请勿为每个结果创建一个DirectoryEntry,因为这将迫使它返回AD并再次请求该对象的属性,即使您已经知道了什么您需要在搜索结果中。因此,请改用SearchResult对象中的值。

  2. documentation for SearchResultCollection说:

  

由于实施限制,当进行垃圾回收时,SearchResultCollection类无法释放其所有非托管资源。为了防止内存泄漏,当不再需要SearchResultCollection对象时,必须调用Dispose方法。

因此,您应该将其放在Using子句中。

  1. 我也不确定为什么不使用返回值时为什么在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,但是如果您在其他未在此处显示的代码中使用它,我将其保留了。

答案 1 :(得分:0)

尝试将String.Equals函数与StringComparer.OrdinalIgnoreCase参数一起使用,而不要使用equals运算符。 还有什么错误?