Table of Content > Object Attributes: Deep Inside > Reading all Attributes of an Object
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://dc1.cerrotorre.de/cn=user1,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 obj.name & ": 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:
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.