Centrum skryptów - Systemy operacyjne

Jak sprawdzać co 30 minut, czy plik został zmodyfikowany?

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 sprawdzać co 30 minut, czy plik został zmodyfikowany?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! W jaki sposób monitorować plik dziennika aplikacji i wysyłać alarm, jeśli sygnatura czasowa nie zmieni się w ciągu 30 minut?

--JA

Cześć Skrypciarze! Odpowiedź

Cześć, JA. Strajku anegdotowego dzień trzeci. Jest trudno – żuję paznokcie, by powstrzymać się od zalania Was serią znakomitych anegdot i historii, jakie przychodzą mi do głowy, ale będę twardy. Trzeba walczyć o swoje prawa i godność. Lada dzień Redaktorka ugnie się przed słusznymi żądaniami, jakie jej stawiam przy Waszym, czyli czytelników, poparciu. Tymczasem zajmijmy się skryptem:

strComputer = "."



Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")



Set colFiles = objWMIService.ExecQuery _

    ("Select * from CIM_Datafile Where Name = 'C:\\Scripts\\Application.log'")



For Each objFile in colFiles

    strOriginalTimestamp = objFile.LastModified

Next



Wscript.Echo "Monitoring application log file: " & Now

Wscript.Echo



Do While True

    Wscript.Sleep 1800000

    Set colFiles = objWMIService.ExecQuery _

        ("Select * from CIM_Datafile Where Name = 'C:\\Scripts\\Application.log'")



    For Each objFile in colFiles

        strLatestTimestamp = objFile.LastModified

    Next 



    If strLatestTimestamp <> strOriginalTimestamp Then

        strOriginalTimestamp = strLatestTimeStamp

    Else

        Wscript.Echo "ALERT: " & Now

        Wscript.Echo "The application log file has not been modified in the last 30 minutes."

        Wscript.Echo

        strOriginalTimestamp = strLatestTimeStamp

    End If

Loop

Zobaczmy, jak to właściwie działa. Na początek łączymy się z usługą WMI na komputerze lokalnym. Była to jedna z pierwszych decyzji, jakie musieliśmy podjąć: czy wykonamy to zadanie za pomocą WMI, czy uciekniemy się do zastosowania innej technologii, np. FileSystemObject? Zdecydowaliśmy się na zastosowanie WMI z jednego, prostego powodu – będziemy mogli dzięki temu napisać skrypt monitorujący plik dziennika na komputerze zdalnym z taką samą łatwością, co na komputerze lokalnym. Chcemy wykonać to zadanie na zdalnym komputerze atl-fs-01? Żaden problem – wystarczy przypisać tę nazwę zmiennej strComputer:

strComputer = "atl-fs-01"

Kolejnym krokiem jest określenie, kiedy plik został ostatnio zmodyfikowany. Musimy poznać bieżącą wartość właściwości LastModified, aby sprawdzić, czy uległa ona (a zarazem i sam plik) zmianie w ciągu ostatnich 30 minut. W tym celu używamy najpierw poniższego wiersza kodu, by pobrać wszystkie wystąpienia klasy CIM_Datafile, których właściwość Name (oznaczająca ścieżkę) ma wartość C:\\Scripts\\Application.log:

Set colFiles = objWMIService.ExecQuery _

    ("Select * from CIM_Datafile Where Name = 'C:\\Scripts\\Application.log'")

Nie, to nie pomyłka – powinno tam być C:\\Scripts\\. Ze względu na to, że \ jest w WMI znakiem zastrzeżonym, każdy taki znak musi zostać oznaczony – w tym celu używa się drugiego znaku \.

Po nawiązaniu połączenia uruchamiamy pętlę For Each, która przechodzi przez kolekcję plików zwróconych przez kwerendę (jak zapewne sami wiecie, w naszej kolekcji może być tylko jeden plik). Następnie za pomocą poniższego wiersza kodu przypisujemy wartość właściwości LastModified do zmiennej o nazwie strOriginalTimestamp:

strOriginalTimestamp = objFile.LastModified

Wszystko to było jedynie wstępem – teraz musimy się dopiero zabrać do prawdziwej pracy. W tym celu uruchamiamy pętlę Do While, która będzie działać po wiek wieków (a przynajmniej dopóki wartość True się nie zmieni):

Do While True

Od czego zaczynamy działanie wewnątrz pętli? W pewnym sensie, od niczego. Wywołujemy metodę Sleep i wstrzymujemy działanie skryptu na pół godziny:

Wscript.Sleep 1800000

Uwaga:

Dla jasności – 1800000 oznacza 1 800 000 milisekund. W sekundzie jest 1 000 milisekund; w minucie – 60 000 milisekund; w 30 minutach jest więc 1 800 000 milisekund (1 000 x 60 x 30).

Po upływie 30 minut ponownie sprawdzamy bieżącą wartość właściwości LastModified; w tym celu ponownie łączymy się z plikiem i przechowujemy wartość właściwości LastModified w zmiennej o nazwie strLatestTimestamp:

strLatestTimestamp = objFile.LastModified

Dochodzimy teraz do tego wiersza kodu:

If strLatestTimestamp <> strOriginalTimestamp Then

Co tutaj robimy? No cóż, porównujemy pierwotną sygnaturę czasową z obecną. Załóżmy, że się one od siebie różnią. O czym to może świadczyć? Tylko o jednym: plik musiał zostać zmodyfikowany w ciągu ostatnich 30 minut. Dlatego też po prostu przypisujemy bieżącą sygnaturę czasową (strLatestTimestamp) zmiennej strOriginalTimestamp, ponownie uruchamiamy pętlę i czekamy kolejne pół godziny.

To było łatwe. Co jednak się stanie, jeśli obie sygnatury są takie same? Ponownie interpretacja może być tylko jedna – plik nie został zmodyfikowany w ciągu ostatnich 30 minut. W takim wypadku używamy poniższych wierszy kodu, by wyświetlić w oknie polecenia odpowiedni komunikat (podobnie jak większość skryptów monitorowania, i ten zdecydowanie najlepiej uruchomić w hoście skryptów CScript (j.ang.):

Wscript.Echo "ALERT: " & Now

Wscript.Echo "The application log file has not been modified in the last 30 minutes."

Wscript.Echo

Da to nam następujący komunikat:

ALERT: 7/20/2007 1:26:35 PM

The application log file has not been modified in the last 30 minutes.

Następnie przypisujemy bieżącą sygnaturę czasową do zmiennej strOriginalTimestamp, ponownie uruchamiamy pętlę, pauzujemy na pół godziny, po czym ponawiamy test. Proces ten będzie się powtarzać bez końca, chyba że użytkownik przerwie skrypt lub zamknie okno poleceń.

Rozumie się chyba samo przez się, że nie musimy ograniczyć się tylko do wyświetlenia komunikatu. Można np. wysłać e-mail, zapisać zdarzenie w dzienniku albo zrobić cokolwiek innego.

To już wszystko na dziś. To zaskakujące, ale Redaktorka ciągle jeszcze nie przyszła na kolanach błagać o wybaczenie. Jestem rozczarowany postawą czytelników – najwyraźniej przyszło za mało wiadomości protestacyjnych. Aby ułatwić Wam ich słanie, podaję poniżej adres:

Skrypciarz piszący artykuły skrypciarskie
Microsoft Corporation
Building 42/4039
Redmond, WA 98052

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne