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.
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:
Network Provider Interface for supporting automatic logon to multiple namespaces
Windows Sockets Registration for service registration
Windows Sockets Resolution (RnR) for resolution
RPC OLE DB for rich query
Active Directory Service Interfaces for directory object manipulation
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
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.
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.
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.
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).
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 |