Effiziente Dateilöschung mit PowerShell: Remove-Item und WMI

Die Aufrechterhaltung des freien Festplattenspeichers ist entscheidend bei der Verwaltung von Servern und Systemen. Als Administratoren möchten Sie nicht unvorbereitet von einer ‚Festplatte voll‘-Situation überrascht werden. Um sicherzustellen, dass Sie auf der sicheren Seite sind, sollten Sie lernen, wie Sie PowerShell zum Löschen von Dateien verwenden!

In diesem Artikel erfahren Sie, wie Sie mit PowerShell auf nahezu jede erdenkliche Weise Dateien von Ihren Systemen entfernen können.

Fangen wir an!

Voraussetzungen

In diesem Artikel werden Beispiele mit PowerShell gezeigt. Wenn Sie mitmachen möchten, benötigen Sie Folgendes.

  • A computer that is running Windows 10 or above.
  • Windows PowerShell 5.1 oder PowerShell 7.0
  • A script editor such as Visual Studio Code, Atom, or Notepad++.

Verwenden des Remove-Item-Cmdlets zum Löschen von Dateien

Wenn Sie einfach nur eine Datei mit PowerShell löschen möchten, werden Sie wahrscheinlich sofort auf das Remove-Item-Cmdlet stoßen. Dieses Cmdlet ist der de-facto-Standard zum Entfernen von Dateien mit PowerShell.

Mit Remove-Item in Verbindung mit dem Get-ChildItem-Cmdlet zum Lesen von Dateien und Ordnern und der leistungsstarken PowerShell-Pipeline können Sie wirklich alles ganz einfach erledigen.

Verwandt: Get-ChildItem: Auflisten von Dateien, Registrierungseinträgen, Zertifikaten und mehr

Wussten Sie, dass das Remove-Item-Cmdlet einen Alias namens del hat? Wenn Sie mit PowerShell arbeiten, führt die Verwendung von Remove-Item oder del zum gleichen Befehl.

Verwendung von PowerShell zum Löschen einer Datei

Das erste Beispiel, das am nützlichsten wäre, ist das einfachste – nämlich das Löschen einer einzelnen Datei. Um nur eine einzelne Datei zu löschen, müssen Sie nur den folgenden Befehl verwenden. Der folgende Code löscht die Datei C:\temp\random.txt.

Remove-Item -Path C:\temp\random.txt

Das Ausführen des obenstehenden Codes in PowerShell würde nichts auf dem Bildschirm anzeigen, es sei denn, es ist ein Fehler aufgetreten.

Verwenden von PowerShell zum Löschen aller Dateien in einem Ordner

In diesem Beispiel löscht der folgende Code alle Dateien in einem Ordner. Der Befehl Get-ChildItem zielt mit dem Parameter -Path auf C:\temp ab. Der Parameter -File gibt an, dass nur Dateien eingeschlossen werden sollen. Get-ChildItem ignoriert Ordner.

Get-ChildItem -Path C:\temp -File | Remove-Item -Verbose

Die Ausgabe sollte wie auf dem folgenden Screenshot aussehen.

Successfully deleted all files in a folder

Verwenden von PowerShell zum rekursiven Löschen aller Dateien

Das vorherige Beispiel hat nur Dateien im Ordner C:\temp gelöscht. Wenn Sie auch die Dateien in allen Unterordnern löschen möchten, müssen Sie den Schalter -Recurse zum Befehl Get-ChildItem hinzufügen, um alle Dateien rekursiv zu erhalten.

Get-ChildItem -Path C:\temp -File -Recurse | Remove-Item -Verbose

Das Ausführen des obigen Codes zwingt PowerShell dazu, alle Unterordner zu durchsuchen und alle Dateien aufzulisten. Die folgende Ausgabe zeigt, dass der Code Dateien im obersten Ordner löschen konnte, jedoch nicht in den Unterordnern.

Failed to retrieve files in sub-folders

Umgehen des Problems mit dem langen Pfad

Der oben angezeigte Fehler zeigt an, dass PowerShell den Pfad nicht finden konnte. Dieser Fehler deutet darauf hin, dass der Pfad, auf den der Befehl zugreifen möchte, nicht vorhanden ist – was irreführend ist.

