Printout Header
RSS Feed

LDAP Objekt-Attribute lesen


Verzeichnisobjekte bestehen aus einer Menge von Attributen: Dies sind die eigentlichen Daten, die bezogen auf das betreffende Objekt im Verzeichnis gespeichert werden. Es müssen nicht alle Attribute eines Objektes auch wirklich mit Daten gefüllt sein, und viele dieser Attribute erlauben es, mehrere Werte in einer Art Menge oder Array abzuspeichern.


Um Verzeichnisattribute auszulesen, kann man sich verschiedener Techniken bedienen. Die notwendigen Grundlagen werden in den folgenden Abschnitten mit Beispielen erläutert:


Attribut-Bezeichnungen
Attribute lesen als ADSI-Objekteigenschaft
Attribute lesen mit Get
Multivalue-Attribute lesen
Attribute lesen mit GetEx - die beste Methode
Operational Attribute lesen mit GetInfoEx
Attributwerte wieder einlesen mit GetInfo
Spezielle Attribut-Datentypen



Attribut-Bezeichnungen


Wenn man auf die Eigenschaften von LDAP-Objekten zugreifen will, muss man die Bezeichnungen der entsprechenden Attribute kennen. Die Menge aller Attribute, die in einem Objek gespeichert werden können, wird im Schema des betreffenden LDAP-Servers gespeichert.


Die Bezeichnungen für die Atribute können je nach Verzeichnisdienst sehr verschieden sein - auch die Anzahl der möglichen Attribute varriert stark. Hier hilft nur ein Blick in die jeweilige Dokumentation oder die Verwendung eines leistungsfähigen LDAP Browsers, der die möglichen Attribute eines konkreten Verzeichnisobjektes aus dem Schema auslesen und anzeigen kann (ein Browser, der dies beherrscht, wäre z.B. LEX - The LDAP Explorer).


Für einige wichtige Objektklassen im Active Directory und für Exchange 5.5-Verzeichnisse habe ich mich bemüht, diejenigen Attribute zu dokumentieren, mit denen man in den grafischen Administrations-Utilities umgeht:


Attribute für ADS-User
Attribute für ADS-Gruppen
Attribute für ADS-Kontakte
Attribute für Exchange 5.5 Mailboxen

Wenn man die Attribut-Namen eines Objektes nicht kennt, so hat man natürlich die Möglichkeit, das Schema des betreffenden Verzeichnis-Servers auszulesen, die entsprechenden Einträge für die Objektklasse herauszufinden und dort in den Eigenschaften abzulesen, welche Attribute für ein bestimmtes Objekt gespeichert sein könnten.


Es gibt jedoch auch eine Möglichkeit, per Skript und ohne Zugriff auf das Schema die Namen aller Attribute herauszufinden, die bei einem konkreten Objekt gerade explizit gesetzt sind und die nicht als sogenannte "Operational Attributes" behandelt werden. Lesen Sie dazu den SelfADSI Thema "Alle Attribute eines Objekts lesen".


Attribute lesen als ADSI-Objekteigenschaft


Dies ist die einfachste Methode, um ein LDA P-Attribut zu lesen. Voraussetzung hierfür ist, dass man einen LDAP Bind für das betreffende Objekt durchgeführt hat. Entweder man sich mit dem Objekt selbst verbunden, oder man erhält die Verbindung zum Objekt, indem man den Bind-Vorgang für den übergeordneten Container durchgeführt hat, und dann in einer Schleiffe im Script die darin enthaltenen Objekte durchgeht.


Normale Attribute können oft direkt als Objekt-Eigenschaft angesprochen werden, der Attribut-Name wird dann durch einen Punkt getrennt hinter dem Objekt-Namen angegeben - so hat man Zugriff auf den Attribut-Wert:

Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=Administrator,cn=Users,dc=cerrotorre,dc=de") WScript.Echo obj.displayName 'Anzeigename im Addressbuch WScript.Echo obj.givenName & " " & obj.sn 'Vorname Nachname WScript.Echo obj.mail 'Mail-Adresse Set ou = GetObject("LDAP://dc1.cerrotorre.de/cn=Users,dc=cerrotorre,dc=de") For Each obj In ou WScript.Echo obj.displayName 'Anzeigename im Addressbuch WScript.Echo obj.samAccountName 'NetBIOS/NT-Anmeldename Next

Diese Syntax verleitet dazu, die so verwendeten Attribute mit den API-Properties zu verwechseln. Diese Properties werden nämlich tatsächlich ausschließlich über die Schreibweise "object.property" zugegriffen. Es handelt sich bei den API-Properties jedoch nicht um Attribute aus dem LDAP-Verzeichnis, sondern um Objekt-Eigenschaften, die die ADSI-Schnittstelle zur Verfügung stellt, z.B. die Eigenschaften ADSPath, Class, Parent und Name. Lesen Sie mehr über diese Properties im Abschnitt "API-Properties von ADSI-Objekten" hier im SelfADSI-Tutorial.


Attribute lesen mit Get


