Rick
Rick

Reputation: 2308

VBA: LDAP Search through all domains in forest

I have the following VBA code that searches a specific user and outputs the full name, email, and department from the 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

It works with users that are in the main domain. Is there a way to change LDAPdomainName so it can search within all sub domains?

Upvotes: 1

Views: 5707

Answers (1)

Eric Fleischman
Eric Fleischman

Reputation: 1158

The answer will vary slightly based upon your specific forest configuration.

Generally, if you want to search children domains too, you can ask ADSI to do what's called chasing referrals. If you search for ADSI + chasing referrals you'll get tons of hits on this...and depending upon what API you ultimately use, there is an answer for each. Some info on this here: http://technet.microsoft.com/en-us/library/cc978014.aspx

That said, there are some nuances:

  • If you have multiple domains where there is not a single parent for all domains in your forest from a namespace perspective (ex: imagine having a forest with foo.com, bar.foo.com and blech.com...there is no single parent that covers them all) then you either have to do multiple searches or use what is called the phantom root control (where you can pass in non-existing topmost parents which instructs AD to search everyone)
  • Keep in mind that this search will hit DCs all over your forest...one for each domain you chase in to. If you are only searching for a limited set of attributes, you might want to hit a global catalog server instead, which can service information about all of your domains from that one server (ie much faster search as it is all local). To do this you'll need to connect to the global catalog port, which is usually 3268/3269 (the latter being LDAPS).

Upvotes: 1

Related Questions