SolutionBase: Automate Active Directory operations with ADSI

For working with Active Directory, the best scripting option is usually ADSI, as this article demonstrates.

As most network administrators know, scripting is a powerful tool that can significantly reduce the administrative workload by automating processes that would otherwise demand hours of manual effort. Building on Visual Basic Scripting Editing (VBS), for instance, Windows Management Instrumentation (WMI) can automate literally thousands of operations related to the Windows operating system and the hardware it resides on.

As it turns out, there is another scripting technology that can be used specifically to automate Active Directory operations: Active Directory Service Interfaces (ADSI). Using ADSI, you can accomplish virtually any task you might otherwise carry out with the Active Directory GUI interface, such as creating, deleting, or modifying directory objects (containers, users, groups, etc.). In addition, ADSI can be used to quickly obtain information by querying the directory.

I'm going to introduce ADSI and cover the basics of using it to carry out Active Directory operations.

Editor's note
In case you missed it, Allen Rouse recently wrote a three-part series on WMI scripting:
"Automate Windows administration with WMI scripting"
"Delve deeper into WMI scripting for Windows administration"
"Learn how to implement WMI in the Windows enterprise"

Binding to the directory
Just as you would use the Visual Basic GetObject method to bind to WMI, you'll use GetObject to bind to the directory, which is based on the Lightweight Directory Access Protocol (LDAP). In an ADSI script, you must first specify the LDAP provider, which is actually a file named adsldp.dll, using the prefix "LDAP:" in the same way you would use "Winmgmts:" in a WMI script. In addition, you must specify a path to a directory object, such as a domain, organizational unit, group, or user. The LDAP provider in conjunction with the path to a directory object is called the ADsPath. In this example, we're binding to the Marketing organizational unit in the domain

First of all, notice that the entire ADsPath is enclosed in parentheses and quotations marks. As with all scripts, you should type your ADSI script in an ASCII text editor such as Notepad, because by default Microsoft Word will create smart quotes, which the scripting host will not recognize. Second, notice how we've designated the object path, the OU, and the domain name using a two-letter designation and an equal sign for each element. This designation is referred to as the distinguished name. The two-letter designation is called the Attribute Type and is used with what we call an Object Class, which simply refers to a specific container or leaf object, as shown in Table A.

Table A
Class Object Attribute Type
User cn
Group/Container Cn
organizationalUnit Ou
Domain Dc

If, for instance, we wanted to bind to a username Mary in the Managers group in the Finance OU of the domain, we would use this ADsPath.

In addition to users and groups, the cn attribute type also refers to containers, such as "Users," "Computers," "Domain Controllers," etc.

Beyond binding
As you would probably expect, once you bind to an object in Active Directory, you can perform one of four basic operations, each of which uses a specific method, as laid out in Table B.

Table B
Operation Method
Read Get
Create Create
Modify Put
Delete Delete

If you want to use any of these methods, you'll also need to provide further information (such as "Create what?") in the form of parameters. Let's say that you want to create a username MSmith in the Marketing OU of We would use this code to do that.

The first two lines tell the script to bind to Active Directory and then create a User object class with the common name of MSmith. The next two lines probably look a little odd. Here's what they're doing: For a user, there are many possible attributes that can be entered and stored in the Active Directory database (as seen in User properties), such as phone number, first name, office, etc. Of all those attributes, only one—the account name, or "sAMAccountName"—is mandatory. So line three uses the Put method to modify an attribute of the user that line two created. Of course, we could specify many other attributes as well.

Finally, line four is necessary to commit a modification (creating an object or modifying an attribute or both) to Active Directory, using a method called SetInfo. Without this, the script would run without making any changes to Active Directory.

We can also use the Get method to read the attributes of an Active Directory object. Let's say we want to display the description attribute of the Marketing OU. We would use this code.

Root Directory Service Entry
Nowhere in the above scripting examples do we specify the name of a server. This is because ADSI supports "serverlessbinding," which means that we don't have to hard-code the name of a domain controller. By the same token, we don't have to hard-code the AdsPath either. Instead, we can bind to the root of the directory, known as the Root Directory Service Entry (rootDSE), and use its attributes to bind to the current domain.

The AdsPath of the current domain is found in an attribute of the rootDSE called defaultNamingContext. By "current domain," we mean the domain in which the client is logged on. Let's say that the current domain is This code would bind to it without hard-coding it.

First we bind to the rootDSE. Next, we use the Get method to access the defaultNamingContext attribute and assign that to a string variable. Finally, we create a reference to the domain using that string variable. In this case, the string variable strADsPath will have the value LDAP://DC=westcoast, DC=acme, DC=com.

The value of binding to the rootDSE is that the same script will run regardless of what the current domain is. As a practical example, let's say that we want to test a certain application in our Active Directory lab, and we want to create 500 users, named User1, User2, etc., in each of three domains. You can imagine how long that would take using the GUI. On the other hand, this script, which will run in each of the three domains, will quickly accomplish the task by binding to the Users container in the current domain.

After the basics
There is, of course, a great deal more to ADSI scripting than what we've covered in this article. In my next article, I'll discuss searching the Active Directory database using ActiveX Data Objects (ADO).

Further reading
For more information on ADSI, check out "Using Active Directory Service Interfaces" on Microsoft's MSDN Web site.