Printout Header
RSS Feed

How to search and find user accounts in Active Directory


In most cases in which I see sample scripts for LDAP searchoperations for Active Directory users, the following LDAP filter is used:

(&(objectClass=user)(objectCategory=person))              <- Inefficient !!

However, this is not the optimal method to search for user accounts. The filter is constructed to cause an unnecessary amount of server power consumption. The reason: The two filter criteria 'objectClass' and 'objectCategory' - thus makes the technical search in the AD database for the server more complex than it ought to be. In domains with a relatively small number of users this fact may not play the major role. But it is very relevant indeed if a directory area isto be searched, in which there are many thousands of user objects.

To use an LDAP filter with only one criterion, fo example this one

(objectClass=user)                  <- Wrong filter for the search for user objects !!

or only this

(objectCategory=person)         <- Wrong filter for the search for user objects !!

is not a good idea neither, because in each case not only users but also computer objects or contacts will be returnedas a result. More difficult to remember, but much effiziernter is a filter that uses the attribute 'samAccountType': For user objects, this attribute always has the value 805306368 - and the attribute is indexed in the AD database for fast search. So , the perfect filter for LDAP search for users object is


(samAccountType=805306368)    <- Efficient filter for user objects :)


The following examples demonstrate the usage of this filter in directory scripts. For a detailed discusion according to LDAP search operations, read the s SelfADSI Tutorial Topic "Searching for LDAP Directory Objects with ADO".


Finding all user accounts in the own domain


This script finds all the Active Directory user accounts in the domain in which the current user is a member of:

ldapFilter = "(samAccountType=805306368)" Set rootDSE = GetObject("LDAP://rootDSE") domainDN = rootDSE.Get("defaultNamingContext") Set ado = CreateObject("ADODB.Connection") ado.Provider = "ADSDSOObject" ado.Open "ADSearch" Set objectList = ado.Execute("<LDAP://" & domainDN & ">;" & ldapFilter & _  ";distinguishedName,samAccountName,displayname,userPrincipalName;subtree") While Not objectList.EOF userDN = objectList.Fields("distinguishedName") logonName = objectList.Fields("samAccountName") On Error Resume Next displayName = "" : displayName = objectList.Fields("displayname") logonNameUPN = "" : logonNameUPN = objectList.Fields("userPrincipalName") On Error Goto 0 WScript.Echo logonName & ";" & logonNameUPN & ";" & displayName & ";" & userDN objectList.MoveNext Wend

Some notes according to this script:

When we want to read the attributes, there is a trick used to prevent runtime errors in case of non existing values. First we set the variable to an empty string, then we try to read the attribute value - the runtime error handling is deactivated for these commands. We don't need this for attributes which are always there. The separating colon (:) is used to execute the two VBScript commands in the same line:

... On Error Resume Next displayName = "" : displayName = objectList.Fields("displayname") On Error Goto 0 ...

Finding all user accounts in the own forest


This script finds all user accounts in the Active Directory forest, in which the current user is a member. Please note that only those attributes can be searched which are also included in the Global Catalog. This affects the structure of the search filter and the list of attributes that are requested in the query:


ldapFilter = "(samAccountType=805306368)" Set aoi = CreateObject("ADSystemInfo") 'evaluate global catalog search base gcBase = aoi.ForestDNSName Set ado = CreateObject("ADODB.Connection") ado.Provider = "ADSDSOObject" ado.Open "ADSearch" Set objectList = ado.Execute("<GC://" & gcBase & ">;" & ldapFilter & _  ";distinguishedName,samAccountName,displayname,userPrincipalName;subtree") While Not objectList.EOF userDN = objectList.Fields("distinguishedName") logonName = objectList.Fields("samAccountName") On Error Resume Next displayName = "" : displayName = objectList.Fields("displayname") logonNameUPN = "" : logonNameUPN = objectList.Fields("userPrincipalName") On Error Goto 0 WScript.Echo logonName & ";" & logonNameUPN & ";" & displayName & ";" & userDN objectList.MoveNext Wend

Finding users in any domain / OU


This script finds all user accounts in the specified domain or OU. Use the suitable LDAP path for your desired domain or container. You could set also other credentials for the search (username and password specified):

searchDN = "DC=example,DC=com" 'insert your own search base container or domain name serverName = "192.168.0.66" 'insert your own DC's name or address userName = InputBox("Enter user name","Credentials") 'you could also just use a static username instead, like "EXAMPLE\userXYZ" password = InputBox("Enter password","Credentials") 'you could also just use a static password instead, like "P@ssw0rd" ldapFilter = "(samAccountType=805306368)" Set ado = CreateObject("ADODB.Connection") ado.Provider = "ADSDSOObject" ado.Properties("User ID") = userName ado.Properties("Password") = password ado.Properties("Encrypt Password") = True ado.Open "ADSearch" Set objectList = ado.Execute("<LDAP://" & serverName & "/" & searchDN & ">;" & ldapFilter & _ ";distinguishedName,samAccountName,displayname,userPrincipalName;subtree") While Not objectList.EOF userDN = objectList.Fields("distinguishedName") logonName = objectList.Fields("samAccountName") On Error Resume Next displayName = "" : displayName = objectList.Fields("displayname") logonNameUPN = "" : logonNameUPN = objectList.Fields("userPrincipalName") On Error Goto 0 WScript.Echo logonName & ";" & logonNameUPN & ";" & displayName & ";" & userDN objectList.MoveNext Wend