Centrum skryptów - Systemy operacyjne

Jak sprawdzić liczbę i rozmiar wszystkich plików, które zostały niedawno zmodyfikowane lub utworzone na komputerze?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

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 sprawdzić liczbę i rozmiar wszystkich plików, które zostały niedawno zmodyfikowane lub utworzone na komputerze?

Cześć, Skrypciarze! Potrzebuję skryptu mogącego przeszukać serwer plików i wymienić liczbę oraz całkowity rozmiar plików, które zostały niedawno zmodyfikowane lub utworzone. Wszelka pomoc będzie mile widziana!

-- KT

Cześć, KT. Zanim zaczniemy, mam dobrą wiadomość – otrzymaliśmy już zamówione laleczki dr. Scripto i właśnie je przygotowujemy do wysłania. To zaskakujące, bo miały dotrzeć w połowie marca. Pomyślicie może, że to jednak nie jest zaskakujące, bo właśnie mamy połowę marca. A jednak jest – w zeszłym roku miały dotrzeć około połowy lutego, a otrzymaliśmy je dopiero w kwietniu!

No cóż, bierzmy się do roboty – oto skrypt zwracający kolekcję wszystkich plików dodanych do komputera od 12 marca 2008 r.:

strMonth = "03"

strDay = "12"

strYear = "2008"



strDate = strYear & strMonth & strDay & "000000.000000+000"



intNumberOfFiles = 0

intTotalSize = 0



strComputer = "."



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



Set colFiles = objWMIService.ExecQuery _

    ("Select * From CIM_DataFile Where CreationDate >= '" & strDate & "'")



For Each objFile in colFiles

    intNumberOfFiles = intNumberOfFiles + 1

    intTotalSize = intTotalSize + objFile.FileSize

Next



Wscript.Echo "Total files added: " & intNumberOfFiles

Wscript.Echo "Total size of the new files: " & intTotalSize

Jak się okazuje, nie jest to trudne, chociaż trochę czasochłonne. Każdy plik należy do klasy WMI o nazwie CIM_DataFile. Problem leży w pracy z datą utworzenia i modyfikacji plików – WMI przechowuje dane o czasie w formacie Universal Time Coordinate (UTC). Oznacza to, że np. 12 marca 1008 r. wygląda tak:

20080312000000.000000+000

