Printout Header
RSS Feed

Writing LDAP Directory Object Attributes


Directory objects consist of a set of attributes: These are the actual data contents, which are - attached to the regarding object - stored in the directory database. Not all of the possible attributes have to be filled with real data. On the other hand many of the object attributes can consist of several values in an array.

We have several different techniques to read the directory attributes. The necessary basics are outlined in the next paragraphs:


Attribute Names
Using SetInfo to write the Changes to the Directory
Writing Attributes as an ADSI object property
Writing Attributes with Put
Writing Multivalued Attributes with PutEx
Special Data Types for Attributes



Attribute Names


If you want to access the properties of LDAP objects, you have to know the names of the regarding attributes. The complete set of attributes which can be stored in an object is specified in the directory server's schema.

The names of the attributes can be very different - depending on the directory service. Even the exact number of possible attributes can vary a lot in each case. The only general approach that helps here is a detailed look into the documentation or the usage of a powerful LDAP browser, which can evaluate and display all the attribute names for a single object based on the schema information (an LDAP browser which would be capable of that would be for example LEX - The LDAP Explorer).

I tried to document the attributes for several important object classes of Active Directory and Exchange 5.5. Hereby i concentrated on attributes which are dealt with in the graphical admin tools:


Attributes for Active Directory Users
Attributes for Active Directory Groups
Attributes for Active Directory Contacts
Attributes for Exchange 5.5 Mailboxes

If you don't know the attribute names of an object, you could also read the schema information from the regarding directory server, identify the concerning entries for the object class and extract there all the attribute names which are assigned to this class.

However, there is also a possibility to evaluate the set of attributes of an object in a script and without accessing the schema. But this method shows only the attributes of an actual object which have values and which are not 'Operational Attributes'. Find out more about this in the SelfADSI topic 'Read all Attributes of an Objects'.


Using SetInfo to write the Changes to the Directory


We will discuss several different methods to write an attribute value for an directory object. Whatever approach you choose, you always have to commit your changes to the regarding LDAP directory. Otherwise you just change your local object attribute cache without any effect to the directory server itself:

Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=PFoeckel,cn=Users,dc=cerrotorre,dc=de") . . we change the values of some attributes here... . . obj.SetInfo 'commit the changes to the directory

Writing Attributes as an ADSI object property


This is the easiest way to write an LDAP attribute. It is a precondition that you performed a valid LDAP Bind for the regarding object. Either you connected to the actual object or the LDAP Bind connection was made to a parent directory and the scripts loops through the containing objects.

Normal attributes can be accessed often directly like a object property, hereby the attribute name is specified with a period behind the object's name - it's as easy as that:

Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=PFoeckel,cn=Users,dc=cerrotorre,dc=de") WScript.Echo obj.displayName 'get the display name obj.displayName = "Foeckeler, Philipp" 'write a new display name obj.SetInfo WScript.Echo obj.displayName 'get the display name again obj.sn = "Foeckeler" 'we cange several attributes obj.givenName = "Philipp" obj.mail = obj.givenName & "." & obj.sn & "@cerrotorre.de" obj.SetInfo 'don't forget to commit! WScript.Echo obj.mail Set ou = GetObject("LDAP://dc1.cerrotorre.de/cn=Users,dc=cerrotorre,dc=de") For Each obj In ou If (len(obj.givenName) <> 0) and (len(obj.sn) <> 0) then obj.mail = obj.givenName & "." & obj.sn & "@cerrotorre.de" WScript.Echo obj.mail End If Next

This notation may tempt us to confuse the used attributes with the API properties. Because this properties can be accessed exclusively with the syntax notation 'object.property'. However, these API properties are definitely not attributes from the LDAP directory, but object properties which is provided by the ADSI interface (and contains often information that is somehow related to attribute values). Examples for these properties are ADSPath, Class, Parent and Name. You can read more information about ADSI properties in the topic 'API properties for objects' here in the SelfADSI tutorial.


Writing Attributes with Put


In some cases it is not possible to access an LDAP attribute simply as an object property with the syntax notation 'object.attributename'. An example: An attribute's name could contain a minus character, and therefore the script interpreter cannot decide in the term


           user.msRADIUS-FramedIpv6Prefix = "2001:1638:1899::/48"


whether you want to set a value for an attribute named 'msRADIUS-FramedIpv6Prefix' or to do a subtraction between the values 'user.msRADIUS' and 'FramedIpv6Prefix'.

Another difficulty which has to be dealt with in scripts: Maybe the name of the attribute is not a constant string, but another variable.

In these cases you should use the ADSI method Put:

Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=PFoeckel,cn=Users,dc=cerrotorre,dc=de") WScript.Echo obj.displayName 'get the display name obj.Put "displayName", "Foeckeler, Philipp" 'write a new display name obj.SetInfo WScript.Echo obj.displayName 'get the display name again obj.Put "sn", "Foeckeler" 'we cange several attributes obj.Put "givenName", "Philipp" obj.Put "mail", obj.givenName & "." & obj.sn & "@cerrotorre.de" obj.SetInfo 'don't forget to commit! WScript.Echo obj.mail Set ou = GetObject("LDAP://dc1.cerrotorre.de/cn=Users,dc=cerrotorre,dc=de") For Each obj In ou If (len(obj.givenName) <> 0) and (len(obj.sn) <> 0) then obj.Put "mail", obj.givenName & "." & obj.sn & "@cerrotorre.de" WScript.Echo obj.mail End If Next

A bit more laborious.... but think about it: That way you are on the safe side, because this is the official method which is described in the ADSI interface specifications.


