Microsoft KB Archive/306867

= PRB: Calling ADSI and CDOEXM Methods from Scripting Languages =

Article ID: 306867

Article Last Modified on 2/12/2004

-

APPLIES TO


 * Microsoft Active Directory Service Interfaces 2.5
 * 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.



Using Dot Notation and dispIDs
The following code uses the dispID to retrieve the comment property from the property cache: set oUser = GetObject(&quot;LDAP://cn=MyUser,...&quot;) 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(&quot;LDAP://cn=MyUser,...&quot;) Debug.Print oUser.Get(&quot;comment&quot;)

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(&quot;LDAP://rootDSE&quot;) wscript.echo rootDSE.get(&quot;defaultNamingContext&quot;) 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(&quot;LDAP://rootDSE&quot;) 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(&quot;LDAP://cn=MyUser,...&quot;) 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(&quot;LDAP://CN=MyDL,CN=Users,DC=MyDomain&quot;) objDistList.HideDLMembership = True

