Manage Directory Resources with Active Directory Services Interface

You don't need different SDKs or different APIs to program for multiple network environments.

Sakari Kouti

October 31, 1997

13 Min Read
ITPro Today logo

Access and manage user accounts and network resources, no matter what network environment they come from

Do you want to use scripting or Visual Basic (VB) to enhance your useradministration and network resource management? Would you like to use a Ccompiler to create utilities that work without modification on both Windows NT and NetWare? Do you want to add 200 user accounts with proper settings in a batch run or print a customized report of your users?

In February, Microsoft released a specification that makes these tasks possible: Active Directory Service Interfaces (ADSI) 1.0. ADSI is not a multivendor or Internet Engineering Task Force (IETF) standard; the copyright belongs solely to Microsoft. With ADSI, you can manage the resources in your directory services--and it doesn't matter which network environments those resources come from.

ADSI works with true directory services, such as NetWare 4.x's NovellDirectory Services (NDS) and NT 5.0's Active Directory (AD). ADSI also workswith network environments that don't have a directory service, such as NetWare3.x (instead, its Bindery stores user accounts and other objects) and NT 4.0(instead, its Security Accounts Manager--SAM--stores the user database anddomain models). Of course, you need an ADSI provider for all these environments.

When you have a true directory service, you can create directory-enabledapplications with ADSI, whether you are an inhouse developer or independentsoftware vendor (ISV). These applications go beyond network administration. They use the directory service as a distributed information store toadd value to current networked applications.

How does ADSI work? NT, NetWare, and other network operating systems havenative APIs for accessing and managing network resources. ADSI just puts auniform layer on top of the native APIs so that you don't need to use differentsoftware development kits (SDKs) or learn different APIs to program for multiplenetwork environments. ADSI abstracts the objects and interfaces of theunderlying directory services and creates component object model (COM) objectsand interfaces for you to use.

Using ADSI might sound difficult, but it's not. You are probably alreadyfamiliar with part of ADSI's technology: COM. ADSI uses the same COM technologyas distributed component object model (DCOM) and ActiveX components. You justneed to learn about those technological areas that you might not be too familiarwith: the ADSI environment and ADSI objects.

The ADSI Environment
Both the ADSI application and provider run on your workstation. The targetserver does not need any ADSI support or installation. The server just receivesnative calls. The main platform for the 32-bit ADSI program is currently NT 4.0,although ADSI also supports Windows 95, as Figure 1 shows. ADSI talks to fourdifferent providers: ADSNW.DLL for NetWare 3.x, ADSNDS.DLL for NetWare4.x, ADSNT.DLL for NT 4.0, and ADSLDP.DLL for NT 5.0 and LightweightDirectory Access Protocol (LDAP) 2.0. These providers convert ADSI calls toWin32 API, NetWare, or LDAP calls.

Although you can use ADSI with different networks, it has the closestrelationship with NT 5.0's AD. ADSI's and AD's terminology, design, structure,and name are similar. ADSI will be the primary interface for programming to AD;Messaging API (MAPI) and the traditional C language API for LDAP will besecondary.

You can use VB 4.0 (32-bit version), VB 5.0, Visual C++ 4.2, and Visual J++with the Java Virtual Machine (JVM) to develop applications. According toMicrosoft, you can also use any other application development tools that bindand invoke interfaces in COM objects or act as an Object Linking and Embedding(OLE) automation controller. For example, you can use ADSI with NT 5.0 WindowsScripting Host (WSH) to develop Visual Basic Script (VBScript) batches orscripts (see the sidebar "Use ADSI with WSH," page 164).

ADSI's Object Architecture
You won't find ADSI's object architecture complicated, but you might find itconfusing because every element in the network directory service is referred toas an object. The object referral process begins when the network directoryservice abstracts its resources by creating objects to represent them. So, forexample, users, servers, and printers become objects in the directory service(NDS or AD). ADSI, in turn, abstracts these NDS and AD objects into COM objects,as shown in Figure 2.

AD COM objects include dependent objects. Dependent objects are COM objectsthat represent common functions, such as collection handling. Because you canaccess dependent objects only through their host AD objects, I will not discussthem further.

AD COM objects represent elements in the underlying directory service. Twotypes exist: AD leaf objects and AD container objects. If an object can containanother object--just like an electronic folder can contain an electronicfile--the object is an AD container object (herein referred to as simply container).If an object cannot house another object--just like a file cannot contain afolder--the object is an AD leaf object (or just leaf). Simply put,containers can house leafs, but leafs cannot house containers. Table 1 containsADSI standard containers and leafs.

A container isn't limited to holding leafs. Just like an electronic foldercan contain other folders, a container can hold other containers. For example,containers house AD Schema containers, which play an important role in ADSI. AnAD Schema container holds the objects that define the schema for a particularpart of a directory service. This container houses three different types ofobjects: AD Schema class objects, AD Property objects, and AD Syntax objects.

