Centrum Skryptów - Active Directory

Jak mapować dyski w oparciu o uczestnictwo w grupie usługi katalogowej Active Directory?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

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 mapować dyski w oparciu o uczestnictwo w grupie usługi katalogowej Active Directory?

Cześć Skrypciarze! Muszę zmapować dysk w oparciu o uczestnictwo użytkownika w określonej grupie usługi katalogowej Active Directory. Jest jednak pewna trudność: muszę zmapować dysk w zależności od tego, czy użytkownik jest menedżerem. Innymi słowy, muszę zmapować dysk na podstawie zarówno uczestnictwa w grupie, jak i stanowiska w firmie. Jak to zrobić?

-- SA

Cześć, SA. Zauważyliście pewnie, że od jakiegoś czasu nie narzekałem na reklamy telewizyjne. Dlaczego? Z jednego prostego powodu: poszedłem po rozum do głowy i przestałem tracić swój cenny czas oglądając telewizję w takim wymiarze, jak dawniej.

Nie, nic się nie stało; wcale nie myślałem, że ktoś mógłby w to uwierzyć. Prawdę mówiąc, oglądam tyle samo telewizji, co wcześniej, a może nawet więcej, ponieważ teraz wszystkie rowery w moim klubie sportowym mają telewizory. (Prawdziwa historia: od momentu, kiedy do każdego roweru gimnastycznego został zamontowany telewizor, nie raz byłem świadkiem sceny, w której ktoś zamiast ćwiczyć, po prostu siedział na tym rowerze i oglądał telewizję.) Nie będę jednak dzisiaj narzekał na żadną konkretną reklamę, nazbierało się tego tyle, że sam już nie wiem, na co powinienem narzekać najpierw. Ale najbardziej irytują mnie reklamy sieci sklepów spożywczych, środków piorących i w ogóle całej chemii. Najgorsze są jednak te przypadki, kiedy nagle widzę jakąś znaną osobę zachwalającą herbatę mrożoną bez konserwantów, albo namawiającą do wzięcia kredytu w określonym banku. Od razu odechciewa mi się pić jakichkolwiek herbat, a nazwę tego banku wymazuję z pamięci. Zauważyłem ponadto, że z wiekiem zaczyna mi się pogarszać, bo irytuje mnie coraz więcej reklam. Na razie lubię jeszcze reklamy samochodów, te mógłbym oglądać godzinami. Rety, ale się nakręciłem. W ogóle nie powinienem mówić nic na temat reklam, bo strasznie się przy tym denerwuję. Teraz, żeby się uspokoić i odzyskać wewnętrzną równowagę, muszę napisać jakiś skrypt.

Na przykład taki, który mapuje dysk w oparciu o uczestnictwo w grupie Active Directory i stanowisko:

On Error Resume Next



Set objADSysInfo = CreateObject("ADSystemInfo")

strUser = objADSysInfo.UserName



Set objUser = GetObject("LDAP://" & strUser)



For Each strGroup in objUser.memberOf

    Set objGroup = GetObject("LDAP://" & strGroup)

    If objGroup.CN = "Finance Department" Then

        strTitle = objUser.Title

        If strTitle = "Manager" Then

            Set objNetwork = CreateObject("Wscript.Network")

            objNetwork.MapNetworkDrive "X:", "\\atl-fs-001\public\managers"

        Else

            Set objNetwork = CreateObject("Wscript.Network")

            objNetwork.MapNetworkDrive "X:", "\\atl-fs-001\public\users"

        End If

        Exit For

    End If     

Next

Zobaczmy, jak on działa. Na początek, zakładam, że ten skrypt ma być skryptem logowania. Tak naprawdę, to nawet musi być skrypt logowania; jest tak dlatego, że nie ma prostej i bezpośredniej metody mapowania dysków na zdalnych komputerach.

Uwaga. Czy to oznacza, że istnieje bardziej skomplikowana i nie-do-końca bezpośrednia metoda mapowania dysków na zdalnych komputerach? Na pewno; jeżeli chcecie czegoś bardziej skomplikowanego i nie-do-końca bezpośredniego, możecie zrobić prawie wszystko. Więcej informacji na temat mapowania dysków na zdalnych komputerach znajduje się w tym archiwalnym artykule rubryki Cześć Skrypciarze.

Ponieważ to jest skrypt logowania, zaczynamy od utworzenia wystąpienia obiektu ADSystemInfo, który przekaże nam informacje o zalogowanym użytkowniku, lokalnym komputerze oraz lokalnej domenie. Jakie informacje przekazuje obiekt ADSystemInfo? No cóż, mówi nam, jaka jest nazwa wyróżniająca DN zalogowanego użytkownika. Za pomocą poniższego wiersza kodu pobieramy nazwę DN dla zalogowanego użytkownika i zachowujemy ją w zmiennej o nazwie strUser:

strUser = objADSysInfo.UserName

Jak zapewne wiecie, nazwa DN informuje nas o „adresie” bieżącego konta użytkownika w grupie usługi katalogowej Active Directory, a to dlatego, że wygląda ona tak:

CN=Ken Myer,OU=Europe,DC=fabrikam,DC=com

Jeżeli chcemy połączyć się tym kontem użytkownika (a chcemy; to jedyny sposób, żeby określić do której grupy należy użytkownik), wystarczy dodać LDAP:// na początku wartości zmiennej strUser, a następnie przekazać tę wartość (tak się składa, że jest to ścieżka ADsPath użytkownika) do metody Get-Object. Innymi słowy, musimy zastosować następujący wiersz kodu:

Set objUser = GetObject("LDAP://" & strUser)

Być może wiecie także, że każde konto użytkownika w usłudze katalogowej Active Directory posiada atrybut o nazwie memberOf; jak sama nazwa wskazuje, ten atrybut zawiera listę wszystkich grup, do których należy użytkownik. To oznacza, naszym następnym zadaniem jest przejść przez tę listę grup i określić, czy użytkownik jest uczestnikiem danej grupy (oraz określić, czy dany użytkownik jest menedżerem). Jak to zrobimy? Cóż, na początek uruchomimy pętlę For Each, która przeprowadzi nas przez każdą z grup znajdujących się w atrybucie memberOf:

For Each strGroup in objUser.memberOf

Każda grupa, do której należy użytkownik, jest zachowana w atrybucie memberOf nazwy DN danej grupy. (Dokładnie tak, grupy także posiadają nazwy DN; a tak naprawdę, praktycznie wszystkie elementy w usłudze Active Directory posiadają nazwę DN.) A ponieważ praca z nazwami DN wcale nie jest zabawna, naszym następnym krokiem jest zastosowanie poniższego wiersza kodu w celu bezpośredniego połączenia się z kontem grupy w usłudze katalogowej Active Directory:

Set objGroup = GetObject("LDAP://" & strGroup)

Dlaczego łączymy się z kontem grupy? No cóż, jak wiecie, w tym momencie nasza pętla przechodzi przez wszystkie grupy, do których należy użytkownik i staramy się określić, czy dany użytkownik jest uczestnikiem określonej grupy (w tym przypadku grupy Finance Department). Gdybyśmy chcieli, moglibyśmy to zrobić określając, czy któraś z grup użytkowników ma określoną nazwę DN:

If strGroup = "CN=Finance Department,OU=Finance,OU=North America,DC=fabrikam,dc=com" Then

To działa, ale delikatnie mówiąc jest trochę kłopotliwe. Dlatego też, żeby ułatwić sobie życie, łączymy się z kontem grupy i pobieramy wartość atrybutu CN. To z kolei umożliwia nam napisanie instrukcji If-Then, wyglądającej tak:

If objGroup.CN = "Finance Department" Then

To jest dużo prostszy sposób.

Uwaga. Inne korzyści wynikające z połączenia się z kontem grupy. Istnieje duże prawdopodobieństwo, że kiedy zasiadamy do pisania skryptu, znamy już nazwę CN grupy (Finance Department). Mniej prawdopodobne jest, że zapamiętaliśmy nazwy DN dla wszystkich grup usługi katalogowej Active Directory. (Jeżeli zapamiętaliście nazwy DN dla wszystkich grup usługi Active Directory… bez komentarza.)

Co robimy, jeżeli pierwsza grupa w kolekcji nie posiada nazwy CN Finance Department? Nic nie szkodzi; w takim wypadku wracamy na początek pętli i próbujemy jeszcze raz z następną grupą. Jeżeli okaże się, że żadna z grup nie ma nazwy CN Finance Department, to też nic się nie stanie: będzie to tylko oznaczać, że użytkownik nie jest uczestnikiem grupy Finance Departament. W takim przypadku, skrypt zakończy działanie i żaden dysk nie zostaje zmapowany.

Ale załóżmy, że jedna z grup naprawdę posiada nazwę CN Finance Department. W tym przypadku, stosujemy następujące dwa wiersze kodu:

strTitle = objUser.Title

If strTitle = "Manager" Then

W wierszu 1 pobieramy wartość atrybutu Title użytkownika i zachowujemy ją w zmiennej o nazwie strTitle; w wierszu 2, sprawdzamy , czy atrybut Title (stanowisko) ma wartość Manager.

Co się stanie, jeżeli dany użytkownik jest menedżerem? Cóż, w takim przypadku jego dysk X zostanie zmapowany do \\atl-fs-001\pubic\managers:

Set objNetwork = CreateObject("Wscript.Network")

objNetwork.MapNetworkDrive "X:", "\\atl-fs-001\public\managers"

Co się natomiast stanie, jeżeli użytkownik jest uczestnikiem grupy Finance Departament, ale nie jest menedżerem? Dysk zostanie zmapowany do \\atl-fs-001\public\users:

Set objNetwork = CreateObject("Wscript.Network")

objNetwork.MapNetworkDrive "X:", "\\atl-fs-001\public\users"

Tak czy inaczej, dysk X zostanie zmapowany. Następnie wywołamy instrukcję Exit For w celu opuszczenia pętli i zakończymy działanie skryptu.

Chyba nie muszę dodawać, że ten skrypt sprawdza uczestnictwo i jednej grupie (Finance Department), a potem sprawdza, czy użytkownik jest (lub nie jest) menedżerem. Można jednakże tak zmodyfikować skrypt, żeby sprawdzał w innych grupach lub sprawdzał inne stanowiska. Wystarczy skopiować, wkleić i ulepszyć różne części skryptu według potrzeby. Przykładowo, poniższy zmodyfikowany skrypt sprawdza, czy użytkownik jest uczestnikiem grupy Finance Department lub uczestnikiem grupy Human Resources Department:

If objGroup.CN = "Finance Department" Then

    strTitle = objUser.Title

    If strTitle = "Manager" Then

        Set objNetwork = CreateObject("Wscript.Network")

        objNetwork.MapNetworkDrive "X:", "\\atl-fs-001\public\managers"

    Else

        Set objNetwork = CreateObject("Wscript.Network")

        objNetwork.MapNetworkDrive "X:", "\\atl-fs-001\public\users"

    End If

    Exit For



ElseIf objGroup.CN = "Human Resources Department" Then



    strTitle = objUser.Title

    If strTitle = "Manager" Then

        Set objNetwork = CreateObject("Wscript.Network")

        objNetwork.MapNetworkDrive "X:", "\\atl-fs-001\public\hrmanagers"

    Else

        Set objNetwork = CreateObject("Wscript.Network")

        objNetwork.MapNetworkDrive "X:", "\\atl-fs-001\public\hrusers"

    End If

    Exit For



End If

Dobre pytanie: co się dzieje, jeżeli użytkownik jest uczestnikiem obydwu grup? Cóż, w takim przypadku, dysk użytkownika zostanie zmapowany w oparci o grupę, która zostanie napotkana jako pierwsza. (Czyli która pojawi się jako pierwsza w pętli For Each.) Jeżeli to stanowi jakiś problem (czyli jeżeli użytkownik jest uczestnikiem grupy A oraz grupy B i chcemy, żeby grupa A miała pierwszeństwo), można zmodyfikować skrypt tak, aby śledził docelowe grupy, do których należy użytkownik i napisać skrypt wybierający „najlepsza” z grup z tej kolekcji. Ale o tym, jak to zrobić, opowiem Wam innym razem.

Jutro? Zobaczymy.

 Do początku strony Do początku strony

Centrum Skryptów - Active Directory