Printout Header
RSS Feed

Objekte im Globalen Katalog suchen


In Tutorial Abschnitt "LDAP Objekte im Verzeichnis suchen (ADO)" wurde beschrieben, wie man allgemein aus einem Script heraus nach Verzeichnisobjekten sucht. Hier soll speziell gezeigt werden, wie man auf Objekte im Globalen Katalog zugreift. Bitte beachten: Im Globalen Katalog sind nur Lesezugriffe möglich, und es sind stehen nicht alle Attribute zur Verfügung. Man kann in der LDAP-Filter der Suche nur Attribute verwenden, die auch im Global Catalog enthalten sind!

 

Standard-Suche im Globalen Catalog
GC-Suche unter Angabe von speziellen Anmeldedaten
GC-Suche über LDAP SSL
GC-Suche, wenn der eigene Domänenname / Forest nicht bekannt ist



Standard-Suche im Globalen Catalog


Wir benutzen hier eine normale LDAP-Such-Operation, bei der LDAP-Pfad geändert wird, so dass der TCP-Port-Nummer 3268 verwendet wird. Darüber hinaus mußr eine andere LDAP Search Base gesetzt werden - es muß hier der DNS-Name der Root-Domäne (dies ist die Domäne, die in der AD-Gesamtstruktur wie die erste Domäne installiert wurde) als Search Base konfiguriert werden.

Wenn wir also einen Active Directory Forest mit der Root-Domäne 'cerrotorre.de' haben und wir eine Liste aller DCs im Forest erhalten wollen, dann würde die Suche ungefähr so aussehen:

filterStr = "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))" 'Suche nach DCs Set ado = CreateObject("ADODB.Connection") 'eine neue ADO Verbindung erzeugen ado.Provider = "ADSDSOObject" 'das ADSI Interface verwenden ado.Open "AD-Search" 'einen beliebigen Namen für die ADO Session vergeben Set adoCmd = CreateObject("ADODB.Command") 'ein neues ADO Kommando erzeugen adoCmd.ActiveConnection = ado 'Zuweisung zu einer existierenden ADO Session adoCmd.Properties("Page Size") = 1000 'Paged Result Wert auf 1000 setzen (AD Standard) adoCmd.Properties("Cache Results") = True adoCmd.CommandText = "<GC://cerrotorre.de>;" & filterStr & ";ADsPath;subtree" Set objectList = adoCmd.Execute 'Suche durchführen While Not objectList.EOF Set dc = GetObject(objectList.Fields("ADsPath")) 'mit gefundenen Objekten verbinden WScript.Echo dc.dnsHostName 'Output: FQDN der DCs objectList.MoveNext 'zum nächsten gefundenen Objekt Wend

Beachten Sie bitte, dass der LDAP Search String den man gewöhnlich verwendet (z.B. 'OU=accounts,DC=slefadsi,DC=org') ersetzt wird durch den DNS Namen der Root-Domäne (hier 'cerrotorre.de'). Der für diese Operation notwendige GC wird durch interne ADSI API Funktionen automatisch gefunden.


GC-Suche unter Angabe von speziellen Anmeldedaten


Die normale Methode der LDAP Verzeichnissuche funktioniert immer dann, wenn ich als angemeldeter User auf Objekte aus meiner eigenen Domäne bzw. aus meinem eigenen Active Directory Forest zugreifen will. Oft ist es jedoch notwendig, auf ein Verzeichnis-System zuzugreifen, bei dem man aktuell nicht als User authentifiziert ist. Hier ist die Angabe von zusätzlichen Anmeldedaten erforderlich. Und: Hier gibt es die Bind-Variante mit dem Befehl OpenDSObject, der die Übergabe von Username und Passwort erlaubt und so eine Anmeldung z.B. auch an fremde Forests ermöglicht.

Set dso = GetObject("LDAP:") 'dies wird später für den OpenDSObject Aufruf verwendet userName = "DOMAIN\userXYZ" 'setzen Sie hier Ihre eigenen Anmeldedaten password = "P@ssw0rd" filterStr = "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))" 'Suche nach nach DCs Set ado = CreateObject("ADODB.Connection") 'eine neue ADO Verbindung erzeugen ado.Provider = "ADSDSOObject" 'das ADSI Interface verwenden ado.Properties("User ID") = userName ado.Properties("Password") = password ado.Open "AD-Search" 'einen beliebigen Namen für die ADO Session vergeben Set adoCmd = CreateObject("ADODB.Command") 'ein neues ADO Kommando erzeugen adoCmd.ActiveConnection = ado 'Zuweisung zu einer existierenden ADO Session adoCmd.Properties("Page Size") = 1000 'Paged Result Wert auf 1000 setzen (AD Standard) adoCmd.Properties("Cache Results") = True adoCmd.CommandText = "<GC://cerrotorre.de>;" & filterStr & ";ADsPath;subtree" Set objectList = adoCmd.Execute 'Suche durchführen While Not objectList.EOF Set dc = dso.OpenDSObject(objectList.Fields("ADsPath"), userName, password, 1) 'mit gefundenen Objekten verbinden WScript.Echo dc.dnsHostName 'Output: FQDN der DCs objectList.MoveNext 'zum nächsten gefundenen Objekt Wend

