Centrum skryptów - Systemy operacyjne

Jak wymusić na użytkownikach jednostki OU zmianę hasła podczas następnego logowania?

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 wymusić na użytkownikach jednostki OU zmianę hasła podczas następnego logowania?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Jak napisać skrypt, który wymusi na wszystkich użytkownikach w jednostce OU zmianę hasła podczas następnego logowania?

-- TH

Cześć Skrypciarze! Odpowiedź

Cześć, TH. To nie jest dobry dzień na zadawanie pytań; piszący te słowa Skrypciarz jest w jeszcze gorszym nastroju niż zwykle (chociaż pewnie trudno to sobie wyobrazić). Kilka tygodni temu Skrypciarze zdecydowali, że skoro pogoda się powoli poprawia, a jedzenie w kantynie Microsoftu – pogarsza, to raz w tygodniu – to, co teraz powiem to ścisła tajemnica – będą wychodzić z firmy w porze lunchu i jeść w prawdziwej restauracji. W związku z tym postanowieniem, przekupili strażników, podwędzili kilka uniformów pracowników pralni i wykopali tunel prowadzący z ich budynku ku wolności.

Uwaga. Czyż nie byłoby prościej po prostu wyjść głównym wyjściem i pójść na lunch w porze obiadowej? No jasne, teraz nam to mówią.

A skoro już o tym mowa, to w Microsoft nie ma strażników. Ciekawe zatem kim byli ci goście, których przekupiliśmy?

Tak, czy inaczej, dzisiaj jest dzień, w którym mieliśmy iść na prawdziwy lunch. Jednak kierownik zwołał spotkanie zespołu właśnie w momencie, gdy Skrypciarze planowali wejść do tunelu i wydostać się z firmy. (Ważne jest, żeby wyjść we właściwym momencie, kiedy reflektory skierowane są w przeciwnym kierunku, a psy patrolują drugą stronę kampusu.) Oznacza to, że zamieniamy frytki i prawdziwego hamburgera na dyskusję o działaniach zespołu. Hura!

W każdym razie, piszący te słowa Skrypciarz jest w podłym nastroju. Początkowo chciał wyrazić swoje niezadowolenie odmawiając odpowiedzi na pytanie TH. To jednak nie byłoby w porządku. To nie przez TH Skrypciarze nie poszli na lunch. W konsekwencji, piszący te słowa Skrypciarz postanowił wdrożyć plan B: rozpocząć strajk głodowy na znak protestu przeciwko dzisiejszemu zebraniu zespołu. To było jednak zanim dowiedział się, że podczas strajku głodowego nie wolno nic jeść. (To jakieś szaleństwo!) Przez krótką chwilę rozważał więc wdrożenie planu C, ale kolejny plan to już za dużo roboty. Dlatego też postanowił po prostu odpowiedzieć na pytanie TH i na tym zakończyć kwestię:

Set objOU = GetObject("LDAP://ou=Accounting,dc=fabrikam,dc=com")

objOU.Filter = Array("user")



For Each objUser in objOU

    objUser.pwdLastSet = 0

    objUser.SetInfo

Next

Jak widać, to bardzo prosty skrypcik. (Mówiliśmy, że odpowiemy na pytanie, a nie że włożymy w to dużo pracy.) Na początek łączymy się z wybraną jednostką OU w Active Directory; w naszym przypadku jest to jednostka Accounting w domenie fabricam.com:

Set objOU = GetObject("LDAP://ou=Accounting,dc=fabrikam,dc=com")

Otrzymujemy wiele pytań tego typu: jak zastosować coś dla wszystkich kont użytkowników/ komputerów/grup w wybranej jednostce OU. Ludziom się wydaje, że musi to być bardzo skomplikowane i wymaga niewiarygodnych umiejętności skrypciarskich oraz dogłębnej znajomości Active Directory. Tak naprawdę to bardzo proste zadanie. Kiedy łączymy się z jednostką OU w Active Directory, domyślnie otrzymujemy kolekcję wszystkich elementów zachowanych w danym katalogu. Gdybyśmy chcieli wywołać echo nazwy każdego z tych elementów, wystarczyłoby tylko uruchomić pętlę For Each:

For Each objItem in objOU

    Wscript.Echo objItem.Name

Next

Oczywiście nam nie zależy na każdym elemencie, jaki znajdziemy w jednostce Accounting OU; chodzi nam jedynie o konta użytkowników. Stąd drugi wiersz kodu w naszym skrypcie:

