PowerShell und LDAP, GC

Seit es die Windows AD Commandlets mit "Get-ADUSER" und anderen Commandlets gibt, könnten sie es als überflüssig ansehen, per LDAP direkt die Domaincontroller abzufragen. Die AD-Commandlets nutzen ja nicht mal die LDAP-Ports 389/TCP, 636/TLS, oder 3268/TCP für den GC sondern einen "WebService", der vom DC für die Clients bereit gestellt wird. Das ist einfach, "Cloud-Tauglich" aber nicht immer schnell.

Diese Seite beschränkt sich auf Code-Beispiele für PowerShell, auf die ich selbst ach immer mal wieder zurückgreifen.

ADSI und PowerShell

Natürlich kann man auch per PowerShell über das ADSI-Kürzel direkt auf Objekte zugreifen.

$objUser = [adsi]"LDAP://cn=user1,ou=Anwender,dc=msxfaq,dc=de"

Wichtig ist hier die genaue Schreibweise mit LDAP in Großbuchstaben und "//"-Zeichen. Ein paar sehr gute Anleitungen gibt es auf:

GC Suche mit Powershell

Für die Powershell habe ich auch ein Beispiel. Hier ist ein Codeschnipsel, mit dem ich einfach den GC finde und befrage und danach zu jedem Objekt ein Feld ausgeben lasse

$root = [system.directoryservices.activedirectory.forest]::getcurrentforest().rootdomain.name
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]"GC://$root")
#$objSearcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]"GC://$root",$sourceuser,$sourcepass)
$objSearcher.PageSize = 1000
$objSearcher.Filter = "(&(mail=*))"
$objSearcher.PropertiesToLoad.Add("mail") | Out-Null
$objSearcher.PropertiesToLoad.Add("ProxyAddresses") | Out-Null


$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults) {
    $mail = $objResult.properties.mail[0]
    write-host "Processing $mail"
    $adobject = [adsi]$objResult.path
    write-host "Bound " + $adobject.displayname
}

Natürlich kann man mit dem Directory Searcher auch "schmutzig" programmieren und mit einer Zeile ein Objekt instanziieren, Suchbedingungen vorgeben und das Ergebnis erhalten:

(New-Object System.DirectoryServices.DirectorySearcher("Samaccountname=Administrator")).findone()

Schauen Sie sich einfach die verschiedenen Overloads für die Instanzierung des Objekts an. Interessant ist in dem Zuge auch ein weiterer Accelerator, der den Code noch weiter verkürzt.

([adsisearcher]"Samaccountname=Administrator").findone()

Allerdings nutzt dieser Searcher dann wieder nur die Default Domäne des angemeldeten Benutzers und keinen GC. Um dies zu ändern, muss man aber nun New-Object verwenden, da ADSISEARCHER keine erweiterten Konstruktoren kann.

(New-Object System.DirectoryServices.DirectorySearcher([ADSI]"GC://servername","Samaccountname=Administrator")).findone()

So geht es dann auch schnell und relativ schmutzig. Zugegeben, ein Zugriff per Get-ADUser aus den Windows 2008 Commandlets ist strukturierter aber leider auch viel langsamer, da diese Commandlets die Active Directory Web Services nutzen. Aber dafür funktionieren Sie auch über HTTP/HTTPS und benötigen keine direkte LDAP-Verbindung.

Weitere Links

Sehr viele Beispiele und Tools auf dieser Webseite nutzen VBScript und ADSI, um bestimmte Tätigkeiten durchzuführen.