In einigen Fällen ist es nicht möglich, ein LDAP-Attribut einfach als Objekteigenschaft mit der Syntax "object.attributname" zu lesen. Denn es könnte sein, dass im Attributnamen ein Minus-Zeichen enthalten ist, und dann kann der Script-Interpreter nicht mehr entscheiden, ob Sie mit dem Ausdruck


           WScript.Echo user.msDS-KeyVersionNumber


einen Attribut-Namen "msDS-KeyVersionNumber" oder ob sie das Ergebnis einer Subtraktion zwischen mit den Werten "user.msDS" und "KeyVersionNumber" ausgeben lassen wollen.


Eine andere Schwierigkeit tritt dann auf, wenn der Variablen-Name selbst wiederum nicht konstant ist.


In diesen Fällen sollten Sie die ADSI-Methode Get anwenden:

Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=Administrator,cn=Users,dc=cerrotorre,dc=de") varDisplay = obj.Get("displayName") 'Anzeigename im Addressbuch WScript.Echo varDisplay varGivenName = obj.Get("givenName") 'Vorname varSurname = obj.Get("sn") 'Nachname WScript.Echo varGivenName & " " & varSurname varMail = obj.Get("mail") 'Mail-Adresse 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") 'Anzeigename im Addressbuch WScript.Echo varDisplay varSAMAccountName = obj.Get("samAccountName") WScript.Echo varSAMAccountName 'NetBIOS/NT-Anmeldename Next

Etwas umständlicher.... aber denken Sie daran: Sie sind so auf der sicheren Seite, den dies ist der offizielle Weg, der in der ADSI-Schnittstellenbeschreibung angegeben ist.


ADSI-Referenz im MSDN: Get()



Multivalue-Attribute lesen


Denken Sie daran, dass es sich bei dem von Ihnen ausgelesenen Attribut auch um ein Multi-Value-Attribut handeln kann. Ist mehr als ein Wert vorhanden, so geben beide bisher beschriebenen Zugriffsmoethoden plötzlich ein Array zurück. Sie wissen jedoch von vornherein nicht, ob das Attribut im konkreten Falle vielleicht doch nur einen einzigen Wert hat - dann kommt das Ergebnis auch nicht als Array. Wollen Sie ganz sicher gehen, müßten Sie dies vor der Behandlung des Ergebnisses stets abfragen:

Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=Administrator,cn=Users,dc=cerrotorre,dc=de") pAddr = obj.proxyAddresses 'Mailadressen - kann ein Array sein, muss aber nicht... 'oder pAddr = obj.Get("proxyAddresses") 'Mailadressen - kann ein Array sein, muss aber nicht... If (IsArray(pAddr)) then 'Array-Check For i = 0 To UBound(pAddr) WScript.Echo pAddr(i) Next Else WScript.Echo pAddr End If

Attribute lesen mit GetEx - die beste Methode


Wenn man nicht genau weiß, ob ein Attribut als Multivalue-Array zurückgeliefert wird oder als einzelner Wert, dann ist es vielleicht besser, die ADSI-Methode GetEx zu verwenden. Diese Funktion liefter IMMER ein Array zurück - selbst wenn das Attribut nur einen Wert hat, oder z.B. wenn das Attribut überhaupt kein Multivalued Attribut ist. Die GetEx-Methode funktioniert ansonsten genauso wie die Get-Funktion:

Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=Administrator,cn=Users,dc=cerrotorre,dc=de") pAddr = obj.GetEx("proxyAddresses") 'Mail-Addresses - wird auf diese Weise immer als Array zurückgeliefert For i = 0 To UBound(pAddr) 'Output OHNE Array Check WScript.Echo pAddr(i) Next

Gegenüber Get ist GetEx beim Auslesen von Multivalued-Attributen stets die bessere Methode!


ADSI-Referenz im MSDN: GetEx()


Operational Attribute lesen mit GetInfoEx


Bei den meisten Attributen muss man sich nicht genau darum kümmern, dass sie als Information mit dem Bind-Vorgang an das betreffende Objekt zur Verfügung stehen: Man kann nach erfolgtem BIND durch die oben beschriebenen Methoden einfach darauf zugreifen. Andere Attribute dagegen sind so genannte Operational Attribute. Sie sind eigentlich für den internen Gebrauch des Verzeichnisdienstes gedacht und werden einem LDAP-Client erst dann übermittelt, wenn er explizit nach Ihnen fragt.


Operational LDAP Atribute werden offiziell in RFC 4512 im Abschnitt 3.4 (Operational Attributes) beschrieben. Insbesondere sind hier folgende Attribute genannt, die man bei den verschiedensten Verzeichnisdiensten antrifft:

Welches die Operational Attribute sind, kann man nur herausfinden, indem man das Schema des betreffenden Verzeichnisses überprüft. Lesen Sie dazu mehr im SelfADSI-Kapitel "Das Verzeichnis-Schema". Active Directory verwendet selbst gar nicht so viele Operational Attributes. Beim LDAP-Zugriff auf alte Exchange 5.x hingegen oder auf eDirectory muss man recht oft auf die hier beschriebene GetInfoEx-Methode zurückfgreifen.


