Printout Header
RSS Feed

LDAP Objekt-Attribute schreiben


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
Änderungen mit SetInfo ins Verzeichnis schreiben
Attribute schreiben als ADSI-Objekteigenschaft
Attribute schreiben mit Put
Multivalue-Attribute ändern mit PutEx
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 Active DirectoryUser
Attribute für Active DirectoryGruppen
Attribute für Active DirectoryKontakte
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".


Änderungen mit SetInfo ins Verzeichnis schreiben


Wir werden mehrere Methoden besprechen, mit denen man Attributwerte für ein LDAP-Verzeichnisobjekt schreiben kann. Welchen davon auch immer Sie benutzen wollen, sie müssen stets die Änderungen dem Verzeichnis explizit als Schreiboperation übergeben ('commit'). Ansonsten haben Sie lediglich Ihren lokalen Attribute-Cache geändert, ohne Auswirkungen auf den Verzeichnis-Server selbst:

Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=PFoeckel,cn=Users,dc=cerrotorre,dc=de") . . hier werden irgendwelche Werte geändert... . . obj.SetInfo 'so werden die Änderungen zurück ins Verzeichnis geschrieben

Attribute schreiben als ADSI-Objekteigenschaft


Dies ist die einfachste Methode, um ein Attribut für eine LDAP-Objekte zu schreiben. 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=PFoeckel,cn=Users,dc=cerrotorre,dc=de") WScript.Echo obj.displayName 'den Anzeigenamen ausgeben obj.displayName = "Foeckeler, Philipp" 'einen neuen Anzeigenamen setzen obj.SetInfo WScript.Echo obj.displayName 'den Anzeigenamen nochmal ausgeben obj.sn = "Foeckeler" 'wir können mehrere Attribute auf einmal setzen obj.givenName = "Philipp" obj.mail = obj.givenName & "." & obj.sn & "@cerrotorre.de" obj.SetInfo 'den abschließenden commit nicht vergessen! WScript.Echo obj.mail Set ou = GetObject("LDAP://dc1.cerrotorre.de/cn=Users,dc=cerrotorre,dc=de") For Each obj In ou If (len(obj.givenName) <> 0) and (len(obj.sn) <> 0) then obj.mail = obj.givenName & "." & obj.sn & "@cerrotorre.de" WScript.Echo obj.mail End If 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 schreiben mit Put


In einigen Fällen ist es nicht möglich, auf ein LDAP-Attribut einfach als Objekteigenschaft mit der Syntax "object.attributname" zuzugreifen. 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


           user.msRADIUS-FramedIpv6Prefix = "2001:1638:1899::/48"


einen Attribut-Namen "msRADIUS-FramedIpv6Prefix" oder ob sie das Ergebnis einer Subtraktion zwischen mit den Werten "user.msRADIUS" und "FramedIpv6Prefix" 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 Put anwenden:

Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=PFoeckel,cn=Users,dc=cerrotorre,dc=de") WScript.Echo obj.displayName 'get the display name obj.Put "displayName", "Foeckeler, Philipp" 'einen neuen Anzeigenamen setzen obj.SetInfo WScript.Echo obj.displayName 'den Anzeigenamen nochmal ausgeben obj.Put "sn", "Foeckeler" 'wir können mehrere Attribute auf einmal setzen obj.Put "givenName", "Philipp" obj.Put "mail", obj.givenName & "." & obj.sn & "@cerrotorre.de" obj.SetInfo 'den abschließenden commit nicht vergessen! WScript.Echo obj.mail Set ou = GetObject("LDAP://dc1.cerrotorre.de/cn=Users,dc=cerrotorre,dc=de") For Each obj In ou If (len(obj.givenName) <> 0) and (len(obj.sn) <> 0) then obj.Put "mail", obj.givenName & "." & obj.sn & "@cerrotorre.de" WScript.Echo obj.mail End If 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 Reference im MSDN: Put()



Multivalue Attribute ändern mit PutEx


Sie sollten darauf achten, dass es sich bei einem Attribut, das Sie schreiben möchten, um einen Multivalue handeln könnte. Das bedeutet, dass in einem einzelnen Attribut ein Array von mehreren Werten gespeichert sein kann. Es muß eine Möglichkeit geben, Werte zu solch einem Array hinzuzufügen, einzelne Werte (aber nicht das gesamte Array) zu löschen, oder Werte in dem Array zu ersetzen. Die ADSI Methode Put ist für den Zugriff auf Multivalue Attribute nicht geeignet - wir müsen hier eine andere Funktion verwenden: PutEx.