AD Schema class objects represent the different types, or classes, ofelements in a directory service. One AD Schema class object exists for eachtype, such as user, computer, group, and organization. The AD Schema classobject tells which properties are mandatory and which are optional for thecorresponding object type. For example, the AD Schema class object for usermight have a mandatory property of user name and an optional property of faxnumber. The AD Schema class object also tells whether the object's class isderived from other classes (and thus would support also their properties).

The AD Property object represents one property of the AD Schema classobject. Thus, in this example, you need two AD Property objects: one torepresent the user name and the other to represent the fax number. If two ADSchema class objects have the same property, they share the AD Property object.For example, if the AD Schema class objects of user and organization both havethe property of fax number, only one AD Property object of fax number willexist.

Each property uses a syntax, which is represented by the AD Syntax object.So, in this example, you need two AD Syntax objects: one to represent the stringsyntax of the name property and another to represent the fax number syntax ofthe fax number property.

The AD Schema class objects define where containers and leafs belong. A given namespace permits only certain types of containers and certain types of leafs. Similarly, each type of container permits only certain types of containers and leafs. Thus, the schema are the rules of the directory service database because they define what information the database can store.

The schema in NT 5.0's AD and NetWare 4.0's NDS are extensible. You candefine new object classes or redefine existing object classes. Applications arenumerous, but one traditional example is to add payroll information to userobjects.

NT 4.0 and NetWare 3.0, however, have locked schema. With fixed objectclasses, only the directory service provider (e.g., Microsoft and Novell) hasthe ability to add objects that are not in the standard ADSI object set.

It's Time to Start
Now that you know about ADSI's environment and object architecture, you canstart experimenting with ADSI. But first, you need to download it from To create programs orscripts with ADSI, you need the several-megabyte SDK, which includes the ADSIspecification (a 100-page Word document). Then you need the 500KB-compressedruntime libraries and possibly a patch for them. You must install theselibraries in each workstation that will execute ADSI applications. (NT 5.0 willinclude these runtime libraries.)

After you install the downloaded files, you need to enable VB to use ADSI.In VB 5.0, simply select Project/References and check Active DS Type Library inthe list of references. In VB 4.0, you first need to use the Tools menu to addthe type library ActiveDS.Tlb (in System32 folder) to your Project menu. Thesesteps let you use AD COM objects in your application.

For the sake of simplicity, the examples from this point on will focus onhow to implement ADSI on NT rather than NetWare. The examples will deal mostlywith users as the objects, but the same principles apply if the objects areprinters, services, or other elements.

Browse a Little, Report a Lot
Once you have installed the necessary files, you can browse with DSBrowse,which is in the SDK. This sample application browses your namespaces and showsobjects and properties in them.

Next, you can run several reports that will help you learn about yourdirectory services. The reports that are most useful are the namespaces, user,and property reports.

Namespaces correspond to the four providers: WinNT, NWCOMPAT, NDS, andLDAP. Table 2 (page 166) gives examples of names in different namespaces. Tocheck which namespaces are installed in your computer system, you can use thiscode:

Dim NamespacesObj as IADs Namespaces

Dim obj as IADs

Set NamespacesObj = GetObject("ADS:")

For Each obj in NamespacesObj

Debug.Print obj.Name

Next obj

This exercise not only tells you which namespaces are available, but alsoshows you many of the steps in ADSI programming. First, you define the variableswith Dim statements, usually including the letters IADs. Next you use GetObjectto instantiate (or create) the object based on the path given. GetObject is anADSI helper function and is not to be confused with a VB function with the samename. Then on the same line, you assign the object to a variable, after whichyou can finally use it. If your object has many elements, you can walk throughthem with the For Each loop.

