Re: On ADSI and LDAP




"jimt" <nospam> wrote in message
news:u2IBqiR3HHA.536@xxxxxxxxxxxxxxxxxxxxxxx
Ed Crowley [MVP] wrote:
Wouldn't it be easier to do an LDAP search for the samAccountName and
return the distinguishedName attribute?

Can I do that?

The script I am trying to write should work with a list of users (samids)
and for each user get some attributes from AD

something like


myuser = "CN=user1,OU=myou1,DC=mydc1,DC=mydomain,DC=com"

Set objAuser = GetObject("LDAP://"; & myuser)

then retrieve some users attributes

the problem is how can I retrieve the value for myuser using the
samaccountname? I do not know in what OUs my users are located so i
cannot bind to them unless i know their DN?

thank u


Since your purpose is to retrieve other attributes of the user objects, it
would be more efficient to use ADO to query AD for the attributes values.
You would not need to bind to the user objects, which would be slower
(especially if you are doing this for many users). For more on using ADO,
see this link:

http://www.rlmueller.net/ADOSearchTips.htm

Using the code examples in the link, and assuming LDAP syntax, your filter
clause could be similar to:

strNTName = "JSmith"
strFilter = "(sAMAccountName=" & strNTName & ")"

Since the value of sAMAccountName must be unique in the domain, you don't
need to also specify that the object is a user object. You would specify the
attribute values to retrieve in a comma delimited list similar to:

strAttributes = "givenName,sn,displayName,telephoneNumber"

For the names of attributes of user objects, see this link:

http://www.rlmueller.net/UserAttributes.htm

One idea would be to read the names one at a time and query for each user in
a loop. If you do this, bind to the ADO objects before the loop (so they are
only bound once), then in the loop assign the new query to CommandText
property of the ADO Command object and invoke the Execute method to get a
new Recordset object.

Another idea if the list of users is not too long is to query for all
sAMAccountNames at once. The filter clause could be:

strFilter = "(|(sAMAccountName=" & strName1 _
& ")(sAMAccountName=" & strName3 _
& ")(sAMAccountName=" & strName4 _
& ")(sAMAccountName=" & strName5 _
& ")(sAMAccountName=" & strName6 _
& ")(sAMAccountName=" & strName7 _
& ")(sAMAccountName=" & strName8 & "))"

The filter clause can be quite long. I've used similar queries. The only
trick is appending the names in a loop when you read them from the file. An
example could be:
======================
Option Explicit



Dim adoCommand, adoConnection, strBase, strFilter, strAttributes
Dim objRootDSE, strDNSDomain, strQuery, adoRecordset, strName
Dim strFilePath, objFSO, objFile
Dim strCN, strFirst, strLast, strPhone



Const ForReading = 1



' Specify the text file of user NT names.
strFilePath = "c:\Scripts\UserList.txt"

' Open the file for read access.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strFilePath, ForReading)



' Setup ADO objects.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection



' Search entire Active Directory domain.
Set objRootDSE = GetObject("LDAP://RootDSE";)
strDNSDomain = objRootDSE.Get("defaultNamingContext")
strBase = "<LDAP://"; & strDNSDomain & ">"



' Read names from file and construct filter clause.
strFilter = "(|"
Do Until objFile.AtEndOfStream
strName = Trim(objFile.ReadLine)
' Skip blank lines.
If (strName <> "") Then
strFilter = strFilter & "(sAMAccountName=" & strName & ")"
End If
Loop

objFile.Close
strFilter = strFilter & ")"



' Comma delimited list of attribute values to retrieve.
strAttributes = "cn,givenName,sn,telephoneNumber"



' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False



' Run the query.
Set adoRecordset = adoCommand.Execute



' Enumerate the resulting recordset.
Do Until adoRecordset.EOF
' Retrieve values and display.
strCN = adoRecordset.Fields("cn").value
strFirst = adoRecordset.Fields("givenName").Value
strLast = adoRecordset.Fields("sn").Value
strPhone = adoRecordset.Fields("telephoneNumber").Value
Wscript.Echo strCN & "," & strFirst & "," & strLast & "," & strPhone
' Move to the next record in the recordset.
adoRecordset.MoveNext
Loop

' Clean up.
adoRecordset.Close
adoConnection.Close
==============

The program should be run at a command prompt using the cscript host. The
output can be redirected to a text file. If any values could have embedded
commas, you might want to delimit the output values with semicolons instead
of commas, so the text file can be read into a spread*** program.


--
Richard Mueller
Microsoft MVP Scripting and ADSI
Hilltop Lab - http://www.rlmueller.net
--


.