MS Active Directory Service Interfaces (ADSI) (Windows NT 4.0)

Archived content. No warranty is made as to technical accuracy. Content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

Updated : February 1, 1997

Abstract

The following paper details the vision of Microsoft for integrating multiple directory services through a well defined, open set of interfaces: Microsoft Active Directory Service Interfaces (formerly OLE-DS). The availability of a standard, open directory service administration and programming model for Windows-based platforms will encourage the inclusion of directory services in a wide range of commercial and customer-developed applications.

The ADSI Software Developer's Kit for Windows NT 4.0 is available to all customers by downloading from the Microsoft Internet Web site at https://www.microsoft.com/win32dev/netwrk/adsi.htm.

On This Page

Introduction
Directory Services Today
Active directory Service Interfaces
Active Directory Service Interfaces Architecture
Active Directory Service Interfaces Standard Objects
Active Directory service Interfaces Programming Model
Using Active Directory Service Interfaces
Using Active Directory service Interfaces for Schema Management
Conclusion

Introduction

Why are Active Directory Service Interfaces Important?

One of the challenges of working within a large, distributed computing environment is identifying and locating resources such as users, groups, print queues, and documents. A directory service is part of a distributed computing environment that provides a way to locate and identify the users and resources available in the system. A directory service is like a phone directory. Given a name for a person or a resource, it provides the information necessary to access that person or resource. You do not have to use specific binding information to access a resource on the network.

Most enterprises already have many different directories in place. For example, network operating systems, electronic mail systems, and "groupware" products all have their own directories. Many issues arise when a single enterprise deploys multiple directories. These issues include usability, data consistency, development cost, and support cost, among others.

Active Directory Service Interfaces addresses these issues by providing a single, consistent, open set of interfaces for managing and using multiple directories.

What You Should Already Know

This document assumes readers have a working knowledge of OLE, the Component Object Model, and directory services. Example code appears in the Microsoft Visual Basic programming system.

Directory Services Today

It is common to find a variety of directoriesmany playing an administrative rolethat are deployed within a single organization. These include network resource directories, such as and LDAP-based directory, DCE Cell Directory Service, Banyan StreetTalk, Microsoft Windows NT operating system Directory Service, and Novell Directory Services, as well as application specific directories, such as, Lotus Notes, cc:Mail, or Microsoft Mail. Although a single directory for an entire organization is desirable, no product available today can fill this very large requirement.

Cc749951.vt1cu(en-us,TechNet.10).gif

Figure 1: - The directory challenge

Multiple directories in the organization pose complex challenges to users, administrators, and developers. These problems have limited wide-directory deployment. End users face multiple logons and a variety of interfaces to information across multiple directories. Administrators face the complexity of managing multiple directories. End users and administrators want application developers to use an existing administrative directory, but developers face a dilemmawhich one should they use? Each directory offers unique application interfaces. Developers must choose a specific directory implementation, or support multiple versions of their application. As a result, developers seldom use existing directory services.

Microsoft has a strategy for helping to solve these customer problems noted abovethe Open Directory Services Interface (ODSI). ODSI is a set of WOSA1 application programming interfaces (APIs) that will make it easy for customers and Independent Software Vendors (ISVs) to build applications that register with, access, and manage multiple directory services with a single set of well-defined interfaces.

One of the most familiar WOSA APIs is Open Data Base Connectivity (ODBC). ODBC provides open interfaces for relational databases, thus allowing developers to write applications and tools that will work with any database that supports ODBC. Because of the thriving ODBC development community, every major relational database now supports ODBC. ODSI is "ODBC for directory services."

ODSI gives developers access to multiple directory service providers via an open set of interfaces. Applications written to ODSI will work with any directory service that offers an ODSI provider. ODSI addresses the problems outlined above with five APIs. All are part of WOSA:

  1. Network Provider Interface for supporting automatic logon to multiple namespaces

  2. Windows Sockets Registration for service registration

  3. Windows Sockets Resolution (RnR) for resolution

  4. RPC OLE DB for rich query

  5. Active Directory Service Interfaces for directory object manipulation

Cc749951.vt1cu(en-us,TechNet.10).gif

Figure 2: - The open solution

The remainder of this document presents the concepts, features, benefits, and architecture of Active Directory Service Interfaces, and provides examples of Active Directory Service Interfaces usage.

Active directory Service Interfaces

What are Active Directory Service Interfaces?

Active Directory Service Interfaces abstracts the capabilities of directory services from different network providers to present a single set of directory service interfaces for managing network resources. The standard Active Directory Service Interfaces objects are those found within multiple namespaces. The typical namespaces for Active Directory Service Interfaces are directory services for various network operating systems. Administrators and developers can use Active Directory Service Interfaces services to enumerate and manage the resources in a directory service, no matter which network environment contains the resource.

Active Directory Service Interfaces makes it easier to perform common administrative tasks, such as adding new users, managing printers, and locating resources throughout the distributed computing environment.

Active Directory Service Interfaces makes it easy for developers to "directory enable" their applications. Administrators and developers deal with a single set of directory service interfacesregardless of the installed directory service(s).

Active Directory Service Interfaces are one component of the Windows Open Services Architecture (WOSA) Open Directory Service Interfaces (ODSI).

Who Will Use Active Directory Service Interfaces?

Network Administrators will use Active Directory Service Interfaces to automate common administrative tasks, such as adding users and groups, managing printers, and setting permissions on network resources.

Independent Software Vendors (ISVs) and end user developers will use Active Directory Service Interfaces to "directory enable" their products and applications. Services can publish themselves in a directory, clients can use the directory to find the services, and both can use the directory to find and manipulate other objects of interest. Because Active Directory Service Interfaces are independent of the underlying directory service(s), the directory enabled products and applications will operate successfully in multiple network and directory environments.

Benefits of Active Directory Service Interfaces

Feature

Benefit

Open

Any directory provider can implement an Active Directory Service Interfaces provider; users gain freedom of choice in directory services without sacrificing manageability.

DS Independent

Administrative applications are not tightly bound to a given vendor's directory service. The same application can work on multiple directories. Development time and support costs are reduced.

Java Support

Active Directory Service Interfaces objects provide easy access to directory services for Java applets and programs through Java COM.

Simple Programming Model

Administrative and other directory-enabled applications can be developed with no need to understand vendor-specific directory APIs.

OLE Automation Server

Any OLE Automation Controller (for example, Visual Basic, Perl, Rexx, C/C++ and others) can be used to develop directory service applications. Administrators and developers can use the tools they already know. Productivity is enhanceddevelopment time and support costs are reduced.

Functionally Rich

ISVs and sophisticated end users can develop serious applications using the same Active Directory Service Interfaces models that are used for simple scripted administrative applications.

Extensible

Directory providers, ISVs, and end users can extend Active Directory Service Interfaces with new objects and functions to add value or meet unique needs.

Active Directory Service Interfaces Architecture

Object Model

The Active Directory Service Interfaces object model consists of Active Directory Service Interfaces objects and dependent objects. Clients manipulate objects with interfaces. Active Directory Service Interfaces providers implement the Active Directory Service Interfaces objects and their interfaces.

Active Directory Service Interfaces Objects

Active Directory Service Interfaces objects are COM objects that represent persistent objects in an underlying directory service. An Active Directory Service Interfaces object is manipulated using one or more COM interfaces.

Active Directory Service Interfaces objects are divided into two groups: directory service leaf objects, and directory service container objects. A container object can contain other Active Directory Service Interfaces objects. A leaf object cannot contain Active Directory Service Interfaces objects.

Dependent Objects

An Active Directory Service Interfaces object is typically the host for one or more dependent objects. Dependent objects are COM objects that logically divide the functionality of an Active Directory Service Interfaces directory service object. Clients obtain interface pointers on dependent objects by calling methods on the interfaces of the host Active Directory Service Interfaces object. Dependent objects can be retrieved only from host objects.

The division of a given object type into a host and one or more dependent objects implements a logical grouping of properties and methods. This division does not necessarily2 reflect the structure of the underlying directory. The host and dependent object relationship should not be confused with the container and contents relationshipthe former is a characteristic of Active Directory Service Interfaces, the latter a characteristic of the underlying directory.

Active Directory Service Interfaces Provider

Cc749951.vt2cu(en-us,TechNet.10).gif

Figure 3: - Provider architecture

An Active Directory Service Interfaces provider contains the implementation of Active Directory Service Interfaces objects and dependent objects for a particular namespace. Figure 3 demonstrates that clients are concerned only with getting and using interfaces on an object, and not with the details of where and how the software of an object is implemented.

Active Directory Service Interfaces Schema Management

Active Directory Service Interfaces provides predefined objects so that directory service manipulation can be uniform across namespaces. However, an Active Directory Service Interfaces object in any given directory might have more functionality than that specified by Active Directory Service Interfaces. A directory might also contain objects that are not defined at all by Active Directory Service Interfaces. In addition, there are extensible directory services that allow their base schema to be modified and their objects to be arbitrarily extended by administrators and independent software vendors.

Object extensions are handled by the Schema Management Active Directory Service Interfaces objects. These objects are used to:

  • Browse the definitions of objects.

  • Extend the definitions of objects.

In Active Directory Service Interfaces, there are three ways to extend an Active Directory Service Interfaces object:

  • Directory extensions for providers that expose more than just the standard objects.

  • Provider schema extensions when clients extend the schema by using a provider's extensible schema.

  • Third-party schema extensions when software developers attach new properties and methods to an object definition as part of their application.

Schema Management Active Directory Service Interfaces Objects

The schema management objects can be used to browse and modify the schema of a namespace. These objects are:

  • Schema container object, which contains a given schema.

  • Class container object, which defines an object class.

  • Property object, which describes a property.

  • Syntax object, which describes a syntax that can be used in a property definition.

These objects are different from directory service objects like the User component, in that their properties are not subdivided into functional sets.

Schema container object

The schema container object is used to attach a set of object definitions to a part of a directory tree. Typically, each instance of a directory will have its own schema. Active Directory Service Interfaces represents this by placing a schema container as a child of the directory root.

Cc749951.vt3cu(en-us,TechNet.10).gif

Figure 4: - The Schema container

Figure 4 shows the typical layout. However, Active Directory Service Interfaces does not limit schema containers to this level of the tree. A complex directory might allow multiple schemas to exist in a directory instance. In that case, schema containers might be found in other parts of a tree. There can only be one schema container in any given Active Directory Service Interfaces container.

Cc749951.vt4cu(en-us,TechNet.10).gif

Figure 5: - Schema hierarchy

The schema container itself is a tree that contains class, functional set, property, and syntax definitions. New classes and functional sets can be created in the container to expand the schema.

Functional sets are defined separately from classes so that they can be used in multiple class definitions.

Class container object

The class container object is used to define a class of objects that can be created in the directory. New classes can be derived from existing classes using the Active Directory Service Interfaces model.

Cc749951.vt5cu(en-us,TechNet.10).gif

Figure 6: - Creating a class

Figure 6 illustrates how a class container object relates to other class objects, property objects, and syntax objects to create a definition of a class. A class object points to property objects, which point to the syntax the property supports.

Active Directory Service Interfaces Caching

All Active Directory Service Interfaces objects provide two methodsGetInfo and SetInfoto provide simple caching for properties. Operations that involve getting and setting properties occur in the cache.

A caller can obtain a property value from an Active Directory Service Interfaces object at any time after obtaining the object. The caller need not call GetInfo first. If the property in question has not been previously retrieved, the provider is responsible for retrieving and caching it to satisfy the request. Subsequent requests will be satisfied from the cached value.

GetInfo is called to explicitly refresh the object's cached properties from the underlying directory. By calling GetInfo, the caller ensures that the property values are current as of the time of the GetInfo call. If the GetInfo method is executed after changes are made to the local object's cache but before the SetInfo method is executed, the changes are discarded. GetInfo allows the client to provide hints about which properties it uses, so that the provider can optimize network access.

