I work in a network that contains a single forest made
up of many Active Directory (AD) domains. I need to verify that a user account
exists and in what domain it exists. I know I can use Active Directory Users
and Computers to find an account. How can I script this task instead?
You can accomplish this task by writing a script that queries a global catalog server in your forest. Because each global catalog server in a forest contains a partial replica of all objects in all domains within the forest, it's the best place for locating AD objects such as user accounts. Listing 1, shows how you can use the ADSI OLE DB provider to search a global catalog server in a forest for a user account whose common name (cn attribute) begins with the letters eth. To make this script a bit more dynamic, I bind to the rootDSE object.
The rootDSE object contains the base Directory System Agent (DSA) information from any domain controller in the domain. DSA information includes data such as the current DNS host name and the various naming contexts in an AD implementation, such as the default schema, and configuration naming contexts. The code at callout A in Listing 1 demonstrates how to bind to the rootDSE, retrieve values from this object (in this case, the script retrieves the distinguished name of the forest, which is stored in the rootDomainNamingContext), and create a variable containing an AdsPath that uses the GC moniker. The GC moniker instructs the script to connect to any domain controller serving as a global catalog server. Under the covers, the GC moniker makes a connection request by using port 3268, which is the listening port for all AD global catalog servers. The actual bind operation performs authentication to an available global catalog server by using the credentials of the currently logged-on user.
The next section of the script demonstrates how to set up a search operation. The most interesting part is constructing the value passed to the CommandText property, which you can see in callout B of Listing 1. The value passed to the property includes four parts:
- The AdsPath to a global catalog. This is the part of the command that contains information about where to start the search operation. In this case, we're starting at the root of the forest.
- The LDAP filter to limit results. In this case, the filter limits results to user accounts that have a name starting with the value stored in the commonNamePart variable.
- The attribute or attributes to return in the result set. In this case, limit the returned results to the distinguishedName attribute of any user account meeting the search criteria defined by the LDAP filter.
- How many levels to search— base, onelevel, or subtree. In this case, the code performs a subtree search to return results from the entire directory starting at the specified AdsPath and searching to the bottom-most domain in the forest.
The last part of the script simply iterates any returned results and displays the distinguished name of any user account meeting the specified criteria. The code download for this article contains a completed Windows Script File (WSF) version of the script you see in Listing 1. I strongly recommend that you download the script sample rather than using the simplified code that Listing 1 shows. The code download demonstrates how to pass in any attribute for your search operation, such as a user's first name (givenName attribute) or last name (sn attribute) rather than using the cn attribute in Listing 1. To call the WSF script, use the following example syntax:
Finduser.wsf /attrib:sAMAccountName =ewilansky