Printout Header
RSS Feed

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:


Attribute Names
Reading Attributes as an ADSI object property
Reading Attributes with Get
Reading Multivalued Attributes
Reading Attributes with GetEx - the best method
Reading Operational Attributes with GetInfoEx
Re-Read the Attribute Values with GetInfo
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 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'.


Reading Attributes as an ADSI object property


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:

Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=Administrator,cn=Users,dc=cerrotorre,dc=de") WScript.Echo obj.displayName 'display name in the address book WScript.Echo obj.givenName & " " & obj.sn 'given name - surname WScript.Echo obj.mail 'mail address Set ou = GetObject("LDAP://dc1.cerrotorre.de/cn=Users,dc=cerrotorre,dc=de") For Each obj In ou WScript.Echo obj.displayName 'display name in the address book WScript.Echo obj.samAccountName 'NetBIOS/NT logon name 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.


Reading Attributes with Get


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


           WScript.Echo user.msDS-KeyVersionNumber


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:

Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=Administrator,cn=Users,dc=cerrotorre,dc=de") varDisplay = obj.Get("displayName") 'display name in the address book WScript.Echo varDisplay varGivenName = obj.Get("givenName") 'given name varSurname = obj.Get("sn") 'surname WScript.Echo varGivenName & " " & varSurname varMail = obj.Get("mail") 'mail address WScript.Echo varMail Set ou = GetObject("LDAP://dc1.cerrotorre.de/cn=Users,dc=cerrotorre,dc=de") For Each obj In ou varDisplay = obj.Get("displayName") 'display name in the address book WScript.Echo varDisplay varSAMAccountName = obj.Get("samAccountName") WScript.Echo varSAMAccountName 'NetBIOS/NT logon name 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: Get()



Reading Multivalued Attributes


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:

Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=Administrator,cn=Users,dc=cerrotorre,dc=de") pAddr = obj.proxyAddresses 'mail addresses - could be an array, but doesn't have to be.... 'or else: pAddr = obj.Get("proxyAddresses") 'mail addresses - could be an array, but doesn't have to be.... If (IsArray(oClass)) then 'array check For i = 0 To UBound(pAddr) WScript.Echo pAddr(i) Next Else WScript.Echo pAddr End If

Reading Attributes with GetEx - the best method


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 :

Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=Administrator,cn=Users,dc=cerrotorre,dc=de") pAddr = obj.GetEx("proxyAddresses") 'mail addresses - always returned as an array For i = 0 To UBound(pAddr) 'output WITHOUT array check WScript.Echo pAddr(i) Next

In comparison to Get, GetEx is always the better approach when reading multivalue attributes!


ADSI Reference on the MSDN: GetEx()


Reading Operational Attributes with GetInfoEx


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:

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:

Set obj = GetObject("LDAP://nldap1.cerrotorre.de/cn=supervisor,ou=ADM,ou=cerrotorre,o=de") attArray = Array("createTimeStamp", "modifyTimeStamp") obj.GetInfoEx attArray, 0 'request operational attributes WScript.Echo obj.distinguishedName 'normal attribut WScript.Echo obj.createTimeStamp 'operational attribut WScript.Echo obj.modifyTimeStamp

GetInfoEx has to called with an array of strings, even if you want to request only one single operational attribute. The second parameter of the GetInfoEx function is reserved and has to be always 0.


ADSI Reference on the MSDN: GetInfoEx()


Re-Read the Attribute Values with GetInfo


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.


Set obj = GetObject("LDAP://nldap1.cerrotorre.de/cn=supervisor,ou=ADM,ou=cerrotorre,o=de") WScript.Echo Now & " " & obj.DisplayName WScript.Sleep 5000 obj.GetInfo 're-read attribute values WScript.Echo Now & " " & obj.DisplayName

By the way: Operational attributes will not be reloaded when you use GetInfo - this can be only done by an explicit call with GetInfoEx.


ADSI Reference on the MSDN: GetInfo()


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.