Printout Header
RSS Feed

Reading all Attributes of an Object

This topic of the SelfADSI tutorial is about the difficulty to read ALL attributes from any directory object, especially if you don't know how many attributes there are, what the naming labels for these attributes are and in which data types these attributes are stored in the object. These tasks will be handled by the example script below: Enum.

In the script we do a little trick: The attribute data are not accessed with normal techniques (like described in the topic 'Reading Object Attributes'). In fact, we use the so called Property Cache. This local cache can be filled with directory data by calling the ADSI method GetInfo and afterwards read with the method GetPropertyItem. The advantage of this approach: Now we have an array of all the attributes which are available and can evaluate their names and data types.

The actual reading of the attribute data is done then with several different techniques, for data types like Octet-String or Provider Specific we have to use some additional script functions to convert data into formats which can be read in outputs.

Over all, this script is good example for all the access technologies, which are discussed according object attributes in the SelfADSI tutorial so far:

Set obj = GetObject("LDAP://,cn=users,dc=cerrotorre,dc=de", _ "administrator", "secret", 1) Const ADSTYPE_DN_STRING=1 Const ADSTYPE_CASE_EXACT_STRING = 2 Const ADSTYPE_CASE_IGNORE_STRING = 3 Const ADSTYPE_PRINTABLE_STRING = 4 Const ADSTYPE_NUMERIC_STRING = 5 Const ADSTYPE_BOOLEAN=6 Const ADSTYPE_INTEGER=7 Const ADSTYPE_OCTET_STRING=8 Const ADSTYPE_UTC_TIME=9 Const ADSTYPE_LARGE_INTEGER=10 Const ADSTYPE_PROV_SPECIFIC=11 obj.GetInfo obj.GetInfoEx Array("createTimeStamp", "modifyTimeStamp"), 0 WScript.Echo & ": attribute count: " & obj.PropertyCount & vbCrLf For i = 0 To obj.PropertyCount-1 Select Case obj.Item(i).ADStype Case ADSTYPE_DN_STRING attrTypeName = "DN String" Case ADSTYPE_CASE_EXACT_STRING attrTypeName = "CaseExact String" Case ADSTYPE_CASE_IGNORE_STRING attrTypeName = "CaseIgnore String" Case ADSTYPE_PRINTABLE_STRING attrTypeName = "Printable String" Case ADSTYPE_NUMERIC_STRING attrTypeName = "Numeric String" Case ADSTYPE_BOOLEAN attrTypeName = "Boolean" Case ADSTYPE_INTEGER attrTypeName = "Integer" Case ADSTYPE_OCTET_STRING attrTypeName = "Octet-String" Case ADSTYPE_UTC_TIME attrTypeName = "UTC Time" Case ADSTYPE_LARGE_INTEGER attrTypeName = "Large Integer" Case ADSTYPE_PROV_SPECIFIC attrTypeName = "Provider Specific" Case Else attrTypeName = CStr(obj.item(i).adstype) End Select WScript.Echo "__________________________________________________________________" WScript.Echo obj.Item(i).Name & " (" & attrTypeName & ")" Select Case obj.Item(i).ADStype Case ADSTYPE_DN_STRING, ADSTYPE_CASE_EXACT_STRING, ADSTYPE_CASE_IGNORE_STRING, _ ADSTYPE_PRINTABLE_STRING, ADSTYPE_INTEGER, ADSTYPE_NUMERIC_STRING, _ ADSTYPE_UTC_TIME valuearray = obj.GetEx(obj.Item(i).name) For Each value In valuearray WScript.Echo value Next Case ADSTYPE_LARGE_INTEGER valuearray = obj.Getex(obj.Item(i).name) For Each value In valuearray WScript.Echo value.HighPart & ":" & value.LowPart Next Case ADSTYPE_BOOLEAN valuearray = obj.GetEx(obj.Item(i).name) For Each value In valuearray If (value) Then WScript.Echo "TRUE" Else WScript.Echo "FALSE" Next Case ADSTYPE_OCTET_STRING valuearray = obj.GetEx(obj.Item(i).name) For Each value In valuearray hstr = OctetToHexStr(value) WScript.Echo PrintOutHex(hstr, 16) Next Case ADSTYPE_PROV_SPECIFIC Set prop = obj.GetPropertyItem(obj.Item(i).name, ADSTYPE_OCTET_STRING) valuearray = prop.Values For Each value In valuearray data = value.OctetString hstr = OctetToHexStr(data) WScript.Echo PrintOutHex(hstr, 16) Next End Select Next Function OctetToHexStr(var_octet) 'converts raw binary data (byte arrays) into strings which shows the hexadecimal values (hex string) Dim n OctetToHexStr = "" For n = 1 To lenb(var_octet) OctetToHexStr = OctetToHexStr & Right("0" & hex(ascb(midb(var_octet, n, 1))), 2) Next End Function Function PrintoutHex(var_hex, width) 'returns an editor-like formatted string out of an hex string 'the width parameter specifies the number of bytes per ouput line Dim k1, k2, s1, s2 PrintOutHex = "" For k1 = 1 To Len(var_hex) Step (width *2) s1 = Mid(var_hex, k1, (width *2)) s2 = "" s3 = HexStrToAscii(s1, False) For k2 = 1 To Len(s1) Step 2 s2 = S2 & Mid(S1, k2, 2) & " " Next s2 = s2 & String((width *3)-Len(s2), " ") If (k1=1) Then PrintOutHex = PrintOutHex & s2 & "| " & s3 Else PrintOutHex = PrintOutHex & vbcrlf & s2 & "| " & s3 End If Next End Function Function HexStrToAscii(var_hex, format) 'converts an hex string into an ASCII string 'is 'format'=TRUE, then tabs and linefeeds are inserted as needed Dim k, v HexStrToAscii = "" For k = 1 To Len(var_hex) Step 2 v = CInt("&H" & Mid(var_hex, k, 2)) If ((v>31) And (v<128)) Then HexStrToAscii = HexStrToAscii & (chr(v)) Else If (format) Then Select Case v Case 8 HexStrToAscii = HexStrToAscii & vbTab Case 10 HexStrToAscii = HexStrToAscii & vbCrLf Case 13 Case Else HexStrToAscii = HexStrToAscii & "." End Select Else HexStrToAscii = HexStrToAscii & "." End If End If Next End Function

The result:

ScreenShot Script Output

ADSI Reference on the MSDN: Property Cache Interface

By the way: In Active Directory environments, attributes are normally never returned in the format syntax "Provider-Specific". Such cases would indicate an error condition of the regarding domain controller or the local ADSI interface on the client. In other directories (for example, in Novell eDirectory environments), you will encounter these Provider-Specific attributes rather often.