fragen stichworte

Holen Sie sich die oberste Organisationseinheit von einem AD-Benutzer

Ich frage diese Frage hauptsächlich, um zu fragen, ob es einen besseren Weg gibt, um das zu erledigen, was ich arbeite. Ich möchte auch wissen, ob jemand Probleme hat, diese Informationen auf diese Weise zu erhalten.

Ich versuche, die Organisationseinheit auf oberster Ebene, in der sich ein Benutzer befindet, und alle Organisationseinheiten auf niedrigerer Ebene abzurufen. Das Hauptproblem ist, dass wir mehrere Standorte haben, von denen einige mehrere Ebenen von Organisationseinheiten für Benutzerkonten (ou=doctors,ou=Users,ou=Site,dc=example,dc=com) haben, und einige Websites, die nur eine einzige Organisationseinheit (ou=Users,ou=Site,dc=example,dc=com) haben. Ich habe das folgende Skript verwendet, um den DN-Pfad abzurufen, zu teilen und ihn mit den letzten drei Teilen rückwärts aufzubauen. Kann irgendjemand Probleme damit sehen? Etwas fühlt sich einfach falsch an ...

$user = Get-ADUser CKnutson
$user.DistinguishedName
# Returns: CN=Cory Knutson,OU=IT,OU=Users,OU=Site,DC=example,DC=com

$split = $user.DistinguishedName.Split(',')
$path = "$($split[-3]),$($split[-2]),$($split[-1])"

Write-Host $path
# Returns: OU=Site,DC=example,DC=com

Um es einfach auszudrücken, war es das Endziel für mich, den Pfad zu der Organisationseinheit "Deaktiviert" zu finden, die wir gerade in jeder der Organisationseinheiten "Site" haben. Daher konnte mein Skript das Objekt verschieben, wenn das Konto an der richtigen Stelle in der obersten Organisationseinheit dieser Site (OU=Disabled,OU=Site,DC=example,DC=com) deaktiviert wurde.

antworten

Can anyone see any issues with doing it this way.

Ja, ich sehe zwei unmittelbare Probleme, die sich aus Ihrem derzeitigen Ansatz ergeben können.


1. Entkommene Kommas

Betrachten Sie eine Organisationseinheit mit einem Komma in ihrem Namen, beispielsweise: OU=Users\\, Admin,DC=corp,DC=example

Ihre Verwendung von string.Split() kümmert sich nicht um die Escape-Sequenz und Sie enden mit:

Admin,DC=corp,DC=example

Verwenden Sie den Regex-Operator -split mit einem Lookbehind, um sicherzustellen, dass Sie die Escape-Kommas ignorieren:

$parts = $user.DistinguishedName -split '(?<!\\\\),'

2. Portabilität

Ihr Code geht davon aus, dass der NC-Teil des DN (z. B. DC=example,DC=com) immer nur 2 Etiketten breit ist. Dies bedeutet, dass Ihr Code fehlschlägt, wenn Sie ihn in Skripts verwenden, die Sie möglicherweise in anderen Domänen/Umgebungen wiederverwenden möchten.

Ich würde jeden Teil von rechts nach links nehmen, bis ich ein ohne das DC RDN-Präfix finde:

$topParts = foreach($part in $parts[-1..-$parts.Length]){
    $part
    if($part -notlike 'DC=*'){
        break
    }
}
# Remember to reverse the RDNs again
$path = $topParts[-1..-$topParts.Length] -join ','

Meiner Meinung nach ist es einfacher, das Pfadname-COM-Objekt zu verwenden und einfach nach dem übergeordneten Element des DN zu fragen. Sie können dies in eine while -Schleife schreiben, um die Hierarchie des Objekts abzurufen. Beispiel mit meinem ADName -Modul:

$dn = Get-ADUser user | Select-Object -ExpandProperty DistinguishedName
$parent = $dn | Get-ADName -Format Parent
while ( $parent -like "OU=*" ) {
  $parent
  $parent = $parent | Get-ADName -Format Parent
}

Beispielausgabe:

OU=Level 3,OU=Level 2,OU=Level 1,DC=fabrikam,DC=com
OU=Level 2,OU=Level 1,DC=fabrikam,DC=com
OU=Level 1,DC=fabrikam,DC=com

Sie suchen also den DN des Pfads zum Konto? Sie können dies mit einem regulären Ausdruck tun, der das (?) Ungreedy-Qualifikationsmerkmal verwendet. Es gibt keine Aufteilung, also sind Kommas mit Komma kein Problem.

"CN=Cory Knutson,ou=doctors,ou=Users,ou=Site,dc=example,dc=com" -match ".+?,(OU=.+)"
$matches[1]
ou=doctors,ou=Users,ou=Site,dc=example,dc=com

"CN=Knutson\, Cory,ou=doctors,ou=Users,ou=Site,dc=example,dc=com" -match ".+?,(OU=.+)"
$matches[1]
ou=doctors,ou=Users,ou=Site,dc=example,dc=com

"CN=Cory Knutson,ou=Site,dc=example,dc=com" -match ".+?,(OU=.+)"
$matches[1]
ou=Site,dc=example,dc=com

Bearbeiten
Ich war aus dem Satz the top level OU that a user is in, and any lower level OUs. nicht klar. Sie können dies auch tun:

$dn = "CN=Cory Knutson,ou=doctors,ou=Users,ou=Site,dc=example,dc=com"
$last = ($dn.toUpper()).lastIndexOf("OU=")
$dn.substring($last)
ou=Site,dc=example,dc=com