Mr. Script
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.
- By Chris Brooke
- 10/01/2000
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].