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 wilt u niet verrast worden door een ‘schijf vol’ situatie. Om er zeker van te zijn dat u veilig bent, moet u leren hoe u PowerShell kunt gebruiken om bestanden te verwijderen!

In dit artikel leert u vrijwel elke manier om bestanden van uw systemen te verwijderen met PowerShell.

Laten we beginnen!

Vereisten

Dit artikel geeft voorbeelden met behulp van PowerShell, en als u wilt volgen, heeft u het volgende nodig.

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

Wanneer u eenvoudigweg PowerShell wilt gebruiken om een bestand te verwijderen, zult u waarschijnlijk direct 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, samen met de krachtige PowerShell-pijplijn, kan de zaken echt eenvoudig maken.

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

Wist u dat de Remove-Item cmdlet een alias heeft met de naam del? Bij het werken in PowerShell voert het gebruik van Remove-Item of del dezelfde opdracht uit.

Het gebruik van PowerShell om een bestand te verwijderen

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

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

Het uitvoeren van de bovenstaande code in PowerShell zou niets op het scherm laten zien, tenzij er een fout is opgetreden.

Gebruik van PowerShell om alle bestanden in een map te verwijderen

In dit voorbeeld verwijdert de onderstaande code alle bestanden in een map. Het Get-ChildItem cmdlet richt zich op  C:\temp met de -Path parameter. De -File parameter 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 als de onderstaande schermafbeelding.

Successfully deleted all files in a folder

PowerShell gebruiken om alle bestanden recursief te verwijderen

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

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

Het uitvoeren van de bovenstaande code dwingt PowerShell om alle submappen te doorzoeken en de lijst met bestanden op te halen. De uitvoer hieronder toont aan dat de code in staat was om bestanden in de hoofdmap te verwijderen; het kon echter niet de bestanden in de submappen ophalen.

Failed to retrieve files in sub-folders

Omgaan met het probleem van lange paden

De hierboven weergegeven fout geeft aan dat PowerShell “een deel van het pad niet kon vinden”. Die fout geeft aan dat het pad dat het cmdlet probeert te bereiken niet bestaat – wat misleidend is.

In dit geval was de fout te wijten aan het feit dat 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 onderliggende submappen bestaan en dat er één tekstbestand genaamd InTooDeep.txt zich bevindt in de onderste submap. Het samenvoegen van alle tekens die de geneste mapnamen vormen, veroorzaakt een probleem met de lange padnaam.

Nested directories creating a long path name

In Windows PowerShell 5.1 is er een workaround voor het probleem van de lange padnaam. De workaround is om de Unicode-versie van het pad te gebruiken. In plaats van het pad op deze manier op te geven – C:\temp, gebruik de Unicode-versie zoals deze – ‘\\?\C:\temp’ voor lokaal gelegen mappen, of ‘\\?\UNC\<computername>\<share>\Temp’ als de map zich in een UNC-pad bevindt.

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

Met de aangepaste code hierboven die is afgestemd op de lange padnaam, toont de onderstaande uitvoer aan 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 van 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 ook de mappen moeten worden verwijderd, verwijder dan eenvoudig de parameter -File 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

Nog een typisch voorbeeld van het 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 het onderstaande script wordt de Naam, CreatieTijd en LeeftijdInDagen van elk bestand in c:\temp weergegeven.

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 zijn en 0 dagen oud zijn.

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 drempelwaarde, 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 drempelwaarde gespecificeerd. De waarde van de $threshold is de ouderdom in dagen die het te verwijderen bestand moet hebben.

De volgende regel code na de variabele $threshold zal:

  • De verzameling bestanden ophalen die zich bevinden in de map die is gespecificeerd in de variabele $path. In dit voorbeeld is het pad C:\temp.
  • Filter de uitvoer 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 drempelwaarde 14 dagen.
  • Buis de gefilterde lijst met bestanden door naar de Remove-Item-waarde om deze 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 output zoals hieronder weergegeven.

The script deleted the files older than 14 days

Merk op dat op basis van het uitgebreide bericht in de screenshot, het script slechts vijf bestanden heeft verwijderd die ouder zijn dan 14 dagen. Om te bevestigen dat nieuwere bestanden dan 14 dagen nog steeds bestaan, voer je de onderstaande code uit om ze opnieuw op te sommen.

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 te matchen en te verwijderen

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

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

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

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

Bijvoorbeeld, de onderstaande code krijgt de *.LOG-bestanden in c:\temp.

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

Als resultaat 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 de 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*

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

The file File_5.log was excluded

Als je al tevreden bent met de verzameling bestanden die je code genereert, kun je de bestandsverzameling doorpompen naar de Remove-Item-cmdlet om die bestanden uiteindelijk te verwijderen.

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

Na het uitvoeren van je laatste 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 gebruik van de gebruikelijke Remove-Item-cmdlet om bestanden te verwijderen, laten we een meer geavanceerd gebruiksscenario bekijken; 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 in de vroegere dagen van Windows gebruikten.

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

Using PowerShell en WMI om een bestand te verwijderen

Deze voorbeeld gaat ervan uit dat je het pad van het specifieke te verwijderen bestand kent. De Get-CimInstance-cmdlet met de Cim_DataFile-klasse wordt gebruikt om informatie over het te verwijderen bestand op te halen, in dit geval 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-opmaakquery. Bij het gebruik van WQL is het nodig om sommige tekens te escapen, waaronder de backslash. Aangezien het escape-teken voor WQL ook de backslash is, leidt dit tot dubbele backslash-tekens – \\.

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

Getting a file using WMI query and PowerShell

Nu de informatie over het bestand C:\Temp\random.txt is opgehaald, kan het resulterende object in de variabele $file2delete worden doorgegeven aan 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 je ziet 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, raadpleeg deze link – Verwijdermethode van de CIM_DataFile-klasse

Bovendien laat de onderstaande schermafbeelding zien 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 u alle bestanden in een map kunt verwijderen met behulp van PowerShell en WMI. Dezelfde cmdlets die in het vorige voorbeeld werden gebruikt, namelijk Get-CimInstance en Invoke-CimMethod, zullen worden gebruikt. Maar dit 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 u 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 op in C:\temp 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 doorgestuurd naar Invoke-CimMethod om alle bestanden in c:\temp te verwijderen.

$file2delete | Invoke-CimMethod -Name Delete

Onthoud dat de ReturnValue-code van 0 betekent dat de operatie succesvol was, en voor elk bestand waarop de verwijdermethode is toegepast, heeft het zijn eigen ReturnValue-code.

All files in c:\temp deleted using WMI

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 dat in de onderstaande code dit keer de query een extra voorwaarde heeft (Name LIKE '%.log). Deze extra voorwaarde betekent dat alleen bestanden die overeenkomen met de .LOG-extensie worden teruggegeven. Het procentteken (%) is een WQL LIKE-operator die betekent “Een reeks van nul of meer tekens”. In programmeertermen is de % het equivalent van een wildcard, dat is het asterisk-teken (*).

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

$file2delete | Invoke-CimMethod -Name Delete

De demonstratie hieronder 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 handleiding heb je een breed overzicht gekregen van hoe je PowerShell kunt gebruiken om bestanden te verwijderen. Je hebt kennis gemaakt met Remove-Item en ook WMI. Beide voeren soortgelijke 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, is veel sneller dan wanneer je WMI gebruikt.

Het onderstaande voorbeeld toont de vergelijking 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 te krijgen.

## Toon alle bestanden in C:\Windows\Web\ recursief met Get-ChildItem
Measure-Command { Get-ChildItem C:\Windows\Web\ -Recurse}

## Toon alle bestanden in C:\Windows\Web\ recursief met 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 getoonde output, duurde het bijna tien keer langer om de bestanden in C:\windows\web op te sommen met Get-CimInstance dan de tijd die Get-ChildItem nodig had om te voltooien!

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 cmdlets Get-ChildItem en Remove-Item moet gebruiken om bestanden te verwijderen. Deze ingebouwde cmdlets zijn flexibeler, eenvoudiger en sneller te gebruiken dan het gebruik van WMI.

Probeer een script te bedenken dat schijfruimtebeheer voor je kan uitvoeren. Er zijn zeker al enkele scripts voor dat doel; gebruik ze gerust als referentie, maar als je wilt oefenen en leren, zou je moeten proberen je eigen script te maken.

Verder lezen

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