Centrum skryptów - Active Directory

Jak mogę określić, do jakiej jednostki organizacyjnej (OU – organizational unit) należy konto użytkownika? Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Cześć Skrypciarze!

Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy.

Jak mogę określić, do jakiej jednostki organizacyjnej (OU – organizational unit) należy konto użytkownika?

Cześć Skrypciarzu! Jak mogę określić, do jakiej jednostki organizacyjnej (OU) należy konto użytkownika?

-- CO

Cześć CO! Ach tak: do jakiego OU należy użytkownik. Bez wątpienia wielu z Was myśli sobie: "Cóż, na pewno jest jakaś właściwość OU w Active Directory, która podaje tą informację. Wystarczy tylko zlokalizować konto użytkownika, a potem zdobyć wartość właściwości OU."

Brzmi to tak sensownie, że – jak zapewne zdążyłeś zgadnąć – wcale tak nie jest. Jak się okazuje, w Active Directory nie ma właściwości OU (ani żadnego jej odpowiednika). Ale nie ma powodów do niepokoju. To wcale nie znaczy, że nie możemy określić OU użytkownika; oznacza to tylko tyle, że żeby to osiągnąć, musimy – niestety – bardziej popracować.

Na użytek tego artykułu zakładamy, że nie znasz nazwy wyróżniającej użytkownika; bądź co bądź z nazwy wyróżniającej w rodzaju: CN=kenmeyer (Common Name – nazwa obiektu), OU=finance, DC=fabrikam, DC=com (Domain Controller – kontroler domeny) nawet Skrypciarz byłby w stanie wydedukować, do jakiej OU należy użytkownik. Zakładamy zatem, że znana jest nam jedynie nazwa SAM (Security Account Manager – menedżer bezpieczeństwa konta) konta użytkownika, czyli nazwa, której on/ona zazwyczaj używa logując się do domeny.

Jeśli znasz nazwę SAM konta użytkownika, to masz szczęście; to dlatego, że w lesie Active Directory nazwy te muszą być unikalne. Dzięki temu możemy znaleźć tego użytkownika poprzez wyszukiwanie Active Directory:

On Error Resume Next



Const ADS_SCOPE_SUBTREE = 2



Set objConnection = CreateObject("ADODB.Connection")

Set objCommand =   CreateObject("ADODB.Command")

objConnection.Provider = "ADsDSOObject"

objConnection.Open "Active Directory Provider"

Set objCommand.ActiveConnection = objConnection



objCommand.Properties("Page Size") = 1000

objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 



objCommand.CommandText = _

    "SELECT distinguishedName FROM 'LDAP://dc=fabrikam,dc=com' WHERE objectCategory='user' " & _

        "AND sAMAccountName='kenmyer'"

Set objRecordSet = objCommand.Execute



objRecordSet.MoveFirst

Do Until objRecordSet.EOF

    Wscript.Echo objRecordSet.Fields("distinguishedName").Value

    objRecordSet.MoveNext

Loop

Jak zaznaczyliśmy wcześniej, przeprowadzenie wyszukiwania Active Directory jest dość trudne, mimo że skrypt nie jest zbyt długi ani przesadnie skomplikowany. Więcej informacji znajdziesz w naszym webcaście (j.ang.).

Bez wdawania się w szczegóły, przeszukaliśmy tu po prostu domenę fabrikam.com w poszukiwaniu użytkownika o nazwie konta SAM (sAMAccountName) kenmeyer; kiedy tylko go znajdujemy, tworzymy echo jego nazwy wyróżniającej (atrybut distinguishedName). Znając formę CN=kenmeyer, OU=finance, DC=fabrikam, DC=com, spoglądamy na rezultaty i określamy OU użytkownika.

Po prawdzie jednak to jesteśmy zbyt leniwi, żeby patrzeć na nazwę wyróżniającą użytkownika; chcemy, żeby skrypt zrobił to za nas. Wprowadźmy więc niewielką modyfikację do naszej pętli Wykonaj (Do). Oto zmodyfikowany kod, za chwilę wyjaśnimy szczegóły:

Do Until objRecordSet.EOF

    strDN = objRecordSet.Fields("distinguishedName").Value

    arrPath = Split(strDN, ",")

    intLength = Len(arrPath(1))

    intNameLength = intLength - 3

    Wscript.Echo Right(arrPath(1), intNameLength)

    objRecordSet.MoveNext

Loop

Nie wiesz co siędzieje? Bez paniki, tak naprawdę to ma sens. Ponownie zaczynamy od uzyskania wartości nazwy wyróżniającej użytkownika; jak już wiemy, będzie to coś w rodzaju CN=kenmeyer, OU=finance, DC=fabrikam, DC=com. Przechowujemy tę wartość w zmiennej strPath, a następnie używamy komendy VBScript Split (podziel), aby, cóż, podzielić strPath na elementy tablicy. Gdy użyjemy komendy Split i podzielimy po przecinku (tzn. wskazujemy, że przecinek jest ogranicznikiem, znakiem rozdzielającym elementy indywidualne w ciągu), otrzymamy tablicę, składającą się z następujących elementów:

CN=kenmyer 

OU=Finance

DC=fabrikam

DC=com

Wiemy, że drugi element tablicy (drugi element tablicy zawsze ma numer indeksu 1) to OU, w którym znajduje się konto użytkownika. Oznacza to, że aby uzyskać nazwę OU, wystarczy nam drugi element tablicy (arrPath(1)) i pozbycie się fragmentu "OU=".

Czy możemy to zrobić? Oczywiście. Używamy funkcji Len (Lenght – długość) do określenia liczby znaków w elemencie 0 naszej tablicy. Pamiętaj, że wartość brzmi OU=Finance, zatem liczba znaków wynosi 10.

Następnie od liczby znaków odejmujemy 3. Po co? Cóż, chcemy się pozbyć „OU=”, czyli właśnie trzech znaków. Odjęcie 3 od 10 pozostawia nam 7, co oznacza, że nazwa OU – Finance – ma 7 znaków długości.

Teraz używamy funkcji Right (prawy), aby uzyskać ostatnich 7 znaków w ciągu; innymi słowy, zaczynamy od e w OU=Finance i cofamy się o 7 znaków. I wiesz co? Zgadłeś: tak się składa, że ostatnich 7 znaków w OU=Finance tworzy słowo Finance, nazwę OU, w którym znajduje się konto użytkownika. Hej, udało nam się!

Oto poprawiony skrypt, który przeszukuje Active Directory i podaje w odpowiedzi OU, w którym znajduje się konto użytkownika:

Const ADS_SCOPE_SUBTREE = 2



Set objConnection = CreateObject("ADODB.Connection")

Set objCommand =   CreateObject("ADODB.Command")

objConnection.Provider = "ADsDSOObject"

objConnection.Open "Active Directory Provider"

Set objCommand.ActiveConnection = objConnection



objCommand.Properties("Page Size") = 1000

objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 



objCommand.CommandText = _

    "SELECT distinguishedName FROM 'LDAP://dc=fabrikam,dc=com' “ & _

        "WHERE objectCategory='user' " & _

            "AND sAMAccountName='kenmyer'"

Set objRecordSet = objCommand.Execute



objRecordSet.MoveFirst

Do Until objRecordSet.EOF

    strDN = objRecordSet.Fields("distinguishedName").Value

    arrPath = Split(strDN, ",")

    intLength = Len(arrPath(1))

    intNameLength = intLength - 3

    Wscript.Echo Right(arrPath(1), intNameLength)

    objRecordSet.MoveNext

Loop

 Do początku strony Do początku strony


Centrum skryptów - Active Directory