ADSI Reference on the MSDN: Put()



Changing Multivalued Attributes with PutEx


You should keep in mind that the attribute which you maybe just want to write could be a multivalue attribute. That means that an array of values is stored in one single LDAP attribute. There has to be an possibility to add some values to such an array, to delete some values (but not the entire array) or to replace some values in the array. The ADSI method Put is not suitable for writing arrays - we have to use another function for this: PutEx.


object.PutEx <operation identifier>, <attribute name>, <array of attributes>



In the third parameter, you should always pass an array to the function, even if you only want to call the function with one single value! In this case you simply build an array which consists only of one value.

Additionally, PutEx needs a parameter to specify the kind of operation which is to be performed on the regarding multi valued attribute:

ADS_PROPERTY_CLEAR = 1 This deletes the entire attribute, no additional values have to be passed to the PutEx call as the third parameter (in fact, you have to pass an EMPTY array as an parameter....)

ADS_PROPERTY_UPDATE = 2 This replaces the entire attribute with the array passed to the PutEx call as a parameter. The old values or the regarding attribute are lost!

ADS_PROPERTY_APPEND = 3 This adds one or several attribute values, which have to be passed to the PutEx function in an array.

ADS_PROPERTY_DELETE = 4 This deletes one or several attribute values, which have to be passed to the PutEx function in an array.


Here are some examples for each write access operation for a multivalue attribute:


Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=Domain Admins,cn=Users,dc=cerrotorre,dc=de") Const ADS_PROPERTY_CLEAR=1 Const ADS_PROPERTY_UPDATE=2 Const ADS_PROPERTY_APPEND=3 Const ADS_PROPERTY_DELETE=4 obj.putex ADS_PROPERTY_UPDATE, "member", _ array("cn=Marten,cn=Users,dc=cerrotorre,dc=de", _ "cn=Michael,cn=Users,dc=cerrotorre,dc=de", _ "cn=Sandra,cn=Users,dc=cerrotorre,dc=de") obj.setinfo 'now only Sandra, Marten and Michael are group members, regardless what users were in there before obj.putex ADS_PROPERTY_APPEND, "member", array("cn=Juli,cn=Users,dc=cerrotorre,dc=de") obj.setinfo 'we added Juli to the group, there are four members now... Sandra, Juli, Marten and Michael 'please note that we pass an array with one value! obj.putex ADS_PROPERTY_DELETE, "member", array("cn=Michael,cn=Users,dc=cerrotorre,dc=de", "cn=Marten,cn=Users,dc=cerrotorre,dc=de") obj.setinfo 'current group members: Sandra and Juli obj.putex ADS_PROPERTY_CLEAR, "member", array() obj.setinfo 'the group is empty now 'please note that we passed an empty array on this call

You should be aware of the fact that if you made an error in specifying one single member in your array which you pass to the PutEx function, the call will fail completely:

Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=Domain Admins,cn=Users,dc=cerrotorre,dc=de") Const ADS_PROPERTY_CLEAR=1 Const ADS_PROPERTY_UPDATE=2 Const ADS_PROPERTY_APPEND=3 Const ADS_PROPERTY_DELETE=4 obj.putex ADS_PROPERTY_UPDATE, "member", _ array("cn=Marten,cn=sers,dc=cerrotorre,dc=de", _ "cn=Michael,cn=Users,dc=cerrotorre,dc=de", _ "cn=Sandra,cn=Users,dc=cerrotorre,dc=de") obj.setinfo 'because there is a typing error in ONE value, NONE of the three values will be written (runtime error will occur) obj.putex ADS_PROPERTY_DELETE, "member", array("cn=Michael,cn=Users,dc=cerrotorre,d=de", "cn=Marten,cn=Users,dc=cerrotorre,dc=de") obj.setinfo 'because there is a typing error in ONE value, NONE of the two values will be deleted (runtime error will occur)
ADSI Reference on the MSDN: PutEx()



Special Data Types for Attributes


Attributes are stored in their directories in different data types. The actual data type specification is also called 'attribute syntax'. And when you read attributes from a directory object, it plays certainly an important role whether you have to deal with strings, integer, long integers, date and time values or even with raw hex values. Because if the handling of a string or an integer is easy and also the conversion between such types is easy on he one hand, you could struggling much more when you have to read (display, compare, and so on...) with attributes which represents date and time formats or raw octet strings.

If you connect to an directory object with an LDAP Bind operation and you read the attributes of this object with standard techniques, you will get no information about the data type of the value(s) you read. However, if you use the more complicated ADSI method GetPropertyItem and a special handling of the property cache, you can retrieve the data type from ADSI for all kind of attributes. And then you can handle this accordingly in a script when you read the attributes value with unknown data types. An example for this approach can be examined in the article 'Reading all Attributes of an Object' here in the SelfADSI tutorial.

Interesting articles in the SelfADSI tutorial regarding attribute data types:


Object attributes of type Octet String: "Octet-String" is an LDAP syntax and one of the standardized data types for raw hexadecimal values. But the according data type Byte[] is not available under VBScript: You have difficulties to handle such attributes without script runtime errors which state that the datatype was wrong or unknown. In this article you learn how to avoid such runtime errors and how to read and handle attributes of type Octet-String.


Object Attributea of type Provider Specific: I an LDAP server returns this data type, it means something like "datatype could not be evaluated by the script exactly...". It is very complicated to read such attributes and handle their values without runtime errors. The only way to find the correct handling is to look in the directory schema and to apply a special method which can convert the values of such attributes into a usable format.


The directory schema:
General information about attribut data types, attribute syntaxes, and their specification in the directory schema.