Das Schema ist erweitert worden. Wie können die neuen Attribute und Objekte nun genutzt werden? Ohne weiteres erst mal gar nicht. Die Verwaltungstools von Windows 2000/2003 lassen sich nicht einfach so um zusätzliche Attribute (Datenfelder) und Objektklassen erweitern. Man kann zwar durchaus neue Registerkarten einfügen, das geht aber nur über COM-Programmierung mit C++.
Wenn man sich auf einen Kompromiss einlässt, kann man aber auch mit einfacheren Methoden eine Schemaerweiterung oder eine eigene Funktion mit den Standardtools nutzen. Es ist nämlich vergleichseiwe einfach, die Kontextmenüs zu erweitern. Hierzu fügt man einen entsprechenden Eintrag im „Configuration“-Container des AD hinzu, der z. B. auf ein Skript verweist. Diese Technik setzt übrigens keine Schema-Erweiterung voraus, sondern lässt sich leicht angepasst für (fast) jedes beliebige AD-Attribut verwenden.
Ein Beispiel: Nehmen wir an, wir haben das AD um ein Attribut „Schuhgröße“ erweitert (Attributname: „sDemo-schuhgroesse“) und wollen für alle Mitarbeiter die Schuhgröße eintragen. Da scheiben wir zunächst ein kleines Skript, das per ADSI einen Wert in das Attribut „Schuhgröße“ des passenden Benutzers einträgt. Dieses Skript wird mit einem Kontextmenü aufgerufen.
Hier ein Script (als HTA [Hypertext Application], damit eine Oberfläche zur Verfügung steht – korrigierte Fassung vom 12. 9. 2005 mit Dank an Ulf B. Simon-Weidner), das eine Anzeige- und Eingabemöglichkeit vorsieht. Man beachte: Wenn ein Skript per Kontextmenü aufgerufen wird, erhält es den Namen (den DN) des Objekts als Argument übergeben. Dies wird in der Funktion „auswerten()“ ausgelesen.
- <HTML>
- <HEAD>
- <TITLE></TITLE>
- <HTA:APPLICATION ID=„oHTA“>
- <META NAME=„author“ CONTENT=„Nils Kaczenski“>
- </HEAD>
- <BODY onload=„start();“>
- <H2 id=„head“></H2>
- <TABLE>
- <TR>
- <TD>Benutzer:</TD>
- <TD><P id=„anzeige“></P></TD>
- </TR>
- <TR>
- <TD>Schuh[g]röße</TD>
- <TD><input id=„groesse“ accesskey=„g“></TD>
- </TR>
- <TR>
- <TD><button onclick=„eintragen();“ accesskey=„e“><U>E</U>intragen</button></TD>
- <TD><button onclick=„window.close();“ accesskey=„s“><U>S</U>chließen</button></TD>
- </TR>
- </TABLE>
- <BR clear=„all“><HR><P class=„klein“>© 2003/2005 Nils Kaczenski – keine Gewähr! Nutzung auf eigene Gefahr!</P>
- <SCRIPT language=„VBScript“>
- dim rootDSE
- dim objUsr
- dim strUser
- DNstrAdsPath = „“
- strTitel = „Demo von Nils Kaczenski“
- function auswerten()
- strText = oHTA.CommandLine
- ‚ CommandLine enthält, durch Blanks getrennt:
- ‚ – Pfad der HTA-Datei (in Anführungsstrichen)
- ‚ – LDAP-Pfad des AD-Objekts (fallweise mit Anführungsstrichen; inkl. Serverangabe)
- ‚ – Objektklasse
- ‚ Das macht die Auswertung etwas aufwändig:
- intPosUser = InStrRev(strText,“ user“)
- intPosLDAP = inStr(strText, „LDAP://“)
- if intPosUser <> 0 then
- ‚ist ein Benutzerobjekt
- auswerten = mid(strText, intPosLDAP, intPosUser – intPosLDAP)
- auswerten = replace(trim(auswerten),„“„“,„“)
- ‚ Jetzt sind Gänsefüßchen und Leerzeichen am Anfang/Ende weg
- ‚ auswertung enthält nur noch den distinguishedName,
- ‚ der weiter verwendet werden kann
- else
- msgBox „Kein User angegeben!“
- exit function
- end if
- end function
- sub start()
- ‚ Funktion:
- ‚ Eingabeparameter:
- ‚ Kommentar:
- window.resizeTo 400,200
- document.title = strTitel
- arrText = auswerten
- strUserDN = auswerten
- if strUserDN = „“ then
- document.all.anzeige.innerText = „keine Argumente“
- exit sub
- end if
- set rootDSE = GetObject(„LDAP://RootDSE“)
- strDomainname = rootDSE.Get(„defaultnamingcontext“)
- set domain = GetObject(„LDAP://“ & strDomainname)
- set objUsr = GetObject(strUserDN)
- strName = objUsr.get(„displayName“)
- document.title = strTitel & „: „ & strSamName
- on error resume next
- strSchuh = objUsr.get(„sDemo-schuhgroesse“)
- if err.number <> 0 then err.clear ‚ kein Eintrag da!
- on error goto 0
- document.all.anzeige.innerText = strName
- if strSchuh <> „“ then document.all.groesse.value = strSchuh
- end sub
- sub eintragen()
- ‚ Funktion:
- ‚ Eingabeparameter:
- ‚ Kommentar:
- if strUserDN = „“ then
- msgBox „Kein User angegeben!“
- exit sub
- end if
- strCheck = document.all.groesse.value
- if isNumeric(strCheck) then
- objUsr.Put „sDemo-schuhgroesse“, strCheck
- objUsr.SetInfo
- msgBox „Schuhgröße eingetragen!“, vbInformation, strTitle
- window.close
- else
- msgBox „Keine Zahl angegeben: „ & strCheck, vbCritical, strTitle
- end if
- end sub
- </SCRIPT>
- </BODY>
- </HTML>
Um das Skript per Kontextmenü aufzurufen, wird die AD-Konfiguration erweitert. Das folgende Skript erledigt dies. Es setzt voraus, dass das obige Skript mit dem Namen „schuhgroesse.hta“ in einem Ordner gespeichert wurde, der per PATH auflösbar ist (z. B. %systemroot%).
(Vgl. auch den Artikel: Registering a static context menu item.)
- Set root= GetObject(„LDAP://rootDSE“)
- strConfig = root.Get(„configurationNamingContext“)
- strPath = „LDAP://cn=user-Display,cn=407,cn=DisplaySpecifiers,“ & strConfig
- Set obj= GetObject(strPath)
- strValue = „5,Schuhgröße,schuhgroesse.hta“
- arrValue = Array(strValue)
- obj.PutEx 3, „adminContextMenu“, arrValue
- obj.SetInfo
- msgBox „Kontextmenüeintrag hinzugefügt: „ & strValue
Nun gibt es im Kontextmenü eines Benutzerkontos in den AD-Verwaltungsprogrammen den Kontextmenüpunkt „Schuhgröße“. Er ruft das Skript „schuhgroesse.hta“ auf. Dieses wiederum ermittelt den AD-Pfad des Benutzerkontos und versucht, den vorhandenen Wert für „sDemo-schuhgroesse“ zu lesen. Sollte einer vorhanden sein, wird er angezeigt. Ein neuer Wert kann eingetragen werden. (Vielen Dank an Alexander Maier für eine Korrektur.)
http://faq-o-matic.net/?p=569