If you want to make a report containing all users and their home directory,you first need to use the code just given to find out the namespaces. (If youwant, you can skip this step and just assume that you are using NT with theWinNT: namespace. This assumption isn't too risky.) Next, determine whichdomains you have. If your namespace is only WinNT:, you can get a list of thedomains from your network neighborhood. Once you know the domains, use thiscode:

Dim Container As IADsContainer

Dim Child As IADs

Set Container = GetObject

Container.Filter = Array("user")

For Each Child In Container

Debug.Print Child.Name + Chr$(9) + Child.HomeDirectory

Next Child

This code sets a filter to the container so that it lists only users. Itignores other objects, such as groups and computers. (You can, however, runreports on other objects in a domain. The SDK can help you with this task.) Thecode then uses a For Each loop to recall each user's name and home directory.

A property report will tell you which optional properties each usersupports. (A printout of mandatory properties would be empty.) Here's how to runthe optional properties report:

Dim Class As IADsClass

Set Class = GetObject("WinNT://SomeDomain/Schema/User")

l = LBound(Class.OptionalProperties)

u = UBound(Class.OptionalProperties)

For i = l To u

Debug.Print Class.OptionalProperties(i)

Next i

Table 3 shows sample output from this procedure.

Another way you can access the properties of AD objects is to use the Getand Put methods. A benefit of using Get and Put is that, theoretically, you donot need to know anything about your network objects or properties beforehand.You can browse the schema and then use the property names found as variables inthe Get and Put statements. (For more information on Get and Put, see the ADSIspecification.)

NT 4.0 has some shortcomings with regard to user properties. It does notreport three properties (PasswordExpirationDate, AccountDisabled, andIsAccountLocked) in OptionalProperties, so you cannot use them with Get and Put.Conversely, two properties (PasswordExpired and BadLoginCount) work only withGet and Put and not the previous procedure. Thus, you might have to use bothapproaches.

Another shortcoming is that you can access the properties ofUserCannotChangePassword, PasswordNeverExpires, and Global/Local account typeonly through the UserFlags bit field property. So you have to find the rightbits and do some calculations. Finally, you cannot access the dial-in settingsand the properties LogonHours, HomeDirDriveLetter, PasswordLastChanged, andLastFailedLogin.

Manipulating Objects
When you have done enough browsing and reporting, you will likely be eagerto make some changes. When manipulating objects, you need to identify both theobjects and their paths. To identify the object from its path, you can use theGetObject function as in the code examples here. To identify the path to anobject, you can use the ADsPath property by typing:

PathToSomeObj = SomeObj.ADsPath.

You can manipulate objects in many ways using Create, Delete, Move, andCopy. Here's an example of how to use Create to add a new user and itsproperties to a container in NT 4.0:

Dim Container As IADsContainer

Dim NewUser As IADsUser

Set Container = GetObject

Set NewUser = Container.Create
("user", "Maggie")

NewUser.FullName = "Henderson Maggie"

NewUser.HomeDirectory = "\Server2Maggie"


NewUser.SetPassword ("secret")

Set NewUser = Nothing

An important element in this code is SetInfo. After you specify the objectyou are creating, its name, and its properties (lines 3 through 6 in the code),the client computer caches this information. The computer creates the object andadds the property values to the user database only when you use SetInfo (line7). You do not have to use SetInfo, however, when creating a password becauseSetPassword (line 8) is a method and not a property.

Another important element is the Set NewUser = Nothingstatement (line 9).Use this statement when you finish working with a COM object. Otherwise,depending on the scope of the object variable, you might not release all thememory back to the operating system.

NT 5.0 beta includes a VBScript example program, which adds and deletesusers using a Microsoft Excel worksheet. The program uses ADSI and is 170 lineslong, half of which are comment lines.

Deleting, moving, and copying objects in ADSI is as simple as creatingthem. The ADSI specification can show you how to perform these and otherprocedures. If you have questions, Microsoft has an ADSI news group Inaddition, Microsoft's Knowledge Base will likely contain program examples andother information. You just need to go to http:// andsearch on ADSI. The Microsoft Developer Network (MSDN) is another resource totap into.

The Best Is Yet to Come
Although the ADSI specification is version 1.0, it performs more like a betaversion. Using ADSI with NT 4.0 or NetWare is more limiting, although easier,than using the corresponding native APIs.

This situation, however, will change next year for two reasons. First,Novell will release an ADSI provider for NDS that will likely support theNetWare environment better than Microsoft's ADSI provider. Novell's ADSIprovider will give NetWare users a way to access NDS via COM programming. Thisaccess will be beneficial because the clients will already be using 32-bitWindows.

Second, Microsoft will release NT 5.0 next year. ADSI is the choseninterface for NT 5.0's AD, so ADSI will perform at full capacity. In addition,although Microsoft designed ADSI and AD at the same time, it released ADSIearlier. The earlier release will give ADSI time to mature. By the timeMicrosoft releases NT 5.0, ADSI's bugs will likely be worked out.

Microsoft has committed to using LDAP 3 in NT 5.0 if the IETF finalizesthis revised protocol in time. The LDAP 3 draft specification calls for animproved referral process, better support for user authentication,extensibility, and other improvements. (For more information about LDAP 3 andhow various vendors plan to use it, see Craig Zacker, "LDAP and the Futureof Directory Services, Part 2," page 191.) The use of LDAP 3 in NT 5.0would likely bring about two changes: ADSI would get an LDAP 3 provider and LDAP3 would update ADSI.

If AD dominates the industry, ADSI will be beside it. But if a newprogramming technique replaces object-oriented COM, ADSI will vanish. However,ADSI probably won't disappear in this millennium, so you need to take a closerlook at it. ADSI is an object that represents the future.

Active Directory ServiceInterfaces (ADSI) 1.0

Contact: Microsoft * 425-882-8080Web: Free

Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like