Wyda się Wam to zapewne dziwne, ale jest tu jakaś metoda. 2008 na początku to rzecz jasna rok; 03 to miesiąc (pamiętajcie o zerze!), a 12 to dzień (więcej informacji o formacie UTC można znaleźć w przewodniku Microsoft Windows 2000 Scripting Guide (j.ang.). Musimy więc przekształcić interesującą nas datę na format UTC.

Używamy do tego poniższego fragmentu kodu:

strMonth = "03"

strDay = "12"

strYear = "2008"



strDate = strYear & strMonth & strDay & "000000.000000+000"

Przypisujemy tu miesiąc, dzień i rok do zmiennych strMonth, strDay i strYear (zwracam ponownie uwagę na poprzedzenie zerem wartości mniejszych niż 10. Poza tym zauważmy, że rok musi mieć cztery cyfry). Następnie używamy poniższego wiersza kodu do połączenia wartości i przypisania powstałego w ten sposób ciągu znaków do zmiennej o nazwie strDate:

strDate = strYear & strMonth & strDay & "000000.000000+000"

Czemu równa będzie wartość strDate? No właśnie:

20080312000000.000000+000

Reszta jest już prosta. Najpierw przypisujemy wartość 0 zmiennym intNumberOfFiles i intTotalSize; omówimy je za chwilę. Następnie łączymy się z usługą WMI komputera lokalnego. Możemy także połączyć się ze zdalnym komputerem – wystarczy przypisać jego nazwę zmiennej strComputer:

strComputer = "atl-fs-001"

Po połączeniu z usługą WMI używamy poniższego fragmentu kodu, by zwrócić kolekcję wszystkich plików na komputerze, których wartość CreationDate jest większa lub równa zmiennej strDate:

Set colFiles = objWMIService.ExecQuery _

    ("Select * From CIM_DataFile Where CreationDate >= '" & strDate & "'")

Pamiętajmy, że WMI domyślnie przeszuka cały komputer (tzn. wszystkie dyski) i namierzy każdy plik o określonej wartości CreationDate. Co to oznacza? Oznacza to, że w zależności od wielkości dysków i liczby plików, wykonanie skryptu trochę potrwa.

Uwaga. Czy można to przyspieszyć? Nie bardzo. Jednak jeśli interesują nas tylko pliki na określonym dysku, możemy dodać instrukcję Where, która ograniczy zakres wyszukiwania do tego dysku. Poniższa kwerenda wyszukuje tylko pliki na dysku D:

("Select * From CIM_DataFile Where CreationDate >= '" & strDate & "' AND Drive = 'D:'")

Prędzej czy później skrypt zakończy działanie. Będziemy wtedy mieli kolekcję wszystkich plików o określonej wartości CreationDate. Jak sprawdzić ich liczbę i całkowitą wielkość? Na przykład tak:

For Each objFile in colFiles

    intNumberOfFiles = intNumberOfFiles + 1

    intTotalSize = intTotalSize + objFile.FileSize

Next

Tworzymy tu pętlę For Each, która przechodzi przez wszystkie pliki w kolekcji. Dla każdego z nich wykonujemy dwie czynności. Po pierwsze zwiększamy wartość intNumberOfFiles o 1. Jak się może domyślacie, posłuży nam ona do śledzenia liczby plików znalezionych w kolekcji. Możemy także po prostu wyświetlić wartość właściwości Count tej kolekcji. My się jednak zdecydowaliśmy na liczenie plików jeden po drugim, bo i tak musimy użyć pętli For Each.

Dlaczego? Ponieważ jedyny sposób sprawdzenia łącznej wielkości plików to dodanie do siebie wielkości poszczególnych z nich. Poniższy wiersz kodu pobiera wartość właściwości FileSize każdego z plików i dodaje ją do zmiennej intTotalSize:

intTotalSize = intTotalSize + objFile.FileSize

Następnie wracamy do góry pętli i powtarzamy ten proces dla kolejnego pliku w kolekcji. Po zakończeniu wyświetlamy wartość zmiennych intNumberOfFiles i intTotalSize:

Wscript.Echo "Total files added: " & intNumberOfFiles

Wscript.Echo "Total size of the new files: " & intTotalSize

Dzięki temu uzyskujemy taki wynik:

Total files added: 42

Total size of the new files: 69559

Ponownie chwilę to zajmie, ale zadziała.

Sprawa z nowymi plikami już załatwiona. Teraz bierzemy się za pliki zmodyfikowane od 12 marca 2008 r.:

intModifiedFiles = 0

intModifiedSize = 0



Set colFiles = objWMIService.ExecQuery _

    ("Select * From CIM_DataFile Where LastModified >= '" & strDate & "'")



For Each objFile in colFiles

    intModifiedFiles = intModifiedFiles + 1

    intModifiedSize = intModifiedSize + objFile.FileSize

Next



Wscript.Echo "Total files modified: " & (intModifiedFiles – intNumberOfFiles)

Wscript.Echo "Total size of the modified files: " & (intModifiedSize – intTotalSize)

Jak widać, nie różni się to zbytnio od kodu służącego do wyszukiwania nowych plików. Najpierw przypisujemy wartość 0 dwóm zmiennym – intModifiedFiles i intModifiedSize. Następnie za pomocą poniższego wiersza kodu pobieramy kolekcję wszystkich plików, których właściwość LastModified ma wartość większą lub równą strDate:

Set colFiles = objWMIService.ExecQuery _

    ("Select * From CIM_DataFile Where LastModified >= '" & strDate & "'")

Teraz uruchamiamy pętlę For Each w celu obliczenia całkowitej liczby plików (intModifiedFiles) oraz ich wielkości (intModifiedSize). Służą do tego poniższe dwa wiersze kodu:

Wscript.Echo "Total files modified: " & (intModifiedFiles – intNumberOfFiles)

Wscript.Echo "Total size of the modified files: " & (intModifiedSize – intTotalSize)

Wyświetlamy tu liczbę i wielkość plików zmodyfikowanych od 12 marca 2008 r. Zwróćmy jednak uwagę, że nie jest to po prostu wartość intModifiedFiles, lecz wartość intModifiedFiles pomniejszona o intNumberOfFiles:

(intModifiedFiles – intNumberOfFiles)

Dlaczego? Otóż pliki utworzone 12 marca 2008 r. również liczą się jako zmodyfikowane w tym dniu. Musimy więc uniknąć liczenia ich dwa razy.

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne