Efficiënte bestandsverwijdering met PowerShell: Remove-Item en WMI

Het handhaven van vrije schijfruimte is cruciaal bij het beheren van servers en systemen. Als beheerders wil je niet verrast worden door een ‘schijf vol’ situatie. Om ervoor te zorgen dat je in de clear bent, moet je leren hoe je PowerShell kunt gebruiken om bestanden te verwijderen!

In dit artikel leer je zo ongeveer elke manier om bestanden van je systemen te verwijderen met PowerShell.

Laten we beginnen!

Vereisten

Dit artikel bevat voorbeelden met behulp van PowerShell, en als je wilt volgen, heb je het volgende nodig.

Het gebruik van de Remove-Item Cmdlet om bestanden te verwijderen

Als je gewoon PowerShell moet gebruiken om een bestand te verwijderen, zul je waarschijnlijk meteen leren over de Remove-Item cmdlet. Deze cmdlet is de facto standaard voor het verwijderen van bestanden met PowerShell.

Het gebruik van Remove-Item in combinatie met de Get-ChildItem cmdlet om bestanden en mappen te lezen en de krachtige PowerShell-pipeline kan echt het werk vergemakkelijken.

Gerelateerd: Get-ChildItem: Bestanden, Register, Certificaten en meer vermelden

Wist je dat de Remove-Item cmdlet een alias heeft onder de naam del? Wanneer je werkt in PowerShell, zal het gebruik van Remove-Item of del dezelfde opdracht uitvoeren.

Het gebruik van PowerShell om een bestand te verwijderen

Het eerste voorbeeld dat het meest nuttig zou zijn, is het meest basale – dat wil zeggen, het verwijderen van een enkel bestand. Om slechts één bestand te verwijderen, hoef je alleen maar de onderstaande opdracht te gebruiken. De code hieronder verwijdert het bestand C:\temp\random.txt.

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

Als je de bovenstaande code in PowerShell uitvoert, wordt er niets op het scherm weergegeven tenzij er een fout is opgetreden.

Gebruik PowerShell om alle bestanden in een map te verwijderen

In dit voorbeeld verwijdert de onderstaande code alle bestanden in een map. De cmdlet Get-ChildItem richt zich op C:\temp met de parameter -Path. De parameter -File geeft aan dat het enige type item dat moet worden opgenomen, bestanden zijn. Get-ChildItem negeert mappen.

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

De uitvoer zou eruit moeten zien zoals de onderstaande schermafbeelding.

Successfully deleted all files in a folder

Gebruik PowerShell om alle bestanden recursief te verwijderen

Het vorige voorbeeld verwijderde alleen bestanden in de map C:\temp. Als je ook de bestanden in elke submap wilt verwijderen, moet je de schakelaar -Recurse toevoegen aan de cmdlet Get-ChildItem om alle bestanden recursief te verkrijgen.

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

Het bovenstaande codevoorbeeld dwingt PowerShell om alle submappen te doorzoeken en alle lijsten met bestanden op te halen. De onderstaande uitvoer toont aan dat de code in staat was om bestanden in de hoofdmap te verwijderen; echter, het lukte niet om de bestanden in de submappen op te halen.

Failed to retrieve files in sub-folders

Omgaan met het probleem van het lange pad

De hierboven getoonde fout geeft aan dat PowerShell “een deel van het pad kon niet worden gevonden”. Die fout geeft aan dat het pad waar de cmdlet probeert te komen, niet bestaat – wat misleidend is.

In dit geval was de fout omdat het pad dat de Get-ChildItem probeert te lezen de maximale padlengte van 260 tekens overschrijdt.

De onderstaande schermafbeelding toont aan dat het pad of de map en de submappen bestaan en dat er één tekstbestand met de naam InTooDeep.txt zich bevindt in de onderste submap. De combinatie van alle tekens die de geneste mapnamen vormen, veroorzaakt een probleem met een lang pad.

Nested directories creating a long path name

In Windows PowerShell 5.1 is er een omweg voor het probleem met de lange padnaam. De omweg is om de Unicode-versie van het pad te gebruiken. In plaats van het pad als volgt te specificeren – C:\temp, gebruik de Unicode-versie als volgt – ‘\\?\C:\temp’ voor mappen die lokaal zijn gelegen, of ‘\\?\UNC\<computernaam>\<delen>\Temp’ als de map zich in een UNC-pad bevindt.

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

Met behulp van de aangepaste code hierboven die rekening houdt met de lange padnaam, laat de onderstaande uitvoer zien dat PowerShell de diep geneste padnaam succesvol heeft gelezen en het bestand heeft verwijderd.

Deleted the file with a long path name

Merk op dat het probleem met de lange padnaam geen invloed heeft op PowerShell 7.0. Met PowerShell 7.0 is het niet nodig om de Unicode-versie van het pad te gebruiken omdat het al ingebouwde ondersteuning heeft voor lange padnamen.

Als de mappen ook moeten worden verwijderd, verwijder dan gewoon de -File-parameter uit de Get-ChildItem-cmdlet, en PowerShell zou alle items moeten verwijderen, inclusief bestanden en mappen.

Gebruik PowerShell om bestanden ouder dan x dagen te verwijderen

Een ander typisch voorbeeld van opruimen van schijfruimte is het verwijderen van bestanden die ouder zijn dan een specifiek aantal dagen. Dit voorbeeld is handig voor het verwijderen van oude logbestanden, zoals die gegenereerd worden door IIS-webservers, om schijfruimte vrij te maken.

In dit voorbeeld zijn er bestanden in c:\temp die ouder zijn dan 14 dagen. Met behulp van het onderstaande script wordt de Naam, CreatieTijd en LeeftijdInDagen van elk bestand in c:\temp getoond.

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

Zoals je kunt zien in de onderstaande schermafbeelding, zijn er bestanden die 15 dagen oud zijn, 7 dagen oud en 0 dagen oud.

List of files in c:\temp

Nu je weet welke bestanden je moet verwijderen, kun je een script maken om alleen bestanden te verwijderen die ouder zijn dan een specifiek aantal dagen – in dit geval ouder dan 14 dagen.

In het onderstaande voorbeeldscript worden bestanden in C:\temp waarvan de waarde van CreationTime ouder is dan de ingestelde drempel, verwijderd.

De eerste regel definieert het pad voor Get-ChildItem om te doorzoeken. Het pad wordt opgeslagen in de variabele $path. Vervolgens wordt op de tweede regel de drempel gespecificeerd. De waarde van de variabele $threshold is de leeftijd in dagen waarop het te verwijderen bestand moet zijn.

De volgende regel code na de variabele $threshold zal:

  • De verzameling bestanden ophalen die zich bevinden in de map gespecificeerd in de variabele $path. In dit voorbeeld is het pad C:\temp.
  • De uitvoer filteren om alleen bestanden op te nemen waarvan de waarde van CreationTime ouder is dan het aantal dagen dat is opgeslagen in de variabele $threshold. In dit voorbeeld is de drempel 14 dagen.
  • Voer de gefilterde lijst met bestanden door naar de Remove-Item waarde om die bestanden te verwijderen.
$path = 'C:\Temp'
$threshold = 14
Get-ChildItem -Path $path -File | Where-Object {$PSItem.CreationTime -lt (Get-Date).AddDays(-$threshold)} |Remove-Item -Verbose

Wanneer je de bovenstaande code uitvoert, zie je een uitvoer zoals hieronder weergegeven.

The script deleted the files older than 14 days

Merk op dat uit het bovenstaande schermvoorbeeld, op basis van het uitgebreide bericht, het script alleen vijf bestanden ouder dan 14 dagen heeft verwijderd. Om te bevestigen dat bestanden nieuwer dan 14 dagen nog steeds bestaan, voer je de onderstaande code uit om ze opnieuw te vermelden.

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

Het resultaat hieronder bevestigt dat Remove-Item de nieuwere bestanden niet heeft verwijderd.

Newer files are left untouched

Het gebruik van PowerShell om bestandspatronen overeen te laten komen en te verwijderen

Het verwijderen van alle bestanden, ongeacht naam, type of extensie, is niet altijd de beste aanpak. Soms moet je expliciet bepaalde bestanden uitsluiten of opnemen in het verwijderingsproces.

Het volgende voorbeeld hieronder laat zien hoe je de bestanden verwijdert die overeenkomen met *.LOG bestandsnaam. Een manier om dit te doen is door direct de Remove-Item cmdlet te gebruiken met behulp van de -Include parameter, zoals hieronder getoond.

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

Een andere manier is misschien de voorzichtige aanpak, namelijk eerst Get-ChildItem gebruiken om de lijst met te verwijderen bestanden te verzamelen. Pas wanneer je tevreden bent met de lijst met te verwijderen bestanden, kun je de verzameling uiteindelijk doorsturen naar de Remove-Item cmdlet.

Bijvoorbeeld, de onderstaande code haalt die *.LOG bestanden op in c:\temp.

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

Als gevolg van de bovenstaande code retourneert Get-ChildItem een lijst met bestanden die overeenkomen met de *.LOG bestandsnaam.

Only files matching the *.log filename is returned

Maar wat als je een bestand wilt uitsluiten dat het nummer 5 in zijn naam heeft? Dit kun je doen door de -Exclude-parameter toe te voegen zoals in de volgende code.

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

Doordat je het bestand met het nummer 5 hebt uitgesloten, is het resultaat nu anders. Specifiek staat het bestand Bestand_5.log nu niet meer op de lijst, zoals hieronder getoond.

The file File_5.log was excluded

Wanneer je al tevreden bent met de verzameling bestanden die je code heeft gemaakt, kun je de bestandsverzameling doorgeven aan de Remove-Item-cmdlet om eindelijk die bestanden te verwijderen.

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

Na het uitvoeren van je definitieve code, heb je je doel bereikt om alleen de geselecteerde bestanden te verwijderen.

Deleting selected files

Bestanden verwijderen met behulp van WMI in PowerShell

Nu je een goed begrip hebt van het gebruiken van de algemene Remove-Item-cmdlet om bestanden te verwijderen, laten we ons storten op een geavanceerder gebruik; het gebruik van WMI.

PowerShell wordt geleverd met ondersteuning voor WMI. En ondersteuning voor WMI betekent dat WMI-query’s en -methoden vanuit PowerShell kunnen worden aangeroepen. Ja, WMI is niet alleen voor Visual Basic-scripts die beheerders vroeger gebruikten in de beginjaren van Windows.

Microsoft heeft WMI-specifieke CIM-cmdlets uitgebracht in PowerShell 3.0. De CIM-cmdlets die worden gebruikt om bestanden te verwijderen zijn Get-CimInstance en Invoke-CimMethod.

Het gebruik van PowerShell en WMI om een bestand te verwijderen

Deze voorbeeld veronderstelt dat u het pad van het specifieke te verwijderen bestand kent. De Get-CimInstance cmdlet met de Cim_DataFile klasse wordt gebruikt om de informatie over het te verwijderen bestand op te halen, dat is C:\Temp\random.txt.

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

In de bovenstaande code accepteert de -Filter parameter een WQL formaat query. Het gebruik van WQL vereist dat u enkele tekens escapet, inclusief de backslash. En, aangezien het escapeteken voor WQL ook de backslash is, resulterend in de dubbele backslash tekens – \\.

Het uitvoeren van de bovenstaande code produceert het resultaat dat wordt getoond in de onderstaande demonstratie. De informatie over C:\Temp\random.txt wordt opgeslagen in de $file2delete variabele

Getting a file using WMI query and PowerShell

Nu de informatie voor het bestand C:\Temp\random.txt is opgehaald, kan het resulterende object in de $file2delete variabele worden doorgestuurd naar de Invoke-CimMethod cmdlet. De Invoke-CimMethod cmdlet heeft een parameter genaamd -Name, die de naam van de methode van de Cim_DataFile klasse vertegenwoordigt.

$file2delete | Invoke-CimMethod -Name Delete

Zoals u kunt zien in de onderstaande schermafbeelding, toont de ReturnValue 0, wat betekent dat de opdracht succesvol was.

File successfully deleted using WMI and PowerShell

Om meer te weten te komen over de mogelijke ReturnValue-codes, zie deze link – Delete-methode van de CIM_DataFile-klasse

Bovendien toont de onderstaande schermafbeelding aan dat na het uitvoeren van de Invoke-CimMethod Delete()-methode, CIM alleen het bestand C:\Temp\random.txt heeft verwijderd. Het heeft de andere bestanden niet verwijderd.

C:\Temp\random.txt file was deleted

Gebruik van PowerShell en WMI om alle bestanden in een map te verwijderen

In dit volgende voorbeeld laat ik zien hoe je alle bestanden in een map kunt verwijderen met behulp van PowerShell en WMI. Dezelfde cmdlets die in het vorige voorbeeld zijn gebruikt, namelijk Get-CimInstance en Invoke-CimMethod, zullen worden gebruikt. Maar deze keer zal de WQL-query alle bestanden in de map ophalen in plaats van slechts één specifiek bestand.

In de volgende code haalt de Get-CimInstance-cmdlet alle bestanden op die zich bevinden in C:\temp. Zoals je hieronder kunt zien, filtert de query de Drive– en Path-eigenschappen van de Cim_DataFile-klasse.

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

Het uitvoeren van de bovenstaande code slaat de opgehaalde informatie over de bestanden in C:\temp op in de variabele $file2delete. Het bekijken van de waarde(n) van de variabele $file2delete toont de onderstaande uitvoer.

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

Nu kunnen de waarden die zijn opgeslagen in de variabele $file2delete worden doorgegeven aan de Invoke-CimMethod om alle bestanden in c:\temp te verwijderen.

$file2delete | Invoke-CimMethod -Name Delete

Onthoud, de ReturnValue-code van 0 betekent succesvol, en voor elk bestand waarop de verwijdermethode is aangeroepen, heeft zijn eigen ReturnValue-code.

All files in c:\temp deleted using WMI

Het gebruik van PowerShell en WMI om bestanden op extensie te verwijderen

Je hebt in het vorige voorbeeld gezien hoe je alle bestanden in een map kunt verwijderen ongeacht de extensie. Je kunt echter ook controleren welke bestanden worden verwijderd op basis van de extensie.

Je zult merken in de onderstaande code dat deze keer de query een extra voorwaarde heeft (Name LIKE '%.log). Deze toegevoegde voorwaarde betekent dat alleen bestanden die overeenkomen met de extensie .LOG worden geretourneerd. Het procentteken (%) is een WQL LIKE-operator die betekent “Een tekenreeks van nul of meer tekens”. In programmeertermen is het % het equivalent van een wildcard, wat het asterisk-teken (*) is.

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

$file2delete | Invoke-CimMethod -Name Delete

De onderstaande demonstratie laat zien dat voordat de bovenstaande code wordt uitgevoerd, er negen *.LOG-bestanden zijn en slechts één *.TXT-bestand. Zodra de code is uitgevoerd, worden de *.LOG-bestanden verwijderd en blijft het *.TXT-bestand als enige over in de map.

Deleting files by extension using WMI

Vergelijking tussen WMI en Remove-Item

Tot nu toe in deze tutorial heb je een breed overzicht gekregen van hoe je PowerShell kunt gebruiken om bestanden te verwijderen. Je hebt geleerd over Remove-Item en ook over WMI. Beide voeren vergelijkbare functies uit, maar op een heel andere manier.

Welke methode moet je gebruiken om bestanden te verwijderen; Remove-Item of WMI?

Het gebruik van een ingebouwde cmdlet in PowerShell zoals Get-ChildItem en Remove-Item om bestanden op te halen en te verwijderen gaat veel sneller dan wanneer je WMI gebruikt.

Het voorbeeld hieronder laat een vergelijking zien tussen het gebruik van WMI en de ingebouwde PowerShell-cmdlet om de lijst met bestanden onder de map C:\windows\web en de onderliggende mappen op te halen.

## Lijst alle bestanden op in C:\Windows\Web\ recursief met behulp van Get-ChildItem
Measure-Command { Get-ChildItem C:\Windows\Web\ -Recurse}

## Lijst alle bestanden op in C:\Windows\Web\ recursief met behulp van Get-CimInstance en WMI Query
Measure-Command { Get-CimInstance -ClassName Cim_DataFile -Filter "Drive = 'c:' AND Path = '\windows\web\%'"}

Wanneer je de bovenstaande code uitvoert in PowerShell, zie je een output vergelijkbaar met hieronder.

Get-ChildItem vs. Get-CimInstance with WMI Query

Zoals je kunt zien aan de output hierboven, duurde het bijna tien keer langer om de bestanden in C:\windows\web op te halen met Get-CimInstance dan met Get-ChildItem!

Heb je ook opgemerkt hoe de regel met Get-ChildItem veel korter is dan die met Get-CimInstance? Niet alleen krijg je snellere uitvoering met Get-ChildItem, maar je profiteert ook van schonere en kortere code.

Volgende stappen

In dit artikel heb je de twee verschillende manieren gezien waarop je PowerShell kunt gebruiken om bestanden te verwijderen met ingebouwde cmdlets en WMI/CIM.

Weet dat je altijd de Get-ChildItem en Remove-Item cmdlet moet gebruiken om bestanden te verwijderen. Deze ingebouwde cmdlets zijn flexibeler, eenvoudiger en sneller te gebruiken dan bij het gebruik van WMI.

Probeer een script te bedenken dat de schijfruimte schoonmaakt. Er zijn al scripts voor dat doel, maar als je wilt oefenen en leren, zou je je eigen script moeten proberen te maken.

Verder lezen

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