In diesem Fall lag der Fehler darin, dass der Pfad, den das Get-ChildItem versucht zu lesen, die maximale Pfadlänge von 260 Zeichen überschreitet.

Der Screenshot unten zeigt, dass der Pfad oder das Verzeichnis und seine Unterordner existieren und eine Textdatei mit dem Namen InTooDeep.txt im untersten Unterordner liegt. Die Kombination aller Zeichen, die die verschachtelten Verzeichnisnamen bilden, erzeugt ein Problem mit dem langen Pfad.

Nested directories creating a long path name

In Windows PowerShell 5.1 gibt es einen Workaround für das Problem mit dem langen Pfadnamen. Der Workaround besteht darin, die Unicode-Version des Pfads zu verwenden. Anstatt den Pfad wie folgt anzugeben – C:\temp, verwenden Sie die Unicode-Version wie folgt – ‘\\?\C:\temp’ für lokal befindliche Ordner oder ‘\\?\UNC\<computername>\<share>\Temp’, wenn der Ordner sich in einem UNC-Pfad befindet.

Get-ChildItem -Path '\\?\C:\temp' -File -Recurse | Remove-Item -Verbose

Mit dem geänderten Code oben, der den langen Pfadnamen berücksichtigt, zeigt die folgende Ausgabe, dass PowerShell den tief verschachtelten Pfadnamen erfolgreich gelesen und die Datei gelöscht hat.

Deleted the file with a long path name

Bemerkenswert ist, dass das Problem mit dem langen Pfadnamen PowerShell 7.0 nicht betrifft. Mit PowerShell 7.0 ist es nicht mehr erforderlich, die Unicode-Version des Pfads zu verwenden, da sie bereits integrierte Unterstützung für lange Pfadnamen bietet.

Wenn auch die Ordner gelöscht werden sollen, entfernen Sie einfach den -File-Parameter aus dem Get-ChildItem-Cmdlet, und PowerShell sollte alle Elemente, einschließlich Dateien und Ordner, löschen.

Verwenden von PowerShell zum Löschen von Dateien, die älter als x Tage sind.

Ein weiteres typisches Beispiel für die Verwaltung des Festplattenspeichers ist das Löschen von Dateien, die älter sind als eine bestimmte Anzahl von Tagen. Dieses Beispiel ist nützlich, um alte Protokolldateien, wie sie von IIS-Webservern generiert werden, freizugeben und Speicherplatz auf der Festplatte zu schaffen.

In diesem Beispiel gibt es Dateien in c:\temp, die älter als 14 Tage sind. Mit dem untenstehenden Skript werden der Name, die Erstellungszeit und das AlterInTagen jeder Datei in c:\temp angezeigt.

Get-ChildItem c:\temp | Select-Object Name,CreationTime,@{n='AgeInDays';e={(New-TimeSpan -Start $PSItem.CreationTime).Days}}

Wie Sie auf dem untenstehenden Bildschirmfoto sehen können, gibt es Dateien, die 15 Tage alt, 7 Tage alt und 0 Tage alt sind.

List of files in c:\temp

Jetzt, da Sie wissen, welche Dateien entfernt werden sollen, können Sie ein Skript erstellen, um nur Dateien zu löschen, die älter sind als eine bestimmte Anzahl von Tagen – in diesem Fall älter als 14 Tage.

In dem untenstehenden Beispiel-Skript werden Dateien in C:\temp, deren Erstellungszeit älter als der festgelegte Schwellenwert ist, gelöscht.

Die erste Zeile definiert den Pfad, nach dem Get-ChildItem suchen soll. Der Pfad wird in der Variablen $path gespeichert. Dann wird in der zweiten Zeile der Schwellenwert festgelegt. Der Wert der Variablen $threshold gibt das Alter in Tagen an, das die zu löschende Datei haben muss.

Die nächste Codezeile nach der Variablen $threshold wird folgendes tun:

  • Die Sammlung von Dateien abrufen, die sich im im $path angegebenen Ordner befinden. In diesem Beispiel ist der Pfad C:\temp.
  • Die Ausgabe filtern, um nur Dateien einzuschließen, deren Erstellungszeit älter ist als die Anzahl der Tage, die in der Variablen $threshold gespeichert sind. In diesem Beispiel beträgt der Schwellenwert 14 Tage.
  • Leiten Sie die gefilterte Liste der Dateien an den Remove-Item-Befehl weiter, um diese Dateien zu löschen.
$path = 'C:\Temp'
$threshold = 14
Get-ChildItem -Path $path -File | Where-Object {$PSItem.CreationTime -lt (Get-Date).AddDays(-$threshold)} |Remove-Item -Verbose

Wenn Sie den obigen Code ausführen, wird die Ausgabe wie unten gezeigt angezeigt.

The script deleted the files older than 14 days

Beachten Sie anhand des oben gezeigten Screenshots, dass das Skript laut der ausführlichen Meldung nur fünf Dateien gelöscht hat, die älter als 14 Tage waren. Um zu bestätigen, dass neuere Dateien als 14 Tage weiterhin existieren, führen Sie den folgenden Code aus, um sie erneut aufzulisten.

Get-ChildItem c:\temp | Select-Object Name,CreationTime,@{n='AgeInDays';e={(New-TimeSpan -Start $PSItem.CreationTime).Days}}

Das folgende Ergebnis bestätigt, dass Remove-Item die neueren Dateien nicht gelöscht hat.

Newer files are left untouched

Verwenden von PowerShell zum Übereinstimmen und Löschen von Dateimustern

Das Löschen aller Dateien, unabhängig von Name, Typ oder Erweiterung, ist nicht immer der beste Ansatz. Manchmal müssen bestimmte Dateien explizit ausgeschlossen oder einbezogen werden.

Das folgende Beispiel zeigt, wie man Dateien löscht, die dem Dateinamen *.LOG entsprechen. Eine Möglichkeit besteht darin, den Befehl Remove-Item direkt mit Verwendung des Parameters -Include zu verwenden, wie unten gezeigt.

Remove-Item -Path C:\temp\* -Include *.log

Eine andere Möglichkeit besteht darin, möglicherweise vorsichtig vorzugehen und zuerst Get-ChildItem zu verwenden, um die Liste der zu löschenden Dateien zu sammeln. Erst wenn Sie mit der Liste der zu löschenden Dateien zufrieden sind, können Sie die Sammlung schließlich an den Befehl Remove-Item weiterleiten.

Zum Beispiel erhält der folgende Code die *.LOG-Dateien in c:\temp.

Get-ChildItem -Path C:\temp\* -Include *.log

Als Ergebnis des obigen Codes gibt Get-ChildItem eine Liste der Dateien zurück, die dem Dateinamen *.LOG entsprechen.

Only files matching the *.log filename is returned

Aber was ist, wenn Sie eine Datei ausschließen möchten, die die Zahl 5 in ihrem Namen enthält? Sie können dies tun, indem Sie den -Exclude-Parameter wie im folgenden Code hinzufügen.

Get-ChildItem -Path C:\temp\* -Include *.log -Exclude *5*

Da Sie die Datei mit der Nummer 5 ausgeschlossen haben, ist das Ergebnis jetzt anders. Konkret befindet sich die Datei File_5.log nicht mehr in der Liste, wie unten gezeigt.

The file File_5.log was excluded

Wenn Sie bereits mit der Sammlung von Dateien zufrieden sind, die Ihr Code erstellt hat, können Sie die Dateisammlung an das Remove-Item-Cmdlet übergeben, um diese Dateien endgültig zu löschen.

Get-ChildItem -Path C:\temp\* -Include *.log -Exclude *5* | Remove-Item -Verbose

Nach Ausführung Ihres endgültigen Codes haben Sie Ihr Ziel erreicht, nur die ausgewählten Dateien zu löschen.

Deleting selected files

Löschen von Dateien mit WMI in PowerShell

Jetzt, da Sie ein gutes Verständnis für die Verwendung des gängigen Remove-Item-Cmdlets zum Löschen von Dateien haben, lassen Sie uns einen fortgeschritteneren Anwendungsfall betrachten: die Verwendung von WMI.

PowerShell unterstützt WMI. Und die Unterstützung für WMI bedeutet, dass WMI-Abfragen und -Methoden aus PowerShell heraus aufgerufen werden können. Ja, WMI ist nicht nur für Visual Basic-Skripte gedacht, die Admins in den früheren Tagen von Windows verwendet haben.

Microsoft hat in PowerShell 3.0 WMI-spezifische CIM-Cmdlets veröffentlicht. Die CIM-Cmdlets, die zum Löschen von Dateien verwendet werden, sind Get-CimInstance und Invoke-CimMethod.

Mit PowerShell und WMI eine Datei löschen

Dieses Beispiel setzt voraus, dass Sie den Pfad der zu löschenden Datei kennen. Das Cmdlet Get-CimInstance mit der Klasse Cim_DataFile wird verwendet, um Informationen über die zu löschende Datei abzurufen, in diesem Fall C:\Temp\random.txt.

$file2delete = Get-CimInstance -ClassName Cim_DataFile -Filter "Name = 'C:\Temp\random.txt'"
 $file2delete

In dem obigen Code akzeptiert der Parameter -Filter eine Abfrage im Format WQL. Die Verwendung von WQL erfordert, dass einige Zeichen, einschließlich des Backslashes, maskiert werden. Da das Maskierungszeichen für WQL ebenfalls der Backslash ist, resultieren doppelte Backslash-Zeichen – \\.

Die Ausführung des obigen Codes liefert das unten gezeigte Ergebnis. Die Informationen über C:\Temp\random.txt werden in der Variablen $file2delete gespeichert.

Getting a file using WMI query and PowerShell

Nachdem die Informationen für die Datei C:\Temp\random.txt abgerufen wurden, kann das resultierende Objekt in der Variablen $file2delete an das Cmdlet Invoke-CimMethod weitergeleitet werden. Das Cmdlet Invoke-CimMethod verfügt über einen Parameter namens -Name, der den Namen der Methode der Klasse Cim_DataFile repräsentiert.

$file2delete | Invoke-CimMethod -Name Delete

Wie im folgenden Screenshot zu sehen ist, zeigt der Wert von ReturnValue 0, was bedeutet, dass der Befehl erfolgreich war.

File successfully deleted using WMI and PowerShell

Um Informationen über mögliche ReturnValue-Codes zu erhalten, verweisen Sie bitte auf diesen Link – Löschen-Methode der CIM_DataFile-Klasse

Zusätzlich zeigt der untenstehende Screenshot, dass nach Ausführung der Invoke-CimMethod Delete()-Methode CIM nur die Datei C:\Temp\random.txt entfernt hat. Es wurden keine anderen Dateien entfernt.

C:\Temp\random.txt file was deleted

Verwenden von PowerShell und WMI zum Löschen aller Dateien in einem Ordner

In diesem nächsten Beispiel wird gezeigt, wie Sie mit PowerShell und WMI alle Dateien in einem Ordner löschen können. Die gleichen Cmdlets, die im vorherigen Beispiel verwendet wurden, nämlich Get-CimInstance und Invoke-CimMethod, werden verwendet. Diesmal ruft die WQL-Abfrage alle Dateien im Ordner ab, anstatt nur eine bestimmte Datei.

In folgendem Code ruft das Cmdlet Get-CimInstance alle Dateien in C:\temp ab. Wie unten zu sehen ist, filtert die Abfrage die Eigenschaften Drive und Path der Klasse Cim_DataFile.

$file2delete = Get-CimInstance -ClassName Cim_DataFile -Filter "Drive = 'c:' AND Path = '\\temp\\'"

Durch Ausführen des obigen Codes werden die Informationen über die Dateien in C:\temp in der Variablen $file2delete gespeichert. Das Anzeigen des Wertes bzw. der Werte der Variablen $file2delete ergibt die folgende Ausgabe.

List of all folders found in c:\temp using WMI

Die in der Variablen $file2delete gespeicherten Werte können nun an Invoke-CimMethod weitergeleitet werden, um alle Dateien in c:\temp zu löschen.

$file2delete | Invoke-CimMethod -Name Delete

Denken Sie daran, dass der Rückgabewert ReturnValue 0 für erfolgreich bedeutet und für jede Datei, auf die die Löschmethode aufgerufen wurde, einen eigenen ReturnValue hat.

All files in c:\temp deleted using WMI

Verwenden von PowerShell und WMI zum Löschen von Dateien nach Dateierweiterung

Sie haben im vorherigen Beispiel gesehen, wie Sie alle Dateien in einem Ordner unabhängig von der Erweiterung löschen können. Sie können jedoch auch steuern, welche Dateien basierend auf der Erweiterung gelöscht werden sollen.

Sie werden im folgenden Code feststellen, dass die Abfrage diesmal eine zusätzliche Bedingung enthält (Name LIKE '%.log). Diese zusätzliche Bedingung bedeutet, dass nur Dateien, die der Erweiterung .LOG entsprechen, zurückgegeben werden. Das Prozentzeichen (%) ist ein WQL LIKE Operator, der „Eine Zeichenfolge von null oder mehr Zeichen“ bedeutet. In Programmierbegriffen ist das % das Äquivalent eines Platzhalters, der durch das Sternchen (*) dargestellt wird.

$file2delete = Get-CimInstance -ClassName cim_datafile `
-Filter "Drive = 'c:' AND Path = '\\temp\\' AND Name LIKE '%.log'"

$file2delete | Invoke-CimMethod -Name Delete

Die folgende Demonstration zeigt, dass vor der Ausführung des obigen Codes neun *.LOG-Dateien und nur eine *.TXT-Datei vorhanden sind. Sobald der Code fertig ist, werden die *.LOG-Dateien gelöscht und die *.TXT-Datei ist die einzige Datei, die im Ordner verbleibt.

Deleting files by extension using WMI

Vergleich von WMI und Remove-Item

Bisher haben Sie in diesem Tutorial einen umfassenden Überblick darüber erhalten, wie Sie PowerShell zum Löschen von Dateien verwenden können. Sie haben sowohl über Remove-Item als auch über WMI gelernt. Beide führen ähnliche Funktionen aus, aber auf unterschiedliche Weise.

Welche Methode sollten Sie zum Löschen von Dateien verwenden; Remove-Item oder WMI?

Mit einem integrierten Cmdlet in PowerShell wie Get-ChildItem und Remove-Item ist das Abrufen und Löschen von Dateien viel schneller als bei der Verwendung von WMI.

Das untenstehende Beispiel zeigt den Vergleich zwischen der Verwendung von WMI und dem integrierten PowerShell-Cmdlet zum Abrufen der Liste von Dateien im Verzeichnis C:\windows\web und seinen Unterverzeichnissen.

## Liste aller Dateien in C:\Windows\Web\ rekursiv mit Get-ChildItem
Measure-Command { Get-ChildItem C:\Windows\Web\ -Recurse}

## Liste aller Dateien in C:\Windows\Web\ rekursiv mit Get-CimInstance und WMI-Abfrage
Measure-Command { Get-CimInstance -ClassName Cim_DataFile -Filter "Drive = 'c:' AND Path = '\windows\web\%'"}

Wenn Sie den obigen Code in PowerShell ausführen, sehen Sie eine ähnliche Ausgabe wie unten dargestellt.

Get-ChildItem vs. Get-CimInstance with WMI Query

Wie aus der oben gezeigten Ausgabe ersichtlich ist, dauerte das Auflisten der Dateien in C:\windows\web mit Get-CimInstance fast zehnmal länger als die Zeit, die Get-ChildItem benötigte, um abzuschließen!

Haben Sie auch bemerkt, wie die Zeile mit Get-ChildItem viel kürzer ist als Get-CimInstance? Nicht nur die Ausführung mit Get-ChildItem ist schneller, sondern Sie profitieren auch von einem saubereren und kürzeren Code.

Nächste Schritte

In diesem Artikel haben Sie zwei verschiedene Möglichkeiten kennengelernt, wie Sie in PowerShell Dateien mit integrierten Cmdlets und WMI/CIM löschen können.

Beachten Sie, dass Sie immer die Cmdlets Get-ChildItem und Remove-Item zum Entfernen von Dateien verwenden sollten. Diese integrierten Cmdlets sind flexibler, einfacher und schneller zu verwenden als bei der Verwendung von WMI.

Versuchen Sie, ein Skript zu erstellen, das die Speicherplatzbereinigung für Sie durchführt. Sicherlich gibt es bereits einige Skripte für diesen Zweck; nutzen Sie sie gerne als Referenz, aber wenn Sie üben und lernen möchten, sollten Sie versuchen, Ihr eigenes Skript zu erstellen.

Weitere Informationen

Source:
https://adamtheautomator.com/powershell-to-delete-files/