Centrum Skryptóe - Systemy Operacyne

Jak usunąć stare pliki ze wszystkich folderów o tej samej nazwie?

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 usunąć stare pliki ze wszystkich folderów o tej samej nazwie?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Mam bardzo dużo folderów o nazwie Archive, wszystkie znajdują się na tym samym komputerze. W jaki sposób wyszukać wszystkie te foldery, przejść przez każdy z nich i usunąć wszystkie pliki starsze niż XX dni?

-- CH

Cześć Skrypciarze! Odpowiedź

Cześć CH. Dzisiaj na forum informatycznym TechEd w Barcelonie będziemy musieli trochę popracować. Wczoraj wystarczyło trochę posiedzieć na stoisku po południu, ale to była niestety taka jednorazowa sytuacja.

Podczas jednego ze spacerów ulicami Barcelony natknęliśmy się na bazylikę Sagrada Familia. To ogromna budowla, której widok potrafi zaprzeć dech w piersiach. Jej wznoszenie rozpoczęto w 1882 r. i do dziś nie zakończono (a to jeszcze długa droga). Postanowiliśmy się założyć z władzami miasta o to, który projekt zostanie zakończony jako pierwszy: bazylika Sagrada Familia czy wyszukiwarka Active Directory (j.ang.) nad którą prace trwają już chyba ze sto lat.

Wskazówka. Na waszym miejscu postawiłbym na bazylikę.

Gdybyśmy byli trochę sprytniejsi, założylibyśmy się o to, co zostanie ukończone jako pierwsze: bazylika Sagrada Familia czy skrypt usuwający pliki starsze niż określona liczba dni ze wszystkich folderów o nazwie Archive, znajdujących się na komputerze. Możecie wierzyć lub nie, ale wygrałby ten oto skrypt:

dtmDate = Date - 90



strDay = Day(dtmDate)



If Len(strDay) < 2 Then

    strDay = "0" & strDay

End If



strMonth = Month(dtmDate)



If Len(strMonth) < 2 Then

    strMonth = "0" & strMonth

End If



strYear = Year(dtmDate)



strTargetDate = strYear & strMonth & strDay



strComputer = "."



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



Set colFolders = objWMIService.ExecQuery _

    ("Select * from Win32_Directory Where FileName = 'Archive'")



For Each objFolder in colFolders

    Set colFiles = objWMIService.ExecQuery _

        ("ASSOCIATORS OF {Win32_Directory.Name='" & objFolder.Name & "'} Where " _

            & "ResultClass = CIM_DataFile")



    For Each objFile In colFiles

        strDate = Left(objFile.CreationDate, 8)

        If strDate < strTargetDate Then

            objFile.Delete

        End If

    Next

Next

Zobaczmy, jak on działa. Zdecydowałem, że będziemy usuwać pliki starsze niż 90 dni. Oczywiście, żeby móc to zrobić, musimy znać dokładną datę sprzed 90 dni. Nasz pierwszy wiersz kodu oblicza tę datę i zachowuje ją w zmiennej o nazwie dtmDate:

dtmDate = Date - 90

Ponieważ mamy zamiar zastosować usługę WMI, musimy teraz przekonwertować zmienną dtmDate na wartość czasu zgodną z UTC. Nie będziemy omawiać teraz tego formatu czasu, więcej informacji na ten temat znajduje się w przewodniku Microsoft Windows 2000 Scripting Guide (j.ang.). Nam powinna teraz wystarczyć informacja, że musimy przekonwertować naszą datę na coś podobnego do poniższego ciągu, gdzie pierwsze cztery cyfry reprezentują rok, następne dwie miesiąc, a ostatnie dwie dzień:

20070809

Wyodrębnienie poszczególnych kawałków z tej wartości czasu jest całkiem proste; możemy to zrobić za pomocą funkcji Day, Month oraz Year. Sytuacja jest trochę bardziej skomplikowana, kiedy mamy datę w formacie amerykańskim: 8/9/2007. W tym przypadku, zarówno miesiąc (8), jak i dzień (9) mają pojedynczą cyfrę. Dlaczego to stanowi problem? No cóż, jest to problem, ponieważ w formacie UTC, miesiąc i dzień muszą mieć po dwie cyfry. Aby załatwić ten problem, uwzględniamy poniższy kod dla dnia i miesiąca:

strDay = Day(dtmDate)



If Len(strDay) < 2 Then

    strDay = "0" & strDay

End If

Co się tutaj dzieje? No cóż, stosujemy tutaj funkcję Day w celu pobrania części daty docelowej i zachowujemy ją w zmiennej o nazwie strDay. Następnie stosujemy funkcję Len w celu sprawdzenia liczby znaków w zmiennej strDay. Jeżeli zmienna strDay posiada mniej niż 2 znaki, stosujemy poniższy kod w celu dodania do tej wartości zera prowadzącego:

strDay = "0" & strDay

Innymi słowy, jeżeli zmienna strDay ma wartość 9, powyższy wiersz kodu doda na początku zero, dzięki czemu zmienna będzie wyglądała tak:

09

Upewniwszy się, że tak dzień, jak i miesiąc mają po dwie cyfry, stosujemy poniższy wiersz kodu w celu połączenia roku, miesiąca i dnia w wartość czasu zgodną z UTC:

strTargetDate = strYear & strMonth & strDay

Teraz zaczyna się zabawa. Naszym następnym krokiem jest połączenie się z usługą WMI na lokalnym komputerze. Jak zwykle w takich przypadkach, możliwe jest także zastosowanie tego skryptu na zdalnym komputerze; w tym celu należy przypisać nazwę zdalnego komputera do zmiennej o nazwie strComputer:

strComputer = "atl-fs-01"

Teraz stosujemy metodę ExecQuery wraz z poniższym wierszem kodu w celu pobrania kolekcji wszystkich folderów o nazwie Archive:

Set colFolders = objWMIService.ExecQuery _

    ("Select * from Win32_Directory Where FileName = 'Archive'")

Co dokładnie otrzymamy dzięki tej kwerendzie? No cóż, jak już mówiłem, otrzymamy kolekcję wszystkich folderów o nazwie Archive. Kolekcja będzie obejmowała następujące foldery:

C:\Archive

D:\Archive

C:\Documents and Settings\Kenmyer\Archive

C:\Documents and Settings\Pilara\My Documents\Archive

Etc., etc.

Co teraz? Cóż, teraz uruchamiamy pętlę For Each, która przejdzie przez każdy folder znajdujący się w kolekcji. Wewnątrz tej pętli używamy jedną z kwerend Associators Of w celu pobrania kolekcji wszystkich plików znajdujących się w pierwszym folderze w tej kolekcji:

For Each objFolder in colFolders

    Set colFiles = objWMIService.ExecQuery _

        ("ASSOCIATORS OF {Win32_Directory.Name='" & objFolder.Name & "'} Where " _

            & "ResultClass = CIM_DataFile")

Następnie uruchamiamy drugą pętlę For Each, która przejdzie przez kolekcję plików znajdujących się w pierwszym folderze. Wewnątrz tej pętli stosujemy następujący fragment kodu:

strDate = Left(objFile.CreationDate, 8)



If strDate < strTargetDate Then

     objFile.Delete

End If

Prawda, że bardzo ciekawy? Stosujemy tutaj funkcję Left w celu pobrania pierwszych 8 znaków z właściwości CreationDate. Ponieważ właściwość CreationDate zachowuje wartości w formacie UTC, oznacza to, że zmienna strDate będzie podobna do poniższego ciągu:

20070618

Teraz mamy dwie wartości liczb całkowitych, które możemy porównać: zmienną strDate (datę utworzenia danego pliku) oraz zmienną strTargetDate (datę sprzed 90 dni). A ponieważ sprytnie skonfigurowaliśmy te dane, żeby były liczbami całkowitymi, oznacza to, że możemy porównać je za pomocą poniższego wiersza kodu:

If strDate < strTargetDate Then

Po zastosowaniu naszych przykładowych dat, ten wiersz kodu informuje nas o tym, że:

If 20070618 < 20070809 Then

Jak się okazuje, 20070618 to mniej niż 20070809. To oznacza, że plik jest stary, co z kolei oznacza, że należy go usunąć. Plik usuwany za pomocą metody Delete:

objFile.Delete

Następnie kontynuujemy działanie pętli i powtarzamy ten proces z następnym plikiem w kolekcji. Po przejściu pętli przez wszystkie pliki w pierwszym folderze, wracamy na początek pierwszej pętli i powtarzamy cały proces dla następnego folderu w kolekcji.

Kiedy skończymy, będzie to oznaczać, że przeszliśmy przez wszystkie foldery o nazwie Archive i usunęliśmy wszystkie pliki starsze niż 90 dni.

 Do początku strony Do początku strony

Centrum Skryptóe - Systemy Operacyne