Batch: Anzahl Dateien im Ordner und löschen

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

Schreibe einen Kommentar