SetInfo is called to write an object back to the underlying directory. No changes are made to an object's properties within the directory until the SetInfo method is called.

Active Directory Service Interfaces Names

Objects that reside within a given namespace, are identified by a unique name. For example, files stored on a PC disk drive reside in the file system namespace. The unique name of a file is based on where it is stored in the file system namespace, for example:

C:\public\documents\ole_ds\oleds_functional_spec_v1.doc  

Directory service namespaces also identify the objects they contain by unique names, which are usually based on the location in the directory where the object can be found. For example, in a DCE3 directory, a given object might have a name like this:

/.../C=US/O=SomeOrg/OU=Accounting/Services/GL/Server1 

Different directory services use different forms for naming the objects they contain. This makes dealing with different namespaces challenging, especially for developers, considering all of the different environments on which the code might be running.

A goal of Active Directory Service Interfaces is to minimize the code's knowledge of an object's path so that programs can be namespace-portable.

Active Directory Service Interfaces defines a naming convention that can uniquely identify an Active Directory Service Interfaces object in a heterogeneous environment. These names are called OleDsPath strings. OleDsPath strings take one of three forms:

"@OLEDS!" 
or 
"@<NamespaceIdentifier>!" 
or 
"@<NamespaceIdentifier!<ProviderSpecificPath>" 

"@OLEDS!" identifies the namespaces Container object. This is a special container, implemented by Active Directory Service Interfaces, that contains the namespace identifiers of the namespaces for which an Active Directory Service Interfaces provider is available. If Active Directory Service Interfaces providers for an LDAP-based directory, Windows NT, NetWare 4.1, and Banyan VINES are all installed on a given system, the Active Directory Service Interfaces namespaces container will contain the namespace identifier for each provider, for example:

"LDAP-Based Directory", "WINNT", "NW41", "VINES."

The second form, "@<NamespaceIdentifier>!", identifies the top-level container for the namespace in question. This is sometimes called the "namespace root." Active Directory Service Interfaces uses this form to identify the Active Directory Service Interfaces provider that understands the rest of the name. For example,

"@NW41!" 

directs Active Directory Service Interfaces to the NetWare 4.1 provider.

The third form, "@<NamespaceIdentifier >!< ProviderSpecificPath >", identifies the target component as an Active Directory Service Interfaces object in the namespace indicated by <NamespaceIdentifier>. The <ProviderSpecificPath> is a string value that must uniquely identify a directory service object in the given namespace. Each provider is responsible for determining the semantics of this string. A typical string for Windows NT would be:

"@WINNT!SomeDomainName\ADomainUser" 

which identifies a user object for "ADomainUser" in the "SomeDomainName" domain.

Active Directory Service Interfaces Standard Objects

Directory Objects

Active Directory Service Interfaces defines two kinds of objects. Clients use Schema Management Objects to browse and extend the schema. Directory Objects represent the objects in the underlying namespaces managed by the Active Directory Service Interfaces providers. Schema Management Objects are discussed above, in "Active Directory Service Interfaces Schema Management."

Active Directory Service Interfaces defines a set of standard container and leaf objects that represent the most common objects found in network directories. Using the schema extension model, provider writers and application developers can add additional objects as needed.

Standard Container Objects

  • Namespaces

  • Country

  • Locality

  • Organization

  • Organizational Unit

  • Domain

  • Computer

Standard Leaf Objects

  • User

  • Group

  • Alias

  • Service

  • Print Queue

  • Print Device

  • Print Job

  • File Service

  • File Share

  • Session

  • Resource

Active Directory service Interfaces Programming Model

Component Object Model

Active Directory Service Interfaces objects are Component Object Model (COM) objects. Active Directory Service Interfaces programming is COM programming. In its most basic form, programmers interact with COM objects by calling one of the standard OLE procedures to obtain a pointer to an object's IUnknown interface. They then call QueryInterface to obtain a pointer to the specific interface of interest.

