Auf die Problematik Dateien unter Windows zu löschen, die älter als X-Tage sind, bin ich bereits im Artikel („Dateien automatisiert löschen, die älter als x-Tage/Datum sind“) eingegangen. Darauf basierend stellt sich folgendes Problem: Ein Sicherungsskript erstellt jeden Tag ein neues Backup, welches auf einer NAS mit Windows-Zugriff gespeichert wird. Im entsprechenden Sicherungsverzeichnis laufen nun jeden Tag Dateien auf und das Verzeichnis belegt von Tag zu Tag mehr Speicherplatz. Also sollen alle Sicherungen, die beispielsweise älter als 5 Tage sind, automatisch gelöscht werden. Dies ist die Ausgangssituation des oben beschriebenen Skriptes.
In der Praxis kommt es leider vor, dass die Sicherung ausfällt. Ein Tag ist zu verschmerzen. Wenn die Sicherung jedoch dauerhaft ausfällt, ist nach wenigen Tagen auch jedes Sicherungsfile gelöscht. Und da Murphy des EDV-lers bester Freund ist, wird nach dem Löschen des letzten Backups auch ein Ausfall des Quell-Systems eintreten.
Also geht es nun darum, das Skript so zu optimieren, dass es Dateien nur löscht, wenn mindestens X (=2,3 (…) 10) Dateien im Ordner noch vorhanden sind. Fallen die Sicherungen aus, verbleiben immerhin die Sicherungen im Sicherungsordner und werden nicht gelöscht.
Optimal wäre in diesem Fall noch, wenn der Administrator benachrichtigt werden würde, wenn ein solcher Fall eintritt. Aber auch dies ist möglich. In der Zeile „IF „%countFiles%“ GTR „%minFiles%“ (“ beginnt der IF-Block, in dem der Code Platz findet, der die Files löscht. Es sind also genug Dateien vorhanden. Im folgenden „ELSE“-Block gibt das Skript lediglich ein Echo („ echo Zuwenig Dateien zum Löschen!“) aus, was wenig sinnvoll ist. Hier könnte das Skript um die Möglichkeit erweitert werden, dem Admin eine Nachricht zukommen zu lassen, sich die Sicherungen einmal anzuschauen.
Im Skript selbst sind nur zwei Variablen vor dem Einsatz anzupassen. Die Variable „minFiles“ muss mit der Mindestanzahl der Dateien gefüllt werden, die auf jeden Fall im Zielverzeichnis verbleiben sollen. Und der Ordner bzw. das Zielverzeichnis selbst muss deklariert werden. Dies geschieht in der Variable „path“.
Das Skript kann einfach als Batch über Scheduled Task aufgerufen werden.
Batch: Wenn Befehle aus Windowssystem32 nicht gefunden werden
Eine Falle, in welche ich mal wieder getappt bin. In einem Batch-Skript gibt es Probleme mit dem Aufruf von Befehlen wie forefiles, net use oder ähnlichen. Diese Befehle liegen alle im System32-Ordner, doch der Aufruf wird mit einem Fehler quittiert (Aufruf fehlerhaft oder er kann Datei nicht finden). In einem solchen Fall sollte man zuerst einen Blick auf seine gesetzten Variablen innerhalb des Skripts werfen. Ist dort ein „SET Path=“ vorhanden, hat man (versehentlich) den System-Pfad überschrieben. Nun versucht das Skript die Befehle in dem neu gesetzten Pfad zu finden, was sicherlich schiefläuft.
Linux: Für die Freunde von Linux und der Bash gibt es hier eine Anleitung, wie man etwas ähnliches unter Linux bewerkstelligen kann.
@echo off REM ************************************************** REM *** Skript löscht Dateien aus einem Ordern, die älter als x Tage sind. REM *** https://sirmark.de/computer/dateien-automatisiert-loeschen-die-aelter-als-x-tagedatum-sind-191.html REM *** REM *** Anpassung 2013: Es wird zuerst geprüft, REM *** ob noch mindestens X (minFiles) Dateien vorhanden sind. REM *** Wenn Mindestanzahl an Dateien NICHT vorhanden sind REM *** (beispielsweise weil ein Sync/Upload nicht mehr funktioniert), REM *** löscht das Skript KEINE Daten mehr. REM REM ### VARIABLEN ### REM minFiles = 5 : Anzahl an Dateien, die mindestens im Verzeichnis liegen müssen REM Pfad=C: (...) : Pfad zum Ordner, der überwacht werden soll REM -> Lokaler Pfad (cmd liegt im Verzeichnis) : Pfad=%~1 REM AlterTage: (min) Tage, wie alt die zu löschenden Dateien sein sollen REM Laufwerksbuchstabe: Da Forfiles keine UNC-Pfade beherrscht, wird dieser Laufwerksbuchstabe gemappt REM countFiles : Interne Zählvariable REM ************************************************** setlocal SET minFiles=5 REM Forefiles kann NICHT mit UNC-Pfaden umgehen REM Hier wird ein Laufwerksbuchstabe aus dem UNC-Pfad mit NET USE gemappt REM und nach dem FORFILES Befehl wieder gelöscht SET Pfad=\\192.168.0.x\meine\Ordnerstruktur SET Laufwerksbuchstabe=J SET AlterTage=5 SET countFiles=0 REM Prüfe, wieviel Dateien im Ordner vorhanden sind if (%Pfad%)==() set Pfad=%~dp0 set first=%Pfad:~0,1% set last=%Pfad:~-1% if not (%first%)==(^") set Pfad=^"%Pfad% if not (%last%)==(^") set Pfad=%Pfad%" for /F %%i in ('dir %Pfad% /B /A-d') do set /A countFiles=countFiles+1 REM Ausgabe der Daten echo %countFiles% Dateien in Pfad - Min: %minFiles% REM Prüfung auf Mindestanzahl an Dateien if %countFiles% GTR %minFiles% ( REM Genug Files vorhanden, lösch die Dateien echo Mappe das Laufwerk ... NET USE %Laufwerksbuchstabe%: %Pfad% /PERSISTENT:NO echo Loesche ... REM Achtung: Unterschiedliche Versionen von Forfiles -p != /P -> genaue Syntax lokal mit /? ermitteln! REM Test - Files nur anzeigen: forfiles -p%Pfad% -d-%AlterTage% -c"CMD /C echo @FILE" REM UNSCHARF: Zeigt nur die Files an. Zum Löschen das folgende echo in del ändern: "CMD /C del @FILE" forfiles /P %Laufwerksbuchstabe%: /D -%AlterTage% /C "CMD /C echo @FILE" echo Gebe den Laufwerksbuchstaben wieder frei ... net use %Laufwerksbuchstabe%: /D /Y ) ELSE ( echo Zuwenig Dateien zum Löschen! ) endlocal