Powershell, Ordner löschen ab einer bestimmten Orndertiefe mit einem bestimmten Alter

fendt230

Newbie
Registriert
Aug. 2014
Beiträge
2
Hallo Forumsgemeinde,

ich grüble nun schon seit Tagen nach einer vernünftigen Lösung meines Problems. Da ich nur über Kenntnisse von Batchdateien verfüge und diese nicht ausreichen, denke ich, dass die Powershell das bestimmt könnte. Nur ich kann diese nicht bedienen und zur Einarbeitung fehlt mir momentan die Zeit. Deshalb hoffe ich, dass hier jemand mir einen Tip geben kann.

Meine Filestruktur sieht z.B. etwa so aus, Datenmenge ca. 19 GB mit 55000 Ordnern und 480000 Dateien


C:\Daten\Messwerte\Results\Kunde1\Datensatz1\Messung1\Ergebniss.* Alter 125 Tage
C:\Daten\Messwerte\Results\Kunde1\Datensatz1\Messung2\Ergebniss.* Alter 90 Tage
.
C:\Daten\Messwerte\Results\Kunde1\Datensatz2\Messung1\Ergebniss.* Alter 7 Tage
C:\Daten\Messwerte\Results\Kunde1\Datensatz2\Messung2\Ergebniss.* Alter 35 Tage
.
C:\Daten\Messwerte\Results\Kunde2\Datensatz1\Messung1\Ergebniss.* Alter 187 Tage
C:\Daten\Messwerte\Results\Kunde2\Datensatz1\Messung2\Ergebniss.* Alter 178 Tage
.
C:\Daten\Messwerte\Results\Kunde2\Datensatz2\Messung1\Ergebniss.* Alter 545 Tage
C:\Daten\Messwerte\Results\Kunde2\Datensatz2\Messung2\Ergebniss.* Alter 380 Tage
.
C:\Daten\Messwerte\Results\Kunde2\Datensatz3\Messung1\Vorabmessung\Ergebniss.* Alter 24 Tage
C:\Daten\Messwerte\Results\Kunde2\Datensatz3\Messung1\Zwischenergebnis\Ergebniss.* Alter 3 Tage
..
und so weiter.

Jetzt bräuchte ich ein Skript, dass in der Aufgabenplanung einmal im Monat über die Datenablage läuft und alle Ordner (inkl. Messung*) abwärts inkl. der Ergebniss-Dateien löscht, sobald diese Ergebniss-Dateien älter sind als 120 Tage.

Angenommen, das Skript läuft erfolgreich, dann säh die Struktur nach einer Bereinigung so aus:

C:\Daten\Messwerte\Results\Kunde1\Datensatz1
C:\Daten\Messwerte\Results\Kunde1\Datensatz1\Messung2\Ergebniss.* Alter 90 Tage
.
C:\Daten\Messwerte\Results\Kunde1\Datensatz2\Messung1\Ergebniss.* Alter 7 Tage
C:\Daten\Messwerte\Results\Kunde1\Datensatz2\Messung2\Ergebniss.* Alter 35 Tage
.
C:\Daten\Messwerte\Results\Kunde2\Datensatz1
C:\Daten\Messwerte\Results\Kunde2\Datensatz1
.
C:\Daten\Messwerte\Results\Kunde2\Datensatz2
C:\Daten\Messwerte\Results\Kunde2\Datensatz2
.
C:\Daten\Messwerte\Results\Kunde2\Datensatz3\Messung1\Vorabmessung\Ergebniss.* Alter 24 Tage
C:\Daten\Messwerte\Results\Kunde2\Datensatz3\Messung1\Zwischenergebnis\Ergebniss.* Alter 3 Tage
..

In den Datei- und Verzeichnisnamen sind so ziemlich alle Zeichen verwendet worden, die die Tastatur hergibt, inkl. Leerzeichen, Umlaute und ;,.-_')~#. Ein echter Graus.
Die Berechtingungen auf Dateien und Ordner inkl. der Zeitstempel darf durch die Skriptanwendung nicht verändert werden.

Ich hoffe nun, dass ein Powershellprofi da mir helfen kann.

Vielen Dank im vorraus.
 
Die Datensatz* Ordner müssen bestehen bleiben? Reicht es nur die Dateien zu löschen oder inkl. leerer Ordner?
 
Hallo Yuuri,

es sollten alle Dateien und Ordern, inkl. leere Ordner gelöscht werden. Aber in meinem Beispiel "C:\Daten\Messwerte\Results\Kunde2\Datensatz2" wäre der Unterordern "Datensatz2" nach dem Löschen ja auch leer, dieser soll aber bestehen bleiben, sonst wir die Ordnersturktur auch auf Kundenebene gelöscht, was nicht sein soll.

Danke
 
Code:
<#

.PARAMETER Days
    Mindestalter an Tagen

.PARAMETER DryRun
    Testdurchlauf ohne zu löschen

.PARAMETER CreateTestData
    Erstellt Test Daten

#>
Param(
    [int]$Days = 120,
    [switch]$DryRun,
    [switch]$CreateTestData
)

if( $CreateTestData )
{
    1..10 | % {
        $k = $_
        1..20 | % {
            $d = $_
            1..10 | % {
                $m = $_

                $app = ""
                if( (Get-Random -Minimum 0 -Maximum 2) -eq 1 )
                {
                    switch( Get-Random -Minimum 0 -Maximum 2 )
                    {
                        0 { $app = "Vorabmessung\" }
                        1 { $app = "Zwischenergebnis\" }
                    }
                }

                @("jpg","bmp","txt","log","ini") | % {
                    $e = $_

                    $f = "Messwerte\Results\Kunde$k\Messung$m\$($app)Ergebnis.$e"
                    ni $f -ItemType File -Force | null
                    (gi $f).LastWriteTime = (Get-Date).AddDays( -(Get-Random -Minimum 1 -Maximum 180) )
                }
            }
        }
    }
}
else
{
    # remove files
    $i = gci . -Recurse -Force `
        | Where-Object { !$_.PSIsContainer -and ($_.LastWriteTime -lt (Get-Date).AddDays( -$Days )) }
    if( $DryRun ) { $i | % { echo "[FILE] $($_.FullName)" } }
    else { $i | Remove-Item -Force }

    # remove folders
    $i = gci . -Recurse -Force `
        | Where-Object { $_.PSIsContainer -and (gci $_.FullName -Recurse -Force `
            | Where-Object { !$_.PSIsContainer }) -eq $null `
        } `
        | Where-Object { $_.FullName -match "\\Kunde\d+\\.+" }
    if( $DryRun ) { $i | % { echo "[DIR] $($_.FullName)" } }
    else { $i | Remove-Item -Force -Recurse }
}
Einfach ins entsprechende Verzeichnis legen, von dem gelöscht werden soll bzw. das Arbeitsverzeichnis im Taskplaner setzen. Mit dem Parameter -DryRun kannst du erstmal nen Testlauf machen, bevor gelöscht wird. Mit -Days kannst du noch den Zeitraum bestimmen. Mit -CreateTestData kannst du dir erstmal Testdaten generieren lassen. Ich hab hier auch mal das Änderungsdatum als Orientierung genommen, ist imho aussagekräftiger.

Im Taskplaner dann einfach powershell.exe auswählen und als Argument
Code:
-File "<Pfad zur Datei>"
hinzufügen. Denk dran das Arbeitsverzeichnis richtig zu setzen bzw. eben "Starten in"!
 
Zurück
Oben