PRB: Calling ADSI and CDOEXM Methods from Scripting Languages (306867)



The information in this article applies to:

  • Microsoft Active Directory Services Interface, System Component
  • Microsoft Active Directory Client Extension

This article was previously published under Q306867

SYMPTOMS

When you use Active Directory Services Interface (ADSI) in a late binding or scripting application, you cannot use either a vTable method of ADSI or an ADSI extension that has the same name as a property that exists in the schema. You may also receive unexpected results when you use dot notation to obtain attributes from the property cache.

CAUSE

When an interface (for example, IADsUser) does not explicitly expose a property (for example, comment) you can retrieve it by using dot notation (oUser.comment). This works because ADSI uses a method named dynamic dispatch to assign dispatch ID codes to the properties in the property cache for an object. You can use the dispID to retrieve the property from the property cache.

If you use dot notation to reference a property, and that property is not in the property cache, ADSI looks in the schema to see whether the property is a property for an object of that class. If it is, then ADSI assigns a dispID to the property and loads the property value into the property cache.

When you use dot notation to retrieve a property from the property cache, ADSI uses the COM function GetIDsOfNames and passes in a property name to get a valid dispID. ADSI then uses the dispID to retrieve the property from the property cache. For example, the oUser.comment statement causes ADSI to pass in comment to GetIDsOfNames, which returns a dispID. ADSI uses this dispID to retrieve the property from the property cache.

In late binding or scripting applications, ADSI looks at the dispID first for a property. If ADSI does not find a dispID for the property, ADSI looks at the vTable.

Example of the Problem When Names Are the Same

A problem can occur if a method of ADSI or an ADSI extension has the same name as a property that exists in the schema for that class of object. When this occurs, ADSI tries to use the dispID of the property and does not use the method found in the vTable.

For example, if you use a property named Prop1 and a method named Meth1 of the object obj, making a call to obj.Meth1 causes ADSI to call GetIDsOfNames and use the dispID that corresponds to Prop1 in the property cache.

The method of the same name that is in the vTable will not be available. This is not the case if you use early binding because the vTable is used first and the dispIDs are used later. In this example, ADSI looks at the vTable first for the method Meth1 and uses the method.

RESOLUTION

For late-binding scripting languages, call a COM object that uses early binding to perform the methods required from your script.

MORE INFORMATION

Using Dot Notation and dispIDs

The following code uses the dispID to retrieve the comment property from the property cache:
set oUser = GetObject("LDAP://cn=MyUser,...")
Debug.Print oUser.comment
				
The following code uses the Get method and property name to retrieve the property from the property cache:
set oUser = GetObject("LDAP://cn=MyUser,...")
Debug.Print oUser.Get("comment")
				

Using Dot Notation with RootDSE

You cannot use dot notation with RootDSE unless you first do a Get or a GetInfo. This is because RootDSE does not exist in the schema and there will be no properties in the property cache when you bind to it.

Using dot notation causes ADSI to look in either the property cache if it exists, or in the schema to determine whether there is a property that corresponds to the requested property. If the property cache is empty, ADSI looks to the schema. If the schema reveals a property of that name, then it does an implicit GetInfo, which loads the property cache. In other words, if you do a Get on a property, a GetInfo is implicitly called and the property cache is also loaded.

Example of Successful Code

The following sample code demonstrates the expected behavior because Get loads the property cache by doing a base-level search on the Null object, and then loads the returned properties into the property cache.
dim rootDSE
Set rootDSE = GetObject("LDAP://rootDSE")
wscript.echo rootDSE.get("defaultNamingContext")
wscript.echo rootDSE.defaultNamingContext
				
Example of Unsuccessful Code

The following sample code does not succeed because RootDSE is not in the schema. The dynamic dispatch ID code looks to see whether the property cache for the object has defaultNamingContext, which it does not because it is empty. The dynamic dispatch ID code then determines whether defaultNamingContext is a valid property in the schema, which it is not. A dynamic dispID cannot be created and the method fails, as demonstrated by the following code:
dim rootDSE
Set rootDSE = GetObject("LDAP://rootDSE")
wscript.echo rootDSE.defaultNamingContext
				

Property Names Generate Different Errors Than Property Methods

If the property is not set on the object, the results that you receive when you use dot notation and specify a function to retrieve the property are different from the results that you receive when you use the property name in dot notation.

For example:
set oUser = GetObject("LDAP://cn=MyUser,...")
Debug.Print oUser.homedirectory
Debug.Print oUser.homepage
				
Homedirectory is the name of a property on a user class object in the schema. Homepage is a function on the IADsUser object that does not exist in the schema. When you use dot notation to retrieve homedirectory from the property cache, ADSI tries to use the dispID to retrieve it. If the property is not found in the cache because it is not set on the object, an error is not generated.

When you use dot notation to retrieve homepage, a dispID cannot be generated because homepage is not found in the schema. ADSI then looks in the vTable and tries to obtain homepage by using the IADsUser::get_homepage function. This function will read wWWhomePage from the property cache. If wWWHomePage has not been set on the object, it will not be in the property cache, and you receive the following error message:
Error code 0x8000500D
The Active Directory property cannot be found in the cache.

Property Name Is the Same as a Method Name

Group objects in the Active Directory have a property named hideDLMembership. There is a CDO for Exchange Management (CDOEXM) method named hideDLMembership. If you try to use the hideDLMembership method, you receive an error in the following code because ADSI will be retrieving the property from the property cache, therefore making the syntax of this line erroneous.
Set objDistList = GetObject("LDAP://CN=MyDL,CN=Users,DC=MyDomain")
objDistList.HideDLMembership = True
				

REFERENCES

For more information about early and late binding, visit the following MSDN Web site:
For more information about dispatch IDs, visit the following MSDN Web site:

Modification Type:MajorLast Reviewed:2/12/2004
Keywords:kbDSWADSI2003Swept kbprb KB306867 kbAudDeveloper