In diesem Beispiel gibt die Suche die Distinguished Names aller Domänencontroller im Forest zurück. Wir verbinden uns mit den betreffenden Objekten mit einem OpenDSObject Aufruf, der letze Parameter (1) führt als Anmelde-Flag dazu, dass eine gesicherte Kerberos-Anmeldung stattfindet.

Voraussetzung hierbei ist natürlich, dass die Station von der aus der Script aufgerufen wird, den Domänennamen der Forest Root Domäne (hier 'cerotorre.de' in eine IP Adresse eines zuständigen DCs dieser Domäne auflösen kann. Indem die SRV-Records ausgelesen werden, die im DNS gespeichert sind, kann der globale Katalog Server mit internen ADSI API Funktionen automatisch gefunden werden.


GC-Suche über LDAP SSL


Man kann auch LDAP-SSL verwenden, wenn man sich den Globalen Katalog durchsuchen will. Dazu benutzt man einfach die TCP-Port-Nummer 3269 (statt 3268) auf. Allerdings klappt das nur, wenn der Server zuvor mit einem SSL-Zertifikat ausgestattet wurde.

Das Beipiel demonstriert, wie man nach allen deaktivierten Benutzerkonten im Forest sucht, und zwar über eine SSL-Verbindung:

filterStr = "(&(sAMAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=2))" 'suche nach deaktivierten Acounts Set ado = CreateObject("ADODB.Connection") 'eine neue ADO Verbindung erzeugen ado.Provider = "ADSDSOObject" 'das ADSI Interface verwenden ado.Open "AD-Search" 'einen beliebigen Namen für die ADO Session vergeben Set adoCmd = CreateObject("ADODB.Command") 'ein neues ADO Kommando erzeugen adoCmd.ActiveConnection = ado 'Zuweisung zu einer existierenden ADO Session adoCmd.Properties("Page Size") = 1000 'Paged Result Wert auf 1000 setzen (AD Standard) adoCmd.Properties("Cache Results") = True adoCmd.CommandText = "<LDAP://cerrotorre.de:3269>;" & filterStr & ";ADsPath;subtree" Set objectList = adoCmd.Execute 'Suche durchführen While Not objectList.EOF Set user = GetObject(objectList.Fields("ADsPath")) 'mit gefundenen Objekten verbinden WScript.Echo user.sAMAccountName & vbcrlf & " " & user.distinguishedName 'Output: User-Namen anzeigen lassen objectList.MoveNext 'zum nächsten gefundenen Objekt Wend

GC-Suche, wenn der eigene Domänenname / Forest nicht bekannt ist


Oft will man Skripte entwickeln, die in verschiedenen Active Directory Umgebungen laufen. Stellen Sie sich z.B. ein Skript vor, dass in der eigenen Domäne irgendwelche Infos zu diversen Objekten ausgibt oder spezielle Änderungen vornimmt. Damit das Skript in beliebigen Domänen läuft, könnte man natürlich den Domänen-Namen als Parameter übergeben lassen. Aber noch eleganter ist es, den Domänen-Namen zu ermiteln, indem man mit einem Serverless Binding das Active Directory selbst danach fragt.

Die entsprechenden Informationen stehen in einem speziellen Verzeichnis-Eintrag, der auf jedem Domänen-Controller zur Verfügung steht: dem rootDSE-Eintrag (Root Directory Service Entry).

Also ist dies ein Beispiel, wie man nach den deaktivierten Benutzern in demjenigen Forest sucht, an dem man gerade angemeldet ist:

Set aoi = CreateObject("ADSystemInfo") rootDNS = aoi.ForestDNSName filterStr = "(&(sAMAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=2))" 'Suche nach deaktivierten Accounts Set ado = CreateObject("ADODB.Connection") 'eine neue ADO Verbindung erzeugen ado.Provider = "ADSDSOObject" 'das ADSI Interface verwenden ado.Open "AD-Search" 'einen beliebigen Namen für die ADO Session vergeben Set adoCmd = CreateObject("ADODB.Command") 'ein neues ADO Kommando erzeugen adoCmd.ActiveConnection = ado 'Zuweisung zu einer existierenden ADO Session adoCmd.Properties("Page Size") = 1000 'Paged Result Wert auf 1000 setzen (AD Standard) adoCmd.Properties("Cache Results") = True adoCmd.CommandText = "<GC://" & rootDNS & ">;" & filterStr & ";ADsPath;subtree" Set objectList = adoCmd.Execute 'Suche durchführen While Not objectList.EOF Set user = GetObject(objectList.Fields("ADsPath")) 'mit gefundenen Objekten verbinden WScript.Echo user.sAMAccountName & vbcrlf & " " & user.distinguishedName 'Output: User-Namen anzeigen lassen objectList.MoveNext 'zum nächsten gefundenen Objekt Wend