objOU.Filter = Array("user")

Stosujemy tutaj dla naszej kolekcji filtr; w szczególności odfiltrujemy wszystkie obiekty z kolekcji z wyjątkiem obiektów użytkownika. A gdybyśmy tak chcieli pracować z kontami komputerów? Użylibyśmy tego filtra:

objOU.Filter = Array("computer")

Całkiem proste, prawda? Zauważmy, że podczas przypisywania typów obiektów do filtra musimy zawsze używać tablicy – nawet, gdy w filtrze mamy tylko jeden obiekt. Zaczynamy się zastanawiać: „Hmmm, czy to oznacza, że moglibyśmy wrzucić do jednego filtra kilka obiektów?”, a odpowiedź brzmi: oczywiście, że tak. Oto przykładowy filtr, który pozbędzie się wszystkiego oprócz kont grup i drukarek (obiektów printQueue):

objOU.Filter = Array("group", "printQueue")

Wystarczy oddzielić obiekty przecinkami i możemy umieścić w filtrze tyle elementów, ile dusza zapragnie.

Kiedy nasza kolekcja będzie się składać wyłącznie z kont użytkowników, możemy uruchomić pętlę For Each, która przejdzie przez cały zbiór elementów. Wewnątrz niej (automatycznie) łączymy się z pierwszym kontem użytkownika i uruchamiamy następujące dwa wiersze kodu:

objUser.pwdLastSet = 0

objUser.SetInfo

W wierszu pierwszym przypisujemy wartość 0 do atrybutu pwdLastSet. Atrybut ten mówi nam, kiedy użytkownik po raz ostatni ustawił swoje hasło. Jeżeli wartość atrybutu pwdlastSet jest równa 0, użytkownik będzie musiał zmienić swoje hasło przy następnym logowaniu. Jeżeli użytkownik jest już zalogowany, będzie mógł bez problemu kontynuować pracę. Jednak po wylogowaniu i przy powtórnym logowaniu, zostanie poproszony o zmianę hasła.

Uwaga. Nie ma się co ekscytować atrybutem pdwLastSet, on naprawdę zawiera datę i godzinę ostatniej zmiany hasła, jednak data jest zachowana - i tego nie da się zmienić – jako liczba całkowita „reprezentująca liczbę 100 nanosekundowych przerw od 1 stycznia 1601 (UTC).” Jeżeli chcemy poznać datę i godzinę ostatniej zmiany hasła, możemy zerknąć do tego artykułu Cześć, Skrypciarze!.

Po nadaniu atrybutowi pwdLastSet wartości 0 wywołujemy metodę SetInfo w celu wprowadzenia zmiany w bieżącym koncie użytkownika Active Directory. Następnie uruchamiamy pętlę i powtarzamy ten proces dla następnego użytkownika z kolekcji. Po zakończeniu, od każdego użytkownika w jednostce Accounting OU będzie wymagana zmiana hasła przy następnym logowaniu.

Uwaga. No dobra, to może nie do końca jest prawdą: to podejście działa tylko wtedy, gdy użytkownik ma wygasające hasło. Jeżeli którykolwiek z użytkowników ma niewygasające hasło, (które, tak na marginesie, nie jest zalecane), przypisanie atrybutowi pwdLastSet wartości 0 nie będzie miało dla konta żadnych skutków. Nie ma się co martwić, artykułów ci u nas dostatek: w tym artykule Cześć, Skrypciarze! znajdziemy informacje o wykrywaniu haseł niewygasających i zamianie ich na hasła, które tracą ważność.

Spójrzmy prawdzie w oczy, po ponad trzech latach istnienia rubryki, mamy całe mnóstwo artykułów Cześć Skrypciarze!

A teraz bez żartów: Jedzenie w kantynie Microsoft nie jest aż takie straszne. Chodzi o to, że w kuchni wyznają zasadę: „Jeżeli smakowało ci to, co było w poniedziałek, we wtorek wyda ci się jeszcze smaczniejsze, a do piątku zdążysz to pokochać!” Tak czy siak, zjedzenie kolejnego kebabu jest prawdopodobnie dużo lepsze niż czołganie się przez kilometr przez zawilgocony, ciemny tunel.

Prawdopodobnie.

P.S. Chociaż raz w tej rubryce pojawia się szczęśliwe zakończenie: spotkanie zespołu było nadzwyczaj krótkie i Skrypciarzom udało się mimo wszystko pójść na lunch!
 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne