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

Die Aufrechterhaltung des freien Festplattenspeicherplatzes ist entscheidend für das Management von Servern und Systemen. Als Admins möchten Sie nicht unvorbereitet in einer Situation mit ‚Festplatte voll‘ erwischt werden. Um sicherzustellen, dass Sie auf der sicheren Seite sind, sollten Sie lernen, wie Sie PowerShell zum Löschen von Dateien verwenden können!

In diesem Artikel erfahren Sie praktisch jede Möglichkeit, Dateien von Ihren Systemen mit PowerShell zu entfernen.

Lassen Sie uns anfangen!

Voraussetzungen

In diesem Artikel werden Beispiele mit PowerShell präsentiert, und 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 eine Datei mit PowerShell löschen müssen, werden Sie wahrscheinlich sofort über das Remove-Item-Cmdlet informiert. Dieses Cmdlet ist der de facto Standard zum Entfernen von Dateien mit PowerShell.

Die Verwendung von Remove-Item in Kombination mit dem Get-ChildItem-Cmdlet zum Lesen von Dateien und Ordnern und der leistungsstarken PowerShell-Pipeline kann wirklich alles erleichtern.

Verwandt: Get-ChildItem: Auflisten von Dateien, Registrierung, Zertifikaten und mehr

Wussten Sie, dass das Remove-Item-Cmdlet einen Alias namens del hat? Bei der Arbeit in PowerShell führt die Verwendung von Remove-Item oder del denselben Befehl aus.

Verwenden 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 Code unten löscht die Datei C:\temp\random.txt.

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

Das Ausführen des obigen Codes in PowerShell würde nichts auf dem Bildschirm anzeigen, es sei denn, es wurde ein Fehler festgestellt.

Verwendung von PowerShell zum Löschen aller Dateien im Ordner

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

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

Die Ausgabe sollte wie in dem untenstehenden Screenshot aussehen.

Successfully deleted all files in a folder

Verwendung 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 jedem Unterverzeichnis löschen müssen, müssen Sie den Schalter -Recurse zum Cmdlet 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, in alle Unterverzeichnisse zu schauen und alle Dateilisten abzurufen. Die untenstehende Ausgabe zeigt, dass der Code in der Lage war, Dateien im obersten Verzeichnis zu löschen. Es gelang jedoch nicht, die Dateien in den Unterverzeichnissen abzurufen.

Failed to retrieve files in sub-folders

Umgang mit dem Problem des langen Pfades

Der oben gezeigte Fehler deutet darauf hin, dass PowerShell „einen Teil des Pfads konnte nicht finden“. Dieser Fehler deutet darauf hin, dass der Pfad, den das Cmdlet zu erreichen versucht, nicht existiert – was irreführend ist.

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

Der Screenshot unten zeigt, dass der Pfad oder das Verzeichnis und seine Unterverzeichnisse existieren und eine Textdatei namens InTooDeep.txt im untersten Unterverzeichnis liegt. Die Kombination aller Zeichen, die die verschachtelten Verzeichnisnamen bilden, führt zu einem Problem mit langen Pfaden.

Nested directories creating a long path name

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

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

Unter Verwendung des oben modifizierten Codes, der auf den langen Dateinamen abzielt, zeigt die Ausgabe unten, dass PowerShell den stark verschachtelten Dateinamen erfolgreich gelesen und die Datei gelöscht hat.

Deleted the file with a long path name

Beachten Sie, dass das Problem mit den langen Dateinamen PowerShell 7.0 nicht betrifft. Mit PowerShell 7.0 ist es nicht erforderlich, die Unicode-Version des Pfads zu verwenden, da bereits eine integrierte Unterstützung für lange Dateinamen vorhanden ist.

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

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

Ein weiteres typisches Beispiel für die Verwaltung von Festplattenspeicherplatz ist das Löschen von Dateien, die älter als eine bestimmte Anzahl von Tagen sind. Dieses Beispiel ist nützlich, um alte Protokolldateien zu entfernen, wie sie von IIS-Webservern generiert werden, um Festplattenspeicher freizugeben.

In diesem Beispiel gibt es Dateien in c:\temp, die älter als 14 Tage sind. Mit dem folgenden Skript wird der Name, Erstellungszeitpunkt und Alter in Tagen jeder Datei in c:\temp angezeigt.

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

Wie im untenstehenden Screenshot zu sehen ist, gibt es Dateien, die 15 Tage alt sind, 7 Tage alt sind und 0 Tage alt sind.

List of files in c:\temp

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

In diesem Beispiel-Skript unten 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 ist das Alter in Tagen, das die zu löschende Datei haben muss.

Die nächste Zeile des Codes nach der Variablen $threshold wird:

  • Die Sammlung von Dateien abrufen, die sich im im $path-Variablen angegebenen Ordner befinden. In diesem Beispiel ist der Pfad C:\temp.
  • Filtern Sie die Ausgabe, 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, sehen Sie eine Ausgabe wie unten gezeigt.

The script deleted the files older than 14 days

Beachten Sie, dass basierend auf der ausführlichen Meldung im Screenshot das Skript nur fünf Dateien gelöscht hat, die älter als 14 Tage sind. Um zu bestätigen, dass Dateien, die neuer als 14 Tage sind, immer noch 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 Suchen 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 eingeschlossen werden im Löschvorgang.

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

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

Eine andere Möglichkeit ist vielleicht der vorsichtige Ansatz, 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 Remove-Item-Befehl weiterleiten.

Zum Beispiel ruft der folgende Code die *.LOG-Dateien in c:\temp ab.

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

Als Ergebnis des obigen Codes gibt Get-ChildItem eine Liste von Dateien zurück, die dem *.LOG-Dateinamen 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. Speziell die Datei Datei_5.log ist 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, können Sie die Dateisammlung an das Remove-Item-Cmdlet übergeben, um diese Dateien endlich 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 dafür haben, wie das übliche Remove-Item-Cmdlet zum Entfernen von Dateien verwendet wird, springen wir in einen fortgeschritteneren Anwendungsfall: die Verwendung von WMI.

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

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

Die Verwendung von PowerShell und WMI zum Löschen einer Datei

In diesem Beispiel wird davon ausgegangen, dass Sie den Pfad der spezifischen zu löschenden Datei kennen. Das Get-CimInstance-Cmdlet mit der Klasse Cim_DataFile wird verwendet, um die Informationen über die zu löschende Datei abzurufen, die C:\Temp\random.txtist.

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

In obigem Code akzeptiert der -Filter-Parameter eine WQL-Formatabfrage. Die Verwendung von WQL erfordert, dass Sie einige Zeichen, einschließlich des Backslashes, escapen. Da das Escape-Zeichen für WQL auch der Backslash ist, ergeben sich die doppelten Backslash-Zeichen – \\.

Das Ausführen des obigen Codes ergibt das unten gezeigte Ergebnis. Die Informationen zu C:\Temp\random.txt werden in der Variablen $file2delete gespeichert

Getting a file using WMI query and PowerShell

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

$file2delete | Invoke-CimMethod -Name Delete

Wie Sie auf dem untenstehenden Screenshot sehen können, zeigt der ReturnValue 0, was bedeutet, dass der Befehl erfolgreich war.

File successfully deleted using WMI and PowerShell

Um mehr über die möglichen ReturnValue-Codes zu erfahren, verweisen Sie bitte auf diesen Link – Löschmethode der CIM_DataFile-Klasse

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

C:\Temp\random.txt file was deleted

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

In diesem nächsten Beispiel zeige ich Ihnen, wie Sie alle Dateien in einem Ordner mithilfe von PowerShell und WMI löschen können. Die gleichen Cmdlets, die im vorherigen Beispiel verwendet wurden, nämlich Get-CimInstance und Invoke-CimMethod, werden verwendet. Dieses Mal wird jedoch die WQL-Abfrage alle Dateien im Ordner abrufen, anstatt nur eine bestimmte Datei.

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

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

Das Ausführen des obigen Codes speichert die abgerufenen Informationen über die Dateien in C:\temp in der Variable $file2delete. Das Anzeigen des Wertes oder der Werte der Variable $file2delete zeigt die folgende Ausgabe.

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

Jetzt können die Werte, die in der Variable $file2delete gespeichert sind, an Invoke-CimMethod weitergeleitet werden, um alle Dateien in c:\temp zu löschen.

$file2delete | Invoke-CimMethod -Name Delete

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

All files in c:\temp deleted using WMI

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

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.

Sie werden im folgenden Code bemerken, dass dieses Mal die Abfrage eine zusätzliche Bedingung hat (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 Zeichenkette aus null oder mehr Zeichen“ bedeutet. In programmtechnischen Begriffen ist das % das Äquivalent eines Platzhalters, der das Asterisk-Zeichen (*) ist.

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

$file2delete | Invoke-CimMethod -Name Delete

Die nachfolgende Demonstration zeigt, dass vor der Ausführung des obigen Codes neun *.LOG-Dateien und nur eine *.TXT-Datei vorhanden sind. Sobald der Code ausgeführt 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 in diesem Tutorial haben Sie 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 sehr unterschiedliche Weise.

Welche Methode sollten Sie verwenden, um Dateien zu löschen; Remove-Item oder WMI?

Die Verwendung eines integrierten Cmdlets in PowerShell wie Get-ChildItem und Remove-Item zum Abrufen und Löschen von Dateien ist wesentlich schneller als die Verwendung von WMI.

Das folgende Beispiel zeigt den Vergleich bei der Verwendung von WMI und des integrierten PowerShell-Cmdlets zum Abrufen der Liste von Dateien im Verzeichnis C:\windows\web und dessen Unterordnern.

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

## Auflisten 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 ein ähnliches Ergebnis wie unten dargestellt.

Get-ChildItem vs. Get-CimInstance with WMI Query

Wie Sie aus dem oben gezeigten Ergebnis sehen können, dauerte das Auflisten der Dateien in C:\windows\web fast zehnmal länger mit Get-CimInstance, als es mit Get-ChildItem dauerte!

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

Nächste Schritte

In diesem Artikel haben Sie die beiden verschiedenen Möglichkeiten gesehen, wie Sie PowerShell zum Löschen von Dateien mit integrierten Cmdlets und WMI/CIM verwenden können.

Beachten Sie, dass Sie immer das Get-ChildItem– und Remove-Item-Cmdlet verwenden sollten, um Dateien zu entfernen. Diese integrierten Cmdlets sind flexibler, einfacher und schneller zu verwenden als WMI.

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

Weitere Informationen

Source:
https://adamtheautomator.com/powershell-delete-file/