VBA:LDAP搜索林中的所有域

时间:2012-08-29 13:02:24

标签: vba dns active-directory subdomain

我有以下VBA代码,用于搜索特定用户并从Active Directory输出全名,电子邮件和部门:

 Public Type LDAPUserInfo
    FullName As String
    Email As String
    Department As String
    AccountStatus As String
 End Type


Function FindUser(ByVal username) As LDAPUserInfo
 On Error GoTo Err

 Dim objRoot As Variant
 Dim LDAPdomainName As String
 Dim cn As Variant
 Dim cmd As Variant
 Dim rs As Variant
 Dim LDAPUserInfo As LDAPUserInfo

 Set cn = CreateObject("ADODB.Connection")
 Set cmd = CreateObject("ADODB.Command")
 Set rs = CreateObject("ADODB.Recordset")

 Set objRoot = GetObject("LDAP://RootDSE")
 LDAPdomainName = objRoot.Get("defaultNamingContext") 'Contains the distinguished name for the domain of which this directory server is a member.
'http://msdn.microsoft.com/en-us/library/windows/desktop/ms684291(v=vs.85).aspx

 cn.Open "Provider=ADsDSOObject;"

 cmd.activeconnection = cn
 'cmd.commandtext = "SELECT ADsPath FROM 'LDAP://" & Domain & "' WHERE sAMAccountName = '" & UserName & "'"
 'To see all attributes names available, connect with Active Directory Explorer and add to Select.
 cmd.commandtext = "SELECT cn, mail, physicalDeliveryOfficeName, userAccountControl  FROM 'LDAP://" & LDAPdomainName & "' WHERE sAMAccountName = '" & username & "'"
 Set rs = cmd.Execute

    Debug.Print rs("cn") & " E-mail: " & rs("mail") & " Dept: " & rs("physicalDeliveryOfficeName")
    LDAPUserInfo.FullName = Nz(rs("cn"), "")
    LDAPUserInfo.Email = Nz(rs("mail"), "")
    LDAPUserInfo.Department = Nz(rs("physicalDeliveryOfficeName"), "")

   FindUser = LDAPUserInfo


If Not rs Is Nothing Then rs.Close
If Not cn Is Nothing Then cn.Close

Exit_Err:

 Set rs = Nothing
 Set cmd = Nothing
 Set cn = Nothing
 Set objRoot = Nothing
 Exit Function

Err:

 If Err <> 0 Then
    MsgBox "Error connecting to Active Directory Database: " & Err.Description & vbCrLf & _
            "User: " & username, , "Error: " & Err.Number
 Else
    If Not rs.BOF And Not rs.EOF Then
        rs.MoveFirst
        MsgBox rs(0)
    Else
        MsgBox "Not Found"
    End If
 End If
 Resume Exit_Err

End Function

适用于主域中的用户。有没有办法更改LDAPdomainName,以便它可以在所有子域中进行搜索?

1 个答案:

答案 0 :(得分:1)

根据您的特定森林配置,答案会略有不同。

通常,如果您也想搜索子域,您可以要求ADSI执行所谓的追逐推荐。如果您搜索ADSI +追逐推荐,您将获得大量的点击...并且根据您最终使用的API,每个都有答案。 有关此内容的一些信息:http://technet.microsoft.com/en-us/library/cc978014.aspx

那说,有一些细微差别:

  • 如果您有多个域,从命名空间的角度来看,林中的所有域都没有单个父域(例如:想象有一个带有foo.com的森林,bar.foo.com和blech.com ......那里并非所有单一的父母都覆盖它们然后你要么做多次搜索,要么使用所谓的幻像根控件(你可以传入不存在的最顶级父母,指示AD搜索每个人)。
  • 请记住,此搜索将在您的森林中点击DC ...您追逐的每个域都有一个。如果您只搜索一组有限的属性,则可能需要访问全局编录服务器,该服务器可以从该服务器提供有关所有域的信息(即搜索速度更快,因为它全部是本地的)。为此,您需要连接到全局编录端口,通常是3268/3269(后者是LDAPS)。