Wie kann man nun Operational Attribute auslesen? Ganz einfach: Indem man die entsprechenden Attributnamen mit der ADSI- Funktion GetInfoEx explizit von einem verbundenen Objekt abfragt. Danach kann man darauf zugreifen wie auf jedes normale Attribut:

Set obj = GetObject("LDAP://nldap1.cerrotorre.de/cn=supervisor,ou=ADM,ou=cerrotorre,o=de") attArray = Array("createTimeStamp", "modifyTimeStamp") obj.GetInfoEx attArray, 0 'zwei operational Attribute anfordern WScript.Echo obj.distinguishedName 'normales Attribut WScript.Echo obj.createTimeStamp 'operational Attribut WScript.Echo obj.modifyTimeStamp

GetInfoEx muss mit einem Array von Strings aufgerufen werden, selbst wenn sie nur ein einziges Operational Attribut auslesen wollen. Der zweite Parameter von GetInfoEx ist übrigens reserviert und muss immer 0 sein.


ADSI-Referenz im MSDN: GetInfoEx()


Attributwerte wieder einlesen mit GetInfo


Attribute werden normalerweise mit einem Bind-Vorgang automatisch in den sogenannten Property-Cache des Verzeichnisobjektes geladen. Wir haben gesehen, dass wir bei Operational Attribute diesem Ladevorgang etwas nachhelfen müssen.


Der Property Cache wird für jedes Objekt gebildet, mit dem man sich über ADSI verbunden hat. In ihm werden lokal alle Eigenschaften und Attribute des Objektes gespeichert. Alle Zugriffe auf dieses Objekt (sowohl lesend als auch schreibend) greifen in Wirklichkeit auf den Property Cache zu. Wenn nun ein anderer LDAP-Client oder ein administrativer Vorgang das Objekt und seine Eigenschaften auf dem Server verändert, merkt unser Skript normalerweise nichts davon, denn der Property Cache wird nicht automatisch aktualisiert.


Wenn man bei einem verbundenen Verzeichnisobjekt die Attribute nochmals anfragen will, dann verwendet man die ADSI-Funktion GetInfo. Damit wird der Property-Cache wieder neu mit den aktuellen Server-Daten für dieses Objekt geladen.

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 'Attribute erneut einlesen WScript.Echo Now & " " & obj.DisplayName

Operational Attribute werden übrigens durch GetInfo nicht in den Property Cache geladen - hier hilft nur ein explizites Abfragen mit GetInfoEx.


ADSI-Referenz im MSDN: GetInfo()


Spezielle Attribut-Datentypen


Attribute werden unter verschiedenen Datentypen im jeweiligen Verzeichnis gespeichert. Dieser Datentyp wird auch "Attribut Syntax" genannt. Und beim Auslesen von Attributen per Skript spielt es natürlich eine Rolle, ob es sich dabei um Strings, Integer, Longs, Datumsformate oder gar um Hex-Werte handelt. Denn während die Handhabung eines Strings oder Integers und auch die Umwandlung zwischen diesen Datentypen trivial sein mag, so kann es doch erhebliche Schwierigkeiten machen, wenn man aus einem Objektattribut z.B. Uhrzeit- und Datumsformate oder reine binäre Rohdaten auslesen, darstellen und vergleichen muss.


Wenn man mit einem LDAP Bind eine Verbindung zu einem Verzeichnisobjekt hergestellt hat und dessen Attribute ausliest, bekommt man mit herkömmlichen Methoden keine Informationen über den Datentyp - wenn man allerdings die etwas umständlichere ADSI-Funktion GetPropertyItem und einen speziellen Umgang mit dem Property Cache verwendet, dann wird von ADSI die Information zurückgegeben, um was für einen Datentyp es sich handelt. Dementsprechend kann man dann im Skript beim Auslesen der Attribute darauf reagieren. Ein Beispiel für diese Technik können Sie im Artikel "Alle Attribute eines Objektes auslesen" hier im SelfADSI Tutorial untersuchen.


Interessante Abschnitte im SelfADSI-Tutorial zu Attribut-Datentypen:


Objekt Attribute des Typs Octect String: "Octet-String" ist eine LDAP-Syntax und damit ein standardisierter Datetyp für reine Hexadezimalwerte. Den entsprechenden Datentyp Byte[] kennt z.B: ein VBScript jedoch nicht: Man hat Schwierigkeiten, die vom Verzeichnis empfangenen Daten dieses Typs z.B. in einen String anzuzeigen. Lesen Sie in diesem Abschnitt, wie es trotzdem funktioniert und man mit Octet-String-Attributen umgeht.


Objekt Attribute des Typs Provider Specific: Wenn ein LDAP-Server diesen Datentyp zurückgibt, heißt das soviel wie "kann vom Skript aus nicht genau entschieden werden". Es ist schwierig, diese Attribute auszulesen. Hier hilft nur ein Blick ins Schema des betreffenden Verzeichnisdiensten und eine spezielle Methode, um die Daten in ein für eine Skript brauchbares Format umzuwandeln.


Das Verzeichnis-Schema:
Allgemeine Infos über Attribut-Datentypen und Attribut-Syntax und deren Definition im Verzeichnisschema.