object.PutEx <operation identifier>, <attribute name>, <array of attributes>



Im dritten Parameter muß stets ein Array übergeben werden, selbst wenn Sie die Funktion eigenlich mit einem Einzelwert aufrufen wollen. In diesem Fall müssen Sie einfach ein Array erzeugen, das nur aus einem Wert besteht.

Zusätzlich dazu benötigt PutEx einen Paramete, der dir Art der Operation festlegt, mit der das betreffende Multivalue Attribut zugegriffen wird:

ADS_PROPERTY_CLEAR = 1 Dies löscht das gesamte Attribut, es brauchen im dritten Parameter des PutEx-Aufrufes keine Werte angegeben werden (tatsächlich muß hier ein LEERES Array als Parameter übergeben werden)

ADS_PROPERTY_UPDATE = 2 Dies ersetzt das gesamte Attribut mit dem Array, das mit dem PutEx-Aufruf als Parameter übergeben wurde. Die alten Inhalte des betreffenden Attributes gehen dadurch verloren!

ADS_PROPERTY_APPEND = 3 Dies fügt einen oder mehrere Attribut-Werte hinzu, die der PutEx-Funktion in einem Array übergeben werden müssen.

ADS_PROPERTY_DELETE = 4 Dies löscht einen oder mehrere Attribut-Werte, die der PutEx-Funktion in einem Array übergeben werden müssen.


Hier sind einige Beispiele für jeden Schreibzugriff auf ein Multivalue-Attribut:


Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=Domain Admins,cn=Users,dc=cerrotorre,dc=de") Const ADS_PROPERTY_CLEAR=1 Const ADS_PROPERTY_UPDATE=2 Const ADS_PROPERTY_APPEND=3 Const ADS_PROPERTY_DELETE=4 obj.putex ADS_PROPERTY_UPDATE, "member", _ array("cn=Marten,cn=Users,dc=cerrotorre,dc=de", _ "cn=Michael,cn=Users,dc=cerrotorre,dc=de", _ "cn=Sandra,cn=Users,dc=cerrotorre,dc=de") obj.setinfo 'Nun sind lediglich Sandra, Marten und Michael Gruppenmitglieder, egal wer vorher in der Gruppe war obj.putex ADS_PROPERTY_APPEND, "member", array("cn=Juli,cn=Users,dc=cerrotorre,dc=de") obj.setinfo 'Wir haben Juli der Gruppen hinzugefügt, es gibt nun vier Mitglieder... Sandra, Juli, Marten and Michael 'Beachten Sie, dass wir hier ein Array mit nur einem Wert übergeben! obj.putex ADS_PROPERTY_DELETE, "member", array("cn=Michael,cn=Users,dc=cerrotorre,dc=de", "cn=Marten,cn=Users,dc=cerrotorre,dc=de") obj.setinfo 'Momentan in der Gruppe: Sandra and Juli obj.putex ADS_PROPERTY_CLEAR, "member", array() obj.setinfo 'Die Gruppe ist nun leer 'Beachten Sie, dass wir auch in diesem Fall ein (leeres) Array als Parameter übergeben

Sie sollten sich stets der Tatsache bewußt sein, dass ein Fehler bei einem einzigen Array-Wert dazu führt, dass der gesamte PutEx-Befehl nicht ausgeführt wird:

Set obj = GetObject("LDAP://dc1.cerrotorre.de/cn=Domain Admins,cn=Users,dc=cerrotorre,dc=de") Const ADS_PROPERTY_CLEAR=1 Const ADS_PROPERTY_UPDATE=2 Const ADS_PROPERTY_APPEND=3 Const ADS_PROPERTY_DELETE=4 obj.putex ADS_PROPERTY_UPDATE, "member", _ array("cn=Marten,cn=sers,dc=cerrotorre,dc=de", _ "cn=Michael,cn=Users,dc=cerrotorre,dc=de", _ "cn=Sandra,cn=Users,dc=cerrotorre,dc=de") obj.setinfo 'Wegen einem Schreibfehler in EINEM der Werte wird KEINER der Array-Werte ins Attribut geschrieben (=>Laufzeitfehler) obj.putex ADS_PROPERTY_DELETE, "member", array("cn=Michael,cn=Users,dc=cerrotorre,d=de", "cn=Marten,cn=Users,dc=cerrotorre,dc=de") obj.setinfo 'Wegen einem Schreibfehler inEINEM der Werte wird KEINER der Array-Werte aus dem Attribut entfernt (=>Laufzeitfehler))
ADSI Reference im MSDN: PutEx()



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.