Wie man sein erstes PowerShell-Skript schreibt: Automatisierung der Dateireinigung

Eine der wichtigsten Programmiermethoden, die man befolgen sollte, ist sicherzustellen, dass man weiß und verwaltet, auf welche Weise der Code „fließen“ kann. Wenn man den Code als Fluss betrachtet, kann er sich verzweigen, zu verschiedenen Punkten zurückkehren und auf viele Bedingungen stoßen.

Die Fehlerbehandlung sorgt dafür, dass man „Netze“ oder einen Standardort einrichtet, zu dem der Code fließen kann, wenn etwas Unerwartetes passiert.

Lass uns ein Szenario aus der realen Welt verwenden, in dem du dich möglicherweise befindest, und zwar beim Umgang mit der Fehlerbehandlung in PowerShell.

Erstellen des ursprünglichen Skripts zur Dateibereinigung

Wir müssen einige alte Dateien bereinigen. Unser Dateiserver gibt es schon ewig, und wir müssen etwas Speicherplatz freigeben. Das Management hat beschlossen, alle Dateien zu entfernen, die älter als eine bestimmte Anzahl von Tagen sind. Wir müssen ein Skript erstellen, das einen Ordner rekursiv durchsucht, alle Dateien findet, die älter als eine bestimmte Anzahl von Tagen sind, und sie entfernt.

Die Aufgabe klingt einfach genug, aber da dies der Abschnitt zur Fehlerbehandlung ist, weißt du, dass einige Dinge schiefgehen werden!

Lass uns beginnen, die Fehlerbehandlung zu verstehen, indem wir zuerst das Dem Skript des Szenarios ohne Fehlerbehandlung erstellen, um das Problem zu demonstrieren, das die Fehlerbehandlung löst.

  1. Öffne zuerst einen neuen Tab in VS Code.

    Da wir jetzt nur ein paar Dinge ausprobieren, werden wir das Skript noch nicht speichern. Sage VS Code vorübergehend, dass du gleich etwas PowerShell schreiben wirst.

    Drücke Ctrl-Shift-P, tippe ‚lang‘, wähle Sprache auswählen, tippe ‚power‘ und wähle PowerShell. Jetzt weiß VS Code, dass du PowerShell schreiben wirst.

  2. Als nächstes teilen Sie das Problem in Aufgaben auf und lösen zuerst die offensichtlichste.

    In diesem Fall besteht die Aufgabe darin, einen Befehl zum Lesen von Dateien in einem Verzeichnis zu erstellen.

    Get-ChildItem -Path C:\OldForgottenFolder
    
  3. Get-ChildItem gibt auch Verzeichnisse zurück, die wir nicht benötigen, also beschränken wir das auf Dateien.

    Get-ChildItem -Path C:\OldForgottenFolder -File
    
  4. Wenn es in diesen Unterverzeichnissen Dateien gibt, müssen wir sie ebenfalls mit Recurse abrufen.

    Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse
    
  5. Jetzt, wo wir den Befehl und die Parameter haben, gibt er ALLE Dateien zurück. Wir müssen nur die finden, die älter als eine bestimmte Anzahl von Tagen sind.

    Da Get-ChildItem jede Datei mit einer LastWriteTime-Objekteigenschaft zurückgibt, müssen wir nach dieser Eigenschaft filtern. Wir verwenden den Where-Filter, um die Dateien mit einer LastWriteTime zu finden, die vor einem bestimmten Datum liegt.

    (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le ?????}
    
  6. Das Datum muss dynamisch sein, da „alt“ heute anders sein wird als „alt“ morgen.

    Kommentiere die vorherige Zeile aus, da wir sie irgendwann benötigen werden und dann die Datumsfrage klären.

    ## (Get-ChildItem -Path C:\\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le ?????}
    $Now = Get-Date
    $Now
    
  7. Jetzt, da wir das heutige Datum haben, lass uns eine bestimmte Anzahl von Tagen vor heute finden, um das Datum zu ermitteln. Ich werde hier vorübergehend 30 eingeben, da ich weiß, dass einige Dateien älter als fünf Tage sind, um einen grundlegenden Test durchzuführen.

    ## (Get-ChildItem -Path C:\\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le ?????}
    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    $LastWrite
    
  8. Fertig! Lass uns bisher alles zusammenfügen.

    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le $LastWrite}
    

    Wir haben jetzt ein kleines Skript, das alle Dateien in einem Verzeichnis findet, die älter sind als eine bestimmte Anzahl von Tagen.

  9. Als Nächstes müssen wir die Möglichkeit hinzufügen, diese älteren Dateien zu entfernen. Dies ist trivial mit dem Remove-Item Cmdlet und der Pipeline.

    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le $LastWrite} | Remove-Item
    
  10. Fertig! Aber warte, ich habe keine Ahnung, welche Dateien entfernt wurden. Es gab auch einige Fehler, die wir in ein paar Minuten ansprechen werden. Lass uns einige grundlegende Funktionen hinzufügen.

    $VerbosePreference = 'Continue'
    
    $Jetzt = Get-Date
    $LetzteÄnderung = $Jetzt.AddDays(-30)
    $alteDateien = (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le $LetzteÄnderung}
    foreach ($datei in $alteDateien) {
        Remove-Item -Path $datei.FullName
        Write-Verbose -Message "Erfolgreich entfernt [$($datei.FullName)]."
    }
    
  11. Du musst eine Schleife wie diese einfügen, um eine Art von Code für jede Datei auszuführen. Hier verwenden wir nicht die Pipeline und legen stattdessen alle gefundenen Dateien in einer alteDateien-Variablen, einem Array von Dateiobjekten, ab. Dann führen wir Remove-Item für jede einzelne wie zuvor aus, aber dieses Mal fügen wir eine ausführliche Nachricht hinzu, die uns mitteilt, welche Datei entfernt wird.

  12. Lasst uns jetzt diesen Code ausführen und sehen, was passiert.

    Durch die ausführliche Nachricht könnt ihr nun sehen, dass einige Dateien entfernt wurden. Der Code, den wir jetzt haben, ist das Herzstück, das wir benötigen, um das Skript zu erstellen. Lassen Sie uns jetzt ein echtes Skript daraus im folgenden Abschnitt erstellen.

