Centrum skryptów - Systemy operacyjne

Jak tworzyć hasła dla użytkowników?

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 tworzyć hasła dla użytkowników?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Próbuję stworzyć kilkunastu użytkowników za pomocą skryptu, ale mam problemy z ich hasłami. Nie chcę nadawać wszystkim tego samego hasła, a jednocześnie wołałbym uniknąć własnoręcznego tworzenia setek haseł i przechowywania ich w pliku. Nie mam pojęcia, jak poradzić sobie z tym problemem. Słyszałem, że w Internecie dostępne są programy służące do generowania haseł. Być może będę zmuszony użyć czegoś podobnego, ale, o ile to możliwe, wolałbym zrealizować to zadanie za pomocą skryptu. Pobrany przeze mnie program posiada graficzny interfejs użytkownika i nie wygląda na to, aby umożliwiał zastosowanie skryptu. Czy można tworzyć hasła w skrypcie przy pomocy powłoki Windows PowerShell?

-RS

Cześć Skrypciarze! Pytanie

Cześć, RS,

Kiedyś mój dziadek podarował mi wspaniały młotek. Miał odkuwaną główkę o wadze 0.5 kg oraz zdobiony rzeźbieniami, palisandrowy trzonek ze skórzanym uchwytem. Było to najładniejsze narzędzie, jakie kiedykolwiek widziałem. Grzechem byłoby zostawić taki młotek w warsztacie stolarskim, więc przyniosłem go do domu. Niestety nie miałem zbyt wielu okazji, aby z niego korzystać. Dlatego gdy trzeba było zamocować śrubę, sięgałem po młotek. Gdy chciałem skruszyć lód - czas na użycie młotka. Telewizor się zepsuł - młotek. Gdy pewnego dnia postanowiłem sprawdzić, czy mój magiczny młotek przyda się do rozbijania jajek, żona kazała mi odnieść go do warsztatu.

Jaki jest morał tej opowieści? Cóż RS, czasem narzędzia są przeznaczone do określonego celu i choć świetnie realizują wybrane zadanie, nienajlepiej radzą z zastosowaniami nieprzewidzianymi przez projektantów. W związku z tym, choć pobrany z Internetu generator haseł może być z powodzeniem wykorzystywany do tworzenia serii losowych haseł, prawdopodobnie nigdy nie był dedykowany do tego celu. Jednak możemy operować nim przy pomocy metody SendKeys obiektu WshShell. Oto przykład wykorzystania SendKeys (funkcji VBScript):

$wshShell = New-Object -ComObject wscript.shell

[void]$wshShell.Run("calc")

[void]$wshshell.AppActivate("kalkulator")

Start-Sleep -milliseconds 100

$wshShell.SendKeys("1{+}2~")

Start-Sleep -milliseconds 100

$wshShell.SendKeys("*5~")

Jak widać, metoda SendKeys uruchomiona przy pomocy powłoki Windows PowerShell działa tak samo, jak działała w kodzie VBScript. Na początku należy stworzyć instancję obiektu WshShell. Do tego celu wykorzystujemy cmdlet New-Object (w VBScript użylibyśmy funkcji CreateObject). Musimy poinformować cmdlet New-Object, że tworzymy obiekt COM oraz określić identyfikator programu w następujący sposób:

$wshshell = New-Object -ComObject wscript.shell

Później wykorzystujemy metodę Run obiektu WshShell znajdującego się w zmiennej $wshShell do uruchomienia instancji programu Kalkulator. Moglibyśmy wpisać po prostu Calc (zamiast wywoływać metodę Run), ale skoro mamy już obiekt WshShell, czemu z niego nie skorzystać. Umieszczamy Kalkulator na pierwszym planie, aby móc z nim pracować. Warto zwrócić uwagę na dwie kwestie. Po pierwsze nazwa pliku wykonywalnego to Calc.exe, a zatem musimy użyć ciągu Calc podczas wywoływania metody Run. Natomiast tytuł okna to Kalkulator i tę właśnie wartość podajemy w metodzie AppActivate. Ale prawdopodobnie już to wiecie, ponieważ te same zasady obowiązywały w języku VBScript. Oto wspomniane dwie linie kodu:

[void]$wshShell.run("calc")

[void]$wshshell.AppActivate("kalkulator")

Zanim zaczniemy symulować wciskanie klawiszy, musimy odczekać chwilę, aby umożliwić załadowanie aplikacji i umieszczenie jej na pierwszym planie. Do tego celu wykorzystujemy cmdlet Start-Sleep (w VBScript użylibyśmy analogicznej metody wscript.sleep). Gdy już jesteśmy pewni, że aplikacja znajduje się na pierwszym planie, stosujemy metodę SendKeys do wysłania sekwencji znaków do aplikacji. W tym przykładzie dodajemy 1+2 i naciskamy ENTER. Czekamy chwilę, a następnie wysyłamy kolejne znaki, aby pomnożyć poprzedni rezultat przez 5 i ponownie naciskamy klawisz ENTER, jak zaprezentowano poniżej:

Start-Sleep -milliseconds 100

$wshShell.SendKeys("1{+}2~")

Start-Sleep -milliseconds 100

