Reading 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:
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 b 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'.
This is the easiest way to read 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:
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.
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
whether you want to display an attribute named 'msDS-KeyVersionNumber' or to do a subtraction between the values 'user.msDS' and 'KeyVersionNumber'.
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 Get:
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.
Reference on the MSDN: Get()
You should keep in mind that the attribute which you maybe just read from an object could be a multivalue attribute. When such an attribute contains more than just one value, then both of the previous described approaches returns suddenly an array. But we don't know exactly whether the regarding attribute has maybe only one value in a particular situation - then the value is not returned as an array. To be completely sure we have to check this, before we deal with the returned value:
If you don't know exactly whether an attribute is returned as an array or as a single value, then could be more clever to use the ADSI method GetEx. This function returns ALWAYS an array, even if the attribute contains only one value, and even if the attribute is no multivalue attribute at all. In every other sense the GetEx method works exactly as the Get method :
Reference on the MSDN: GetEx()
Regarding the most attributes, you do not have to care about how you can read their values after a successful Bind operation to the according object: you just do the Bind connect to an object and then you can access the attributes with the methods described above. However, there are other attributes called Operational Attributes. Normally these attributes are intended for the internal technical usage of the directory services only - they will not be transferred to an LDAP client unless this client explicitly asks for them.
Operational attributes are specified and described officially in RFC 4512 in paragraph 3.4 (Operational Attributes). Particularly this specification enumerates the following attributes, which can be encountered in all sorts of directory services:
- creatorsName (the object's creator, unfortunately not implemented in Active Directory environments)
- createTimestamp (date and time when the object was created)
- modifiersName (the account which last altered the object, unfortunately not implemented in Active Directory environments)
- modifyTimestamp (date and time when the object was last modified)
You can only evaluate the set of operational attributes if you check the schema of the regarding directory services. Read more about this techniques in the topic 'The directory schema' here in the SelfADSI tutorial. Active Directory doesn't even use a lot of operational attributes, but when you access old Exchange 5.5 servers or Novell eDirectory services, then you have to use the GetInfoEx method quite often, which is to be described here.
So how can we read these operational attributes? It's quite simple: You just have to explicitly request all the regarding attribute names with the ADSI function GetInfoEx according to a connected object. After this you can access the operational attributes just as every other normal attribute:
Reference on the MSDN: GetInfoEx()
Normally attributes are loaded in the so-called property cache of an directory object, when an LDAP Bind is performed for this. We have seen that we have to help along this load operation when we want to access operational attributes.
The property cache is built up by the ADSI interface for each object we initiated a connection to. In this cache all properties and all attributes of the regarding object are stored locally. In fact, all access operations (read or write) are performed in the first instance on this local cache. If another LDAP client or some other administrational event does modify the object on the server, our script normally does not realize such changes, because the content of the local property cache is not updated automatically.
If you want to request the attributes again for a connected directory object, then you can use the ADSI method GetInfo. This reloads the content of the property cache from the directory server.
Reference on the MSDN: GetInfo()
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.