Active Directory Service Interfaces can all be called using this standard COM model by using traditional compiled languages such as, Microsoft C and Microsoft C/C++. Active Directory Service Interfaces provides a "helper" function, OleDsGetObject, to simplify the process of obtaining the desired interface pointer from a given Active Directory Service Interfaces object.

Example 1: Creating a User (C/C++)

IOleDsContainer

*pContainer;

IOleDs

*pNewObject;

IOleDsContainer

*pContainer;

IOleDs

*pNewObject;

IOleDsUser

*pUser;

IOleDsUserAccountRestrictions

*pAcctRestr;

// 
// Bind to the known container. 
// 
OleDsGetObject(TEXT"@WinNT!MSFT", 
IID_IOleDsContainer, 
(void**)&pContainer); 
// 
// Create the new Active Directory Service Interfaces User object. 
// 
pContainer->Create(TEXT"User", 
TEXT"Jane", 
&pNewObject); 
// 
// Get the IOleDsUser interface from the user object. 
// 
pNewObject->QueryInterface(IID_IOleDsUser, &pUser); 
// 
// Set Jane's password. 
// 
pUser->AccountRestrictions(&pAcctRestr); 
pAcctRestr->SetPassword(TEXT"Argus"); 
// 
// Complete the operation to create the object. 
// 
pUser->SetInfo(); 
// 
// Cleanup. 
// 
pContainer->Release(); 
pNewObject->Release(); 
pUser->Release(); 
pAcctRestr->Release(); 

OLE Automation Interface (IDispatch)

Active Directory Service Interfaces objects are also OLE Automation Servers. All Active Directory Service Interfaces can be invoked via the IDispatch interface.

The IDispatch interface is defined by OLE. It is the OLE Automation interface for controllers that do not use COM interfaces directly. Accessing an object through IDispatch is called name-bound or late-bound access, since the connection between the client and the OLE object (server) occurs at run time, and not when the client program is linked.

OLE Automation controllers like Visual Basic hide the inner workings of OLE, and calls all of the necessary methods in IDispatch on behalf of the programmer. Programmers can concern themselves with the logic of their application, and not the low-level details of OLE.

Example 2: Creating a User Object (Visual Basic)

Dim Container as IOleDsContainer 
Dim NewUser as IOleDsUser 
' Bind to the known container. 
Set Container = GetObject("@WinNT!MSFT") 
' Create the new Active Directory Service Interfaces User. 
Set NewUser = Container.Create("User", "Jane") 
' Set Jane's password. 
NewUser.AccountRestrictions.SetPassword("Argus") 
' Complete the operation to create the object in the directory. 
NewUser.SetInfo 

Using Active Directory Service Interfaces

Using Active Directory Service Interfaces for Administration

Creating a List of Users.

Building lists of users and their properties is a common need. In this example, a Visual Basic script extracts all of the users in the "NS" namespace in the Austin organizational unit of the ABX Compute Corporation's Manufacturing division. Here each user's name and known telephone numbers (as they appear in the directory) are passed to a "PrintUser" routine.

Example 3: Creating a list of users

dim MyUserContainer as IOleDsContainer
dim MyUser as IOleDsUser
set MyUserContainer as GetOBject("@NS!ABX\Manufacturing\Austin")
for each MyUser in MyUserContainer
 PrintUser MyUser.Name, MyUser.BusinessInformation.TelephoneNumbers
next MyUser


Adding Users to Groups

Adding users to groups for security purposes is a common and time-consuming activity for system administrators. In this example, the Austin users from the preceding example are added to the Manufacturing_Users group in the ABX organization, if they do not already belong.

Example 4: Adding users to groups

dim MyUserContainer as IOleDsContainer
dim MyUser as IOleDsUser
dim MyGroup as IOleDsGroup
dim Filter as Variant
Filter = Array("user")
set MyUserContainer = GetOBject("@NS!ABX\Manufacturing\Austin")
MyContainer.Filter = Filter  ' filter out all objects except users
set MyGroup = GetObject("@NS!ABX\Manufacturing_Users")
for each MyUser in MyUserContainer
 if not MyGroup.GeneralInfo.IsMember(MyUser) then
 	 MyGroup.GeneralInfo.Members.Add(MyUser)
 end if
next MyUser

A slightly more sophisticated version will accomplish the same task for all organizational units in the manufacturing division.

Example 5: Adding users to groupsextended version

dim MyUserContainer as IOleDsContainer 
dim MyOuContainer as IOleDsContainer 
dim MyUser as IOleDsUser 
dim MyGroup as IOleDsGroup 
dim Filter as Variant 
Filter = Array("ou") 
set MyOuContainer = GetOBject("@NS!ABX\Manufacturing") 
MyOuContainer.Filter = Filter 
Filter = Array("user") 
for each MyUserContainer in MyOuContainer 
 MyUserContainer.Filter = Filter 
for each MyUser in MyUserContainer 
 if not MyGroup.GeneralInfo.IsMember(MyUser.OleDsPath) then 
  MyGroup.GeneralInfo.Members.Add(MyUser.OleDsPath) 
 end if 
next MyUser 
next MyUserContainer 

Simplifying Administration: A "Real World" User Manager

The notion of "user roles" is a common one in system administration. The access rights and privileges of a given user will depend on the roles a user fills. Rights and privileges are usually associated with security groups defined in a directory service. Unfortunately, the connection of a given "role" to a set of group memberships is generally defined in an administrator's memory or a notebook containing security procedures. When a new user is added to the system, the notebook or administrator who has the knowledge must be consulted to get the proper group memberships established.

In this example, the mapping of user roles to groups is captured in a small program written in Visual Basic. This program uses Active Directory Service Interfaces to create the users and add them to the necessary groups based upon a "role" selected via the user interface (UI).

Cc749951.vt6cu(en-us,TechNet.10).gif

Example 6: Visual Basic Code for Active Directory Service Interfaces User Addition Application

Setting up the Environment

Global declarations hold the information necessary for running the sample application as is shown below:

Public Domain As IOleDs 
Public MfgUsers As IOleDsGroup 
Public PersUsers As IOleDsGroup 
Public EngUsers As IOleDsGroup 
Public FinUsers As IOleDsGroup 
Public AcctUsers As IOleDsGroup 
Public UserType As Integer 
' Namespace root for Active Directory Service Interfaces operations 
Public Const NameRoot As String = "@WinNT!Pell" 
' Constant values for each user role we handle 
Public Const iAddDefault As Integer = 0 
Public Const iAddPersonnel As Integer = 1 
Public Const iAddFinance As Integer = 2 
Public Const iAddEngineering As Integer = 3 

When the form is displayed this code sets up the Active Directory Service Interfaces Domain and Group objects needed by the sample application.

Private Sub Form_Load() 
' When this form is loaded: 
' Instantiate objects for the domain and groups to which users 
' will be added 
' 
On Error GoTo Error_Form_Load 
    StatusBar.Panels.Item(1).Text = "Connecting..." 
    Set Domain = GetObject(NameRoot) 
    Set MfgUsers = GetObject(NameRoot + "\Manufacturing_Users") 
    Set PersUsers = GetObject(NameRoot + "\Personnel_Users") 
    Set EngUsers = GetObject(NameRoot + "\Engineering_Users") 
    Set FinUsers = GetObject(NameRoot + "\Finance_Users") 
    Set AcctUsers = GetObject(NameRoot + "\Accounting_Users") 
    ' 
    ' Let the user know we are ready 
    StatusBar.Panels.Item(1).Text = "Ready" 
    Exit Sub 
Error_Form_Load: 
    ' 
    ' Let the user know we have a problem 
    StatusBar.Panels.Item(1).Text = "Init Err:" + Str(Err.Number) 
End Sub 

Selecting the Role

This code stores the role the user will have. It is called whenever one of the "role" radio buttons is clicked to save the newly selected role. The value of "index" will be one of the values for which constants have been defined in the global declarations.

Private Sub OptionUser_Click(Index As Integer) 
    UserType = Index 
End Sub 

Adding the New User

This code creates the new user and adds the new user to the groups associated with their role.

Private Sub ButtonAdd_Click()
Dim NewUser As IOleDsUser
    Dim businfo As IOleDsFSUserBusinessInformation
    On Error GoTo ButtonAdd_Error
    StatusBar.Panels.Item(1).Text = "Adding User..."
    ' check the password
    If TextPassword <> TextPassword2 Then
        response = MsgBox("Passwords do not match.", vbCritical, "Re-enter Password")
        Exit Sub
    End If
    ' Add a new user to the domain
    ' First, create the new user object
    Set NewUser = Domain.Create("user", TextUserId)
    ' Set the properties of the user object
    With NewUser.BusinessInformation
        .FullName = TextFirstName + " " + TextLastName
        .Description = TextDescription
    End With
' write to the DS
    NewUser.SetInfo
' set the password
    NewUser.AccountRestrictions.SetPassword (TextPassword)
' Add the new user to the desired groups
    Select Case UserType
        Case iAddPersonnel
            MfgUsers.GeneralInfo.Groups.Add (NewUser.OleDsPath)
            PersUsers.GeneralInfo.Groups.Add (NewUser.OleDsPath)
        Case iAddFinance
            FinUsers.GeneralInfo.Groups.Add (NewUser.OleDsPath)
            AcctUsers.GeneralInfo.Groups.Add (NewUser.OleDsPath)
        Case iAddEngineering
            MfgUsers.GeneralInfo.Groups.Add (NewUser.OleDsPath)
            EngUsers.GeneralInfo.Groups.Add (NewUser.OleDsPath)
        Case Else 'add the default user
            MfgUsers.GeneralInfo.Groups.Add (NewUser.OleDsPath)
    End Select
StatusBar.Panels.Item(1).Text = "Ready"
    Exit Sub
ButtonAdd_Error:
     StatusBar.Panels.Item(1).Text = "Add Err:" + Str(Err.Number)
     Resume Next
End Sub

Using Active Directory service Interfaces for Schema Management

A useful feature of schema-based directory services is the ability of administrators to add properties to objects. For example, administrators at the "ABX" organization might want to create an "ABXuser" based on the standard Active Directory Service Interfaces user object, which contains additional properties useful at ABX.

Assume that ABX wants to add a Card Key number to the user object, and call the new object type "ABXuser." Active Directory Service Interfaces makes this simple. First, a new class is created in the schema container, and is marked as derived from the desired base class. New properties are added to the new Class. The Visual Basic code to perform this extension appears below.

Example 7: Extending the Schema

Dim schema as IOleDsSchema  
Dim user as IOleDsClass  
Dim ABXuser as IOleDsClass 
Dim CardKey as IOleDsProperty 
' bind to the schema container 
set schema = GetObject("@NS!ABX\Schema") 
' get the base user object to derive from 
set user = GetObject("@NS!ABX\Schema\user") 
' create a new class in the schema 
set ABXuser = schema.create("class","ABXuser") 
' set the properties of the new class - we don't want to override the base 
' object, so we copy the base object's properties 
ABXuser.CLSID = user.CLSID 
ABXuser.PrimaryInterface = user.CLSID 
ABXuser.Container = False 
ABXuser.DerivedFrom = user.PrimaryInterface 
ABXuser.Containment = user.Containment 
' write out the new class 
ABXuser.SetInfo 
 'create a new property in the class 
set CardKey = ABXuser.create("property","CardKey") 
CardKey.syntax = "Bstr" 
CardKey.SetInfo 
 'Done! 

Conclusion

Most organizations have multiple directories in place. The presence of multiple directories within an organization poses complex challenges to users, administrators, and developers.

Active Directory Service Interfaces addresses these challenges by providing a single, consistent, open set of interfaces for managing and using multiple directories.

Active Directory Service Interfaces and the associated ODSI components are an effective tool for simplifying the directory usage and management issues facing users and developers.

1 Windows Open Services Architecture
2 The division may coincidentally reflect the actual structure of the underlying directory; the point here is that the host/dependent object relationship is an artifact of the Active Directory Service Interfaces, not of any particular directory.
3 Open Software Foundation's Distributed Computing Environment