$wshShell.SendKeys("*5~")

Ale jaki związek ma zaprezentowane rozwiązanie z pytaniem RS? Metoda SendKeys może posłużyć do kontrolowania zewnętrznej aplikacji. Jest to jedna z opcji, które warto wziąć pod uwagę. Jednak w tym konkretnym przypadku mamy lepszy pomysł. A gdyby tak napisać własny generator haseł? Jeśli interesuje Was taka możliwość, czytajcie dalej. W przeciwnym wypadku możecie użyć przykładu SendKeys i spróbować zautomatyzować program do generowania haseł. Nie poczuję się urażony, pisanie poniższego kodu sprawiło mi sporą frajdę.

Param($pwdPass = 2)

Function CreatePassword()

{

$rnd = new-object system.random

for($i = 1 ; $i -le $pwdPass ; $i++)

{

LtrFmAscii($rnd.Next(33,47))

LtrFmAscii($rnd.Next(48,57))

LtrFmAscii($rnd.Next(65,90))

LtrFmAscii($rnd.Next(97,122))

}

} #end CreatePassword

Function LtrFmAscii($ascii)

{

$script:password += [char]$ascii

} #End LtrFmAscii

Function DisplayPassword()

{

$script:password

} #end DisplayPassword

# *** POCZĄTEK SKRYPTU ***

$script:password = $null

CreatePassword

DisplayPassword

Pierwszą czynnością realizowaną przez ten skrypt jest zdefiniowanie parametru wiersza polecenia o nazwie pwdPass. Parametr ten służy do kontrolowania liczby przejść w funkcji CreatePassword. Każde przejście przez funkcję CreatePassword powoduje dodanie jednego specjalnego znaku, jednej liczby, jednej małej litery i jednej wielkiej litery. Oto linia kodu, w której zmienna $pwdPass otrzymuje domyślną wartość 2:

Param($pwdPass = 2)

Jak to możliwe, że pwdPass stanowi parametr wiersza polecenia, a jednocześnie zmienna $pwdPass zawiera wartość 2? Ponieważ gdy uruchamiamy skrypt w wierszu polecenia, wykorzystujemy parametr -pwdPass w następujący sposób:

Powyższy rysunek demonstruje również, że nazwy parametrów wiersza polecenia mogą być wpisywane bez uwzględniania wielkości liter.

Następnie budujemy funkcję CreatePassword, którą rozpoczynamy od stworzenia instancji klasy .NET Framework System.Random i umieszczenia jej w zmiennej $rnd. Później wykorzystujemy instrukcję for do zdefiniowania pętli, w której pobieramy losowe numery z czterech różnych przedziałów tablicy znaków ASCII. Każdy z losowych numerów jest przekazywany do funkcji LtrFmAscii, w której liczba zostaje przekształcona w znak. Funkcja CreatePassword została zaprezentowana poniżej:

Function CreatePassword()

{

$rnd = new-object system.random

for($i = 1 ; $i -le $pwdPass ; $i++)

{

LtrFmAscii($rnd.Next(33,47))

LtrFmAscii($rnd.Next(48,57))

LtrFmAscii($rnd.Next(65,90))

LtrFmAscii($rnd.Next(97,122))

}

} #end CreatePassword

Następne zadanie polega na stworzeniu funkcji pomocniczej LtrFmAscii. Funkcja ta służy do przekształcenia liczby pobranej z funkcji CreatePassword w znak (instancję klasy system.charvaluetype). Przy pomocy operatora += łączymy poszczególne znaki w pojedynczy ciąg znaków, który wykorzystujemy w naszym haśle. Do przechowywania budowanego ciągu używamy zmiennej $password (o zasięgu skryptu):

Function LtrFmAscii($ascii)

{

  $script:password += [char]$ascii

} #End LtrFmAscii

Po wygenerowaniu hasła przechodzimy do funkcji DisplayPassword. Funkcja DisplayPassword nie jest zbyt zaawansowana, zajmuje się jedynie wyświetleniem hasła na ekranie. Jednak w przyszłych wersjach tego skryptu można zapisywać hasło w pliku tekstowym lub wysyłać je w e-mailu np. do menedżera nowo utworzonego użytkownika. Ze względu na duży potencjał zdecydowaliśmy się umieścić tę logikę w osobnej funkcji:

Function DisplayPassword()

{

  $script:password

} #end DisplayPassword

To już wszystkie funkcje. Początkowa część skryptu rozpoczyna się od deklaracji zmiennej $password (na poziomie skryptu), co oznacza, że zmienna ta może być wykorzystywana w dowolnym miejscu skryptu. Efekt ten uzyskujemy dzięki następującemu modyfikatorowi:

$script:password

Następnie inicjalizujemy zmienną $password, przypisując jej wartość $null oraz wywołujemy funkcje CreatePassword i DisplayPassword. Początkowa część skryptu została zaprezentowana poniżej:

# *** POCZĄTEK SKRYPTU ***



$script:password = $null

CreatePassword

DisplayPassword

To już wszystkie informacje dotyczące generowania losowych haseł.

Ed Wilson i Craig Liebendorfer, Skrypciarze

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne