Centrum Skryptóe - Systemy Operacyjne

Jak upewnić się, że skrypt zadziała na danym komputerze tylko raz?

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 upewnić się, że skrypt zadziała na danym komputerze tylko raz?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Jak upewnić się, że skrypt zadziała na danym komputerze tylko raz?

-- ML

Cześć Skrypciarze! Odpowiedź

Cześć, ML. Mieliśmy zacząć dzisiejszy artykuł od powiedzenia „Pokażcie nam swoje lalki”. Ale nie chcieliśmy wyjaśniać ludziom z Microsoftu, że w tym zdaniu nie ma nic ryzykownego ani obscenicznego. Po prostu chcieliśmy wiedzieć, co ludzie zrobili ze swoimi lalkami Dr Scripto Bobblehead. Dlatego, chociaż chcemy, aby ludzie pokazali nam swoje lalki, nie poprosimy ich, aby je nam pokazali. W końcu Skrypciarze nie chcą pakować się w kłopoty. Innymi słowy, pod żadnym pozorem nie pokazujcie nam swoich lalek. Dziękujemy.

Zamiast tego, jeśli należycie do 250 szczęściarzy, którzy wygrali taką lalkę podczas Zimowej Olimpiady Skrypciarskiej 2007, chętnie dowiemy się, co z nią zrobiliście. Po prostu zróbcie zdjęcie i wyślijcie je na adres scripter@microsoft.com. Opublikujemy wasze zdjęcia w Script Center, obok zdjęcia, które otrzymaliśmy od Bena Simkinsa ze Szwajcarii:

Uwaga. Tak, to jest Dr Scripto. Jak odróżnić Dr Scripto od Skrypciarki Jean Ross? Oto wskazówka: Dr Scripto nie ma zszywek w głowie.

Dobrze, przejdźmy do pracy. Prawdę mówiąc, nie znamy żadnego idealnego sposobu upewnienia się, że skrypt działa tylko raz na danym komputerze. Możliwe, że taki sposób istnieje, ale jest zapewne zbyt skomplikowany, by go skonfigurować, a jego wdrożenie jest jeszcze bardziej skomplikowane. Dlatego mamy prostsze rozwiązanie, może nie 100% pewne, ale na pewno łatwe w implementacji.

Oto, co zrobimy: za każdym razem, gdy skrypt się uruchomi, pierwszą rzeczą, którą zrobi jest sprawdzenie wartości w rejestrze. Jeśli wartość ta wynosi Nie, oznacza to, że skrypt ten nie był jeszcze uruchamiany na tym komputerze. W rezultacie, skrypt się uruchomi i po zakończeniu zmieni tę wartość w rejestrze na Tak. Jak można się domyślić, jeśli wartość wynosi Tak, oznacza to, że skrypt był uruchamiany na tym komputerze. Co się stanie jeśli uruchomicie ten skrypt ponownie? To proste. Skrypt sprawdzi rejest, zobaczy, że już był uruchomiony i automatycznie zakończy swoje działanie. Może nie jest to najładniejsze możliwe rozwiązanie, ale powinno zadziałać.

Oczywiście, zanim skrypt zadziała, musimy utworzyć wartość rejestru. Aby to zrobić potrzebne są dwie rzeczy. Po pierwsze, utworzenie nowego klucza rejestru (w gałęzi HKEY_LOCAL_MACHINE) o nazwie AdminScripts. Gdy to zrobimy, musimy utworzyć nową wartość rejestru o nazwie Script 1 wewnątrz klucza AdminScripts. Oto, jak wygląda skrypt robiący te dwie rzeczy:

 

Const HKEY_LOCAL_MACHINE = &H80000002



strComputer = "."

 

Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")

 

strKeyPath = "SOFTWARE\AdminScripts"

objRegistry.CreateKey HKEY_LOCAL_MACHINE, strKeyPath



strValueName = "Script 1"

strValue = "No"

objRegistry.SetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue

Uwaga: Jeśli uruchamiacie ten skrypt w systemie Windows Vista, musicie otworzyć okno wiersza polecenia z konta administratora. Kliknijcie prawym przyciskiem myszki na Wiersz polecenia w menu Start i wybierzcie Uruchom jako administrator. Przypominamy o tym, ponieważ w przeciwnym razie skrypt będzie działał bez błędów, ale w efekcie nie utworzy nowego klucza rejestru.

Jak widzicie, zaczynamy od zdefiniowania stałej o nazwie HKEY_LOCAL_MACHINE i przydzielenia jej wartości &H80000002. Ta stała mówi srkyptowi, w której gałęzi rejestru ma działać. Następnie łączymy się z usługą na lokalnym komputerze, wiążąc się bezpośrednio z klasą StdRegProv, która znajduje się w obszarze nazw root\default:

Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")

Można oczywiście uruchomić ten skrypt na zdalnym komputerze. Należy jedynie przydzielić nazwę tego komputera zmiennej strComputer. Na przykład, następująca linia kodu sprawi, że skrypt będzie działać na zdalnej maszynie atl-fs-01:

strComputer = "atl-fs-01"

Gdy już tu dojdziemy, utworzenie nowego klucza rejestru to bułka z masłem. Musimy jedynie przydzielić klucz rejestru zmiennej o nazwie strKeyPath i wywołać metodę CreateKey. To właśnie zrobimy w następujących dwóch wierszach kodu:

strKeyPath = "SOFTWARE\AdminScripts"

objRegistry.CreateKey HKEY_LOCAL_MACHINE, strKeyPath

Gdy tylko powstanie klucz rejestru, możemy dodać do niego nową wartość. Aby to zrobić, najpierw przydzielamy wartość zmiennej o nazwie strValueName. Następnie przydzielamy domyślną wartość (No) zmiennej o nazwie strValue. Po to są następujące dwa wiersze:

strValueName = "Script 1"

strValue = "No"

Wtedy po prostu wywołujemy metodę SetStringValue która nie tylko tworzy wartość rejestru Script 1, ale przydziela jej również wartość No:

objRegistry.SetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue

To było proste, prawda? Dodamy, że rozdzieliliśmy zadanie na dwie części. Pierwsza to utworzenie klucza rejestru i jego wartości (to właśnie wam pokazałem), a następnie utworzenie kolejnego skryptu, który chcemy uruchomić raz na danym komputerze. Czy moglibyśmy połączyć te dwa skrypty w jeden, który sprawdza, czy wartość rejestru istneije i jeśli nie, to ją tworzy? Jasne. Informacje o weryfikowaniu istnienia wartości rejestru znaleźć można w tym artykule w naszym archiwum.

Uwaga. Dlaczego od razu nie połączyliśmy tych dwóch skryptów? Głównie dlatego, że chcieliśmy wszystko uprościć. Z naszego doświadczenia, ludziom łatwiej jest przeczytać i zrozumieć dwa 10-linijkowe skrypty niż jeden 20-linijkowy. I zaufajcie nam, jeśli chodzi o prostotę nikt nie jest prostszy niż Skrypciarze.

W takim razie co z tym drugim skryptem, tym, który ma być uruchomiony tylko raz na danym komputerze? Oto szybka i prosta wersja, demonstrująca nasze rozwiązanie:

Const HKEY_LOCAL_MACHINE = &H80000002



strComputer = "."

 

Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")

 

strKeyPath = "SOFTWARE\AdminScripts"

strValueName = "Script 1"

objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue



If strValue = "No" Then

    Wscript.Echo "This script will now run."

    strValue = "Yes"

    objRegistry.SetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue

Else

    Wscript.Quit

End If

Uwaga: To samo jeśli chodzi o Windows Vista: Uruchom jako administrator jeśli chcesz, aby ten skrypt zadziałał.

Jak pewnie zauważyliście, między tym skryptem a poprzednim jest sporo podobieństw. Jak poprzednio, definiujemy stałą o nazwie HKEY_LOCAL_MACHINE i łączymy się z usługą WMI. Gdy to zrobimy, przydzielimy wartości do zmiennych strKeyPath (ścieżka w gałęzi rejestru) i strValueName (nazwa wartości rejestru, którą chcemy odczytać). To sprowadza nas do następującego wiersza kodu:

objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue

Używamy teraz metody GetStringValue do odczytania wartości rejestru Script 1. Jak widzicie, używamy czterech parametrów:

  • HKEY_LOCAL_MACHINE, reprezentującego gałąź rejestru.
  • strKeyPath, reprezentującego ścieżkę w tej gałęzi.
  • strValueName, reprezentującego wartość rejestru, którą chcemy odczytać.
  • strValue, parametr do przechowania wartości odczytanej z strValueName.

I macie rację: nie przydzieliliśmy wartości strValue, prawda? To właśnie uroda parametrów: nie musimy nic robić. Zamiast tego dostarczamy nazwę zmiennej metodzie GetStringValue, która sama przydziela zmiennej odpowiednią wartość.

Tak WMI mówi “dziękuję”.

Nie trzeba wspominać, że naszym kolejnym krokiem jest określenie, jaka wartość została przydzielona strValue:

If strValue = "No" Then

Jeśli wartość strValue wynosi No, oznacza to, że skrypt nie był jeszcze uruchomiony na tym komputerze. Dlatego kontynuujemy jego działanie. W naszym przykładowym skrypcie oznacza to wyświetlenie wartości na ekranie:

Wscript.Echo "This script will now run."

Musicie tylko zastąpić poprzedni wiersz kodu wierszem lub wierszami, które wy chcecie wykonać.

Teraz, gdy skrypt został uruchomiony, musimy zmienić wartość w rejestrze z No na Yes. To właśnie robi następujący fragment kodu:

strValue = "Yes"

objRegistry.SetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue

Nic wyszukanego. Przydzielamy wartość Yes zmiennej strValue, a następnie wywołaliśmy metodę SetStringValue aby zapisać nową wartość w rejestrze.

Załóżmy teraz, że strValue nie równa się No. W takim wypadku, zakładamy dwie rzeczy: że strValue równa się Yes i że skrypt działał już na tym komputerze. Co wtedy robimy? To, co Skrypciarzom wychodzi najlepiej: nic. Zamiast tego wywołujemy metodę Quit i kończymy wykonywanie skryptu:

Wscript.Quit

I to by było na tyle. Jeszcze raz, to nie jest stuprocentowo bezpieczne: ktoś może wejść do rejestru i ręcznie zmienić wartość Script 1 z Yes na No. Jeśli tak się stanie, skrypt będzie myślał, że nie działał jeszcze na danej maszynie. Ale ogólnie można założyć, że tak się nie stanie.

Uwaga. Jeśli zachodzą takie obawy, można ustawić inspekcję danego klucza albo monitorować jego zmiany. To nie zapobiegnie zmianom tego klucza, ale administrator otrzyma wtedy powiadomienie.

Jeśli zaś chodzi o wysyłanie nam zdjęć, cóż, zdajemy sobie sprawę, że większosć ludzi nie wygrała laleczki Dr Scripto. Co możemy dla nich zrobić? Nic. Następnym razem trochę bardziej się postarajcie, co?

Nie, tylko żartujemy. Jak się okazało, Skrypciarzom zostało parę lalek Dr Scripto, przechowywanych obecnie pod kluczem w Fort Knox. Niektóre z nich rozdamy na TechEd 2007; jeśli wybieracie się na TechEd, pamiętajcie, aby zahaczyć o stoisko TechNet Magazine, przywitać się ze Skrypciarzami i zapisać się na losowanie. A jeśli nie wybieracie się na konfernecję, nie rozpaczajcie. W czasie TechEd ogłosimy mały konkurs, w którym każdy będzie miał szansę wygrać Dr Scripto. Więcej szczegółów ujawnimy za parę tygodni.

Pamiętajcie tylko, jeśli wygracie, nie pokazujcie nam swojej lalki. Wyślijcie nam tylko zdjęcie swojej nagrody.

 Do początku strony Do początku strony

Centrum Skryptóe - Systemy Operacyjne