Centrum skryptów - Systemy operacyjne

Jak mogę określić, czy członek grupy to użytkownik, komputer, czy inna grupa? 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ć, czy członek grupy to użytkownik, komputer, czy inna grupa?

Cześć, Skrypciarzu! W jaki sposób mogę określić, czy członek grupy to użytkownik, komputer, czy inna grupa?

-- ON

Cześć, ON. To ciekawe pytanie, ale, szczerze mówiąc, nigdy się nad tym nie zastanawialiśmy. Nietrudno jest wywołać listę wszystkich członków grupy; poniżej znajduje się skrypt powodujący wyświetlenie listy członków grupy Finance Managers:

Set objGroup = GetObject _

    ("LDAP://cn=Finance Managers, ou=Finance, dc=fabrikam, dc=com")



For Each strUser on objGroup.Member

        Wscript.Echo strUser

Next

Uruchomienie tego skryptu powoduje wyświetlenie wartości atrybutu distinguishedName (DN – nazwa wyróżniona) każdego z członków grupy; wynik będzie wyglądał w ten sposób:

cn=atl-ws-01, ou=Finance, dc=fabrikam, dc=com

cn=Ken Myer, ou=Finance, dc=fabrikam, dc=com

cn=North American Finance Users, ou=Finance, dc=fabrikam, dc=com

cn=Pilar Ackerman, ou=Finance, dc=fabrikam, dc=com

Co jest zatem nie tak z tym skryptem? No cóż, niby nic, ale na podstawie samej nazwy może być ciężko określić, czy dany członek grupy to użytkownik, komputer, czy podgrupa. Oprócz tego, być może chodzi Ci o to, by skrypt podejmował określone działania w zależności od rodzaju członka grupy; na przykład, chcesz, by w przypadku znalezienia podgrupy uruchamiana była funkcja rekursywna pobierająca i wyświetlająca listę członków tej z kolei grupy. Żeby to było jednak możliwe, konieczne jest określenie, czy interesujący nas członek grupy jest w istocie podgrupą.

Jak zatem odróżnić użytkowników od komputerów, a grupy od wszystkiego innego? Okazuje się, że wszystkie obiekty Active Directory posiadają atrybut o nazwie Class - klasa. (Tak tak, w Active Directory nawet Skrypciarze mają klasę!) Znając atrybut Class, możemy określić o jaki rodzaj obiektu chodzi: o użytkownika, komputer, grupę, czy coś innego. Wystarczy zbadać wartość tego atrybutu.

Ale nie spodziewacie się chyba, że nie będzie haczyka? Otóż, wyliczanie członków grupy powoduje podanie jedynie nazwy wyróżnionej danego obiektu; atrybut Class nie jest podawany. Oznacza to, że nie można tak po prostu wyliczyć członków grupy i odpowiadających im klas. Trzeba połączyć się z kontem Active Directory każdego użytkownika i wywołać echo wartości atrybutu Class. Nie martwcie się jednak. To proste.

Spójrzmy na skrypt powodujący wyświetlenie członków grupy Finance Managers i odpowiadających im klas:

"Select * from CIM_Datafile Where Name = 'c:\\windows\\system32\\scrrun.dll'"

W całej ścieżce używamy znaków \\. Jest to konieczne, bo pojedynczy znak \ jest zastrzeżony w WMI, więc chcąc użyć go w wyrażeniu typu Where musimy poprzedzić go drugim znakiem \. Nic wielkiego, ale trzeba o tym pamiętać.

Teraz skrypt jest już zupełnie prosty. Skrypt przykładowy podaje informacje o pliku Scrrun.dll na komputerze lokalnym. W celu uzyskania tych informacji z komputera zdalnego należy zmienić wartość zmiennej strComputer. I tak, poniższy wiersz kodu przypisuje tej zmiennej wartość atl-ws-01:

Set objGroup = GetObject _

    ("LDAP://cn=Finance Managers, ou=Finance, dc=fabrikam, dc=com")



For Each strUser on objGroup.Member

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

    Wscript.Echo objMember.CN & ", " & objMember.Class

Next

No właśnie, wystarczyło kilka dodatkowych wierszy kodu. Najpierw łączymy się z grupą Finance Managers w Active Directory. Po połączeniu używamy pętli For Each, by przejść przez wszystkie wartości atrybutu Member (który posiada kilka wartości). Atrybut ten zawiera nazwy wyróżnione wszystkich członków grupy, więc dzięki pętli uzyskamy…no, właśnie nazwy wyróżnione wszystkich członków grupy.

Zanim ktoś zapyta: tak, też uważamy, że nazwa atrybutu powinna brzmieć Members, z literką –s oznaczającą liczbę mnogą na końcu. Ale wcale tak nie jest.

Gdyby zależało nam tylko na nazwie wyróżnionej każdego z członków grupy, na tym moglibyśmy poprzestać. Ale potrzebna nam jest jeszcze wartość atrybutu Class. Dlatego też w każdej pętli For Each łączymy się z kontem Active Directory każdego z członków grupy. Zajmuje się tym poniższy wiersz kodu:

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

W celu połączenia się z obiektem Active Directory musimy określić jego ścieżkę ADsPath. Ścieżka ta składa się z nazwy providera ADSI (w przypadku Active Directory jest to zawsze LDAP://) oraz nazwy wyróżnionej obiektu. Znamy już nazwę – jest ona przechowywana w zmiennej strUser. Wystarczy więc dodać wartość tej zmiennej do fragmentu LDAP:// i przekazać tę wartość metodzie GetObject. Dzięki temu metoda GetObject połączy nas z kontem Active Directory.

Jasne? Jasne.

Po połączeniu z kontem możemy wywołać echo wartości dowolnego z jego atrybutów. W naszym przykładowym skrypcie wywołujemy po prostu echo wartości atrybutów CN i Class (rozdzielając je przecinkiem); uzyskujemy wynik podobny do poniższego:

atl-ws-01, computer

Ken Myer, user

North American Finance Users, group

Pilar Ackerman, user

I o to chodziło: widzimy teraz czarno na białym, do jakiej klasy należy każdy członek grupy. Zwykle nikt nam nie wierzy kiedy mówimy, że skrypty są proste, ale teraz mamy na to dowód!

 Do początku strony Do początku strony


Centrum skryptów - Systemy operacyjne