Delve into the Depths of ADSI

Get ready for Active Directory Services Interface, the powerful scripting tool that helps you manage Active Directory and much more.

Having touched on ADSI briefly last month, we’ll now tackle it in earnest, beginning a series in which I’ll delve deep into this powerful scripting tool. Don’t think this is just for those of you running Windows 2000 across the board. As I pointed out last month, “You can use ADSI to access and change NT information even if Active Directory is not installed.” This is a tool for all of us, NT and Win2K admins alike.

Before we go any deeper, you may want to wait a full hour after eating, because we’re about to go swimming in a sea of unbridled power. Over the next several months, we’re going to discuss ADSI using real-world examples and solving common administrative challenges.

Last month we wrote a script that used ADSI to enumerate namespaces, domains, and resources in a specific domain, concentrating on the WinNT namespace. Since many of you probably work for companies that haven’t yet fully (or even partially) migrated to Windows 2000, we’re going to start by delving deeper into the WinNT namespace. In this way, I hope to give each of you something useful that you can start using today. Fear not, though, because before we’re done, I will move into manipulating Active Directory (using the LDAP namespace). In this way, I hope to give you something to prepare you for when you do migrate to Win2K and Active Directory.

Let’s begin by clarifying some terms we’ll be using over the course of our ADSI series. We’ve already defined namespaces, which are the “top-level” ADSI interfaces. The next level underneath namespaces is containers. A container can be a domain or an individual workstation/server. Each container contains objects such as Users and Groups (and in the case of a domain container, computers). In the final example last month, we enumerated every object (resource) in a domain. In a large organization, this domain container can contain quite a large number of objects. Listing through it every time we need to find something can be incredibly time-consuming. Fortunately, ADSI allows us to filter a container by specific objects. In this way we can list only users, groups, or computers. Here’s how we apply a filter to list all the users in a specified domain:

' ListUsers.vbs
Dim objContainer, colUsers
Set objContainer=GetObject("WinNT://domain")
objContainer.Filter=Array("User")
For Each colUsers in objContainer
WScript.Echo colUsers.Name
Next

If we wanted to list groups or computers, we would simply modify line 4 to read Array (“Group”) and Array (“Computer”) respectively. Since we’re dealing with the WinNT provider, chances are that the domains we’ll be accessing are divided up into account domains and resource domains. This simplifies matters a bit, since account domains contain mostly users and resource domains contain mostly computers. Still, the ability to filter by specific objects can help to reduce your daily aspirin intake.

Of course, filtering is only necessary when listing objects in a container. When you create, modify, or remove objects, you are not required to use a filter. The object type is simply specified during the operation. Let’s add a user to our domain:

' AddUser.vbs
dim objContainer, cslUser, strUser
Set objContainer=GetObject("WinNT://domain")
strUser="CBrooke"
Set clsUser=objContainer.Create("User", strUser)
clsUser.SetInfo

We now have a user called “Cbrooke.” The first argument in the line 5 “objContainer.Create” method specifies the type of object we are creating (a User). The account doesn’t actually get created until we execute the SetInfo method in line 6. This creates the user account and sets the default properties. Let’s put this user into the appropriate groups, shall we? We start by binding to the group object:

Dim objGroup
Set objGroup=GetObject("WinNT://domain/groupname, group")

We add the bound user via the “Group.Add” method. Let’s modify the above script to add and group the user at the same time:

' AddGroupUser.vbs
dim objContainer, objGroup, clsUser, strUser
Set objContainer=GetObject("WinNT://domain")
strUser="CBrooke"
Set clsUser=objContainer.Create("User", strUser)
clsUser.SetInfo
Set objGroup=GetObject("WinNT://domain/MyGroup, group")
objGroup.Add(clsUser.ADsPath)
objGroup.SetInfo

All we’ve really done is taken the original AddUser script and added in the lines where we bind to the group. In line 8, we add the user to the group by passing the clsUser.AdsPath property. This is simply the Distinguished Name of the user, which ADSI uses for reference. You’d think you should be able to just pass the clsUser.Name property, but you can’t. Not with ADSI.

Homework

For next month, use what you’ve learned about manipulating users and groups with ADSI, to write a script to force a password reset on every user in the domain. Don’t forget: ADSI providers are case-sensitive, and I will be grading on spelling.

About the Author

Chris Brooke, MCSE, is a contributing editor for Redmond magazine and director of enterprise technology for ComponentSource. He specializes in development, integration services and network/Internet administration. Send questions or your favorite scripts to [email protected].

Featured