Maximierung von Flexibilität und Wiederverwendbarkeit mit Parametern

Sie haben Ihr Skript erstellt, aber es hat immer noch das Potenzial, flexibel und wiederverwendbar zu sein. Wie? Parameter ermöglichen es uns, das Verzeichnis und das Alter der Dateien, die wir anvisieren möchten, anzugeben, was das Skript flexibler macht.

  1. Bevor wir viel weiter gehen, lassen Sie uns unsere Arbeit speichern. Nennen Sie es Remove-FileOlderThan.ps1.

    Beachten Sie das Verb/Nomen-Format mit einem Bindestrich. Wenn möglich, versuchen Sie immer, Skriptnamen auf die gleiche Weise wie PowerShell-Befehle zu erstellen, um Konsistenz und Lesbarkeit zu gewährleisten.

  2. Zuerst sind Skripte darauf ausgelegt, wiederverwendbar zu sein. Es ist wahrscheinlich, dass Sie dieses Skript in verschiedenen Verzeichnissen und für unterschiedliche Altersstufen verwenden möchten. Wir müssen einige Parameter einführen. Um das zu tun, überlegen wir, was sich ändern wird. Das Verzeichnis und die Anzahl der Tage. Verstanden.

    param (
        [Parameter(Mandatory)]
        [string]$FolderPath,
    [Parameter(Mandatory)]
    [int]$DaysOld
    

    )

    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    $oldFiles = (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le $LastWrite}
    foreach ($file in $oldFiles) {
    Remove-Item -Path $file.FullName
    Write-Verbose -Message "Erfolgreich entfernt [$($file.FullName)]."
    }

    Fügen Sie einen param-Block oben hinzu und definieren Sie jeden Parameter als obligatorisch, da wir einen Pfad und eine Anzahl benötigen, damit das Skript funktioniert. Geben Sie auch den Typ hier als Best Practice an.

  3. Ersetzen Sie die statischen Elemente, die wir zuvor im Code hatten, durch die Parameterwerte.

    param (
        [Parameter(Mandatory)]
        [string]$FolderPath,
    [Parameter(Mandatory)]
    [int]$DaysOld
    

    )

    $Now = Get-Date
    $LastWrite = $Now.AddDays(-$DaysOld)
    $oldFiles = (Get-ChildItem -Path $FolderPath -File -Recurse).Where{$_.LastWriteTime -le $LastWrite}
    foreach ($file in $oldFiles) {
    Remove-Item -Path $file.FullName
    Write-Verbose -Message "Erfolgreich entfernt [$($file.FullName)]."
    }

  4. Lass uns jetzt das Skript ausführen und sehen, was passiert.

    C:\Scripts\Remove-FileOlderThan.ps1 -FolderPath C:\OldForgottenFolder -DaysOld 30 -Verbose
    

    Du kannst sehen, wie wir den Pfad des Ordners und die Anzahl der Tage als Parameter angeben müssen. Verwende den Verbose-Parameter, um diese Write-Verbose-Zeile zu sehen.

    PowerShell hat das Skript genau wie zuvor ausgeführt, aber jetzt haben wir ein parametrierbares Skript, das wir in jedem Verzeichnis oder für Dateien jeden Alters verwenden können!

    Wenn wir uns die Ausgabe ansehen, haben wir einige rote Texte erhalten. Entweder hast du keine Rechte oder die Datei ist schreibgeschützt. Aber bei welchen Dateien ist es fehlgeschlagen? Und wie stellst du sicher, dass diese Dateien ebenfalls entfernt werden?

    Fazit

    In diesem Tutorial haben wir ein Skript erstellt, um alte Dateien aus einem Verzeichnis zu entfernen, wobei wir durch das Hinzufügen von Parametern Flexibilität gewährleistet haben. Während das Skript wie beabsichtigt funktioniert, haben wir gesehen, dass die Fehlerbehandlung noch nicht angesprochen wurde, was entscheidend ist, wenn es um reale Szenarien geht.

    Wenn wir voranschreiten, wird das Hinzufügen von Fehlermanagement es uns ermöglichen, Probleme zu behandeln, wie z.B. Cmdlets, die Fehler auslösen, oder Dateien, die nicht zugänglich sind, was uns hilft, eine Skriptbeendigung zu vermeiden und detaillierte Einblicke darüber zu geben, was schiefgelaufen ist.

    Bleib dran für die nächste Demo! PowerShell 101: Beenden, Nicht-Beenden von Fehlern und Try/Catch.

Source:
https://adamtheautomator.com/powershell-file-cleanup-script/