Suppression efficace de fichiers avec PowerShell : Remove-Item et WMI

Maintenir un espace disque libre est crucial lors de la gestion des serveurs et des systèmes. En tant qu’administrateurs, vous ne voudriez pas être pris au dépourvu par une situation de ‘disque plein’. Pour vous assurer que vous êtes en sécurité, vous devriez apprendre à utiliser PowerShell pour supprimer des fichiers!

Dans cet article, vous apprendrez pratiquement toutes les façons de supprimer des fichiers de vos systèmes avec PowerShell.

Commençons!

Prérequis

Cet article présente des exemples utilisant PowerShell, et si vous prévoyez de suivre, vous aurez besoin des éléments suivants.

Utilisation de la cmdlet Remove-Item pour supprimer des fichiers

Lorsque vous avez simplement besoin d’utiliser PowerShell pour supprimer un fichier, vous apprendrez probablement immédiatement à propos de la cmdlet Remove-Item. Cette cmdlet est la norme de facto pour supprimer des fichiers avec PowerShell.

L’utilisation de Remove-Item combinée à la cmdlet Get-ChildItem pour lire les fichiers et dossiers et le puissant pipeline PowerShell peut vraiment faciliter les choses.

Connexe: Get-ChildItem: Listing Files, Registry, Certificates and More

Saviez-vous que la cmdlet Remove-Item a un alias sous le nom de del? Lorsque vous travaillez dans PowerShell, utiliser Remove-Item ou del exécutera la même commande.

Utilisation de PowerShell pour supprimer un fichier

Le premier exemple qui serait le plus utile est le plus basique – c’est-à-dire, supprimer un seul fichier. Pour supprimer juste un seul fichier, vous avez seulement besoin d’utiliser la commande ci-dessous. Le code ci-dessous supprime le fichier C:\temp\random.txt.

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

Exécuter le code ci-dessus en PowerShell ne montrerait rien à l’écran sauf s’il y avait une erreur rencontrée.

Utiliser PowerShell pour supprimer tous les fichiers dans un dossier

Dans cet exemple, le code ci-dessous supprime tous les fichiers dans un dossier. La commande Get-ChildItem cible C:\temp avec le paramètre -Path. Le paramètre -File indique que le seul type d’élément à inclure sont les fichiers. Get-ChildItem ignore les dossiers.

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

La sortie devrait ressembler à cette capture d’écran ci-dessous.

Successfully deleted all files in a folder

Utiliser PowerShell pour supprimer tous les fichiers de manière récursive

L’exemple précédent a seulement supprimé les fichiers dans le dossier C:\temp. Si vous avez besoin de supprimer également les fichiers à l’intérieur de chaque sous-dossier, vous devez ajouter l’option -Recurse à la commande Get-ChildItem pour obtenir tous les fichiers de manière récursive.

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

Exécuter le code ci-dessus oblige PowerShell à examiner tous les sous-dossiers et à récupérer la liste de tous les fichiers. La sortie ci-dessous montre que le code a pu supprimer les fichiers dans le dossier principal ; cependant, il n’a pas réussi à récupérer les fichiers dans les sous-dossiers.

Failed to retrieve files in sub-folders

Résoudre le problème du chemin long

L’erreur affichée ci-dessus indique que PowerShell “ne peut pas trouver une partie du chemin”. Cette erreur indique que le chemin vers lequel la commande essaie d’accéder n’existe pas – ce qui est trompeur.

Dans ce cas, l’erreur s’est produite parce que le chemin que Get-ChildItem tente de lire dépasse la longueur maximale du chemin de 260 caractères.

La capture d’écran ci-dessous montre que le chemin ou le répertoire et ses sous-répertoires existent et qu’un fichier texte nommé InTooDeep.txt est situé dans le sous-répertoire le plus bas. La combinaison de tous les caractères qui composent les noms de répertoires imbriqués crée un problème de chemin long.

Nested directories creating a long path name

Dans Windows PowerShell 5.1, il existe une solution de contournement au problème du nom de chemin long. La solution consiste à utiliser la version Unicode du chemin. Au lieu de spécifier le chemin comme ceci – C:\temp, utilisez la version Unicode comme ceci – ‘\\?\C:\temp’ pour les dossiers situés localement, ou ‘\\?\UNC\<nomd’ordinateur>\<partage>\Temp’ si le dossier est situé dans un chemin UNC.

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

En utilisant le code modifié ci-dessus qui prend en compte le nom de chemin long, la sortie ci-dessous montre que PowerShell a réussi à lire le nom de chemin profondément imbriqué et a supprimé le fichier.

Deleted the file with a long path name

Notez que le problème du nom de chemin long n’affecte pas PowerShell 7.0. Avec PowerShell 7.0, il n’est pas nécessaire d’utiliser la version Unicode du chemin car il prend déjà en charge intégrée les noms de chemin longs.

Si les dossiers doivent également être supprimés, il suffit de supprimer le paramètre -File de la cmdlet Get-ChildItem, et PowerShell devrait supprimer tous les éléments, y compris les fichiers et les dossiers.

Utilisation de PowerShell pour supprimer les fichiers plus anciens que x jours

Un autre exemple typique de gestion de l’espace disque consiste à supprimer les fichiers qui sont plus anciens qu’un nombre spécifique de jours. Cet exemple est utile pour supprimer les anciens fichiers journaux, comme ceux générés par les serveurs web IIS, afin de libérer de l’espace disque.

Dans cet exemple, il y a des fichiers dans c:\temp qui sont plus anciens que 14 jours. En utilisant le script ci-dessous, le Nom, CreationTime, et AgeInDays de chaque fichier dans c:\temp est montré.

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

Comme vous pouvez le voir dans la capture d’écran ci-dessous, il y a des fichiers qui ont 15 jours, 7 jours, et 0 jours.

List of files in c:\temp

Maintenant que vous connaissez les fichiers à supprimer, vous pouvez créer un script pour ne supprimer que les fichiers qui sont plus anciens qu’un nombre spécifique de jours – dans ce cas, plus anciens que 14 jours.

Dans ce script d’exemple ci-dessous, les fichiers dans C:\temp dont la valeur de CreationTime est plus ancienne que le seuil défini seront supprimés.

La première ligne définit le chemin pour que Get-ChildItem recherche. Le chemin est enregistré dans la variable $path. Ensuite, la deuxième ligne est où le seuil est spécifié. La valeur du $threshold est l’âge en jours que le fichier à supprimer doit avoir.

La ligne de code suivante après la variable $threshold fera ce qui suit:

  • Obtenir la collection de fichiers situés dans le dossier spécifié dans la variable $path. Dans cet exemple, le chemin est C:\temp.
  • Filtrer la sortie pour inclure uniquement les fichiers dont la valeur de CreationTime est plus ancienne que le nombre de jours enregistré dans la variable $threshold. Dans cet exemple, le seuil est de 14 jours.
  • Passez la liste filtrée des fichiers à la valeur Remove-Item pour effectuer la suppression de ces fichiers.
$path = 'C:\Temp'
$threshold = 14
Get-ChildItem -Path $path -File | Where-Object {$PSItem.CreationTime -lt (Get-Date).AddDays(-$threshold)} |Remove-Item -Verbose

Lorsque vous exécutez le code ci-dessus, vous verrez une sortie comme indiqué ci-dessous.

The script deleted the files older than 14 days

Remarquez que dans la capture d’écran ci-dessus, en fonction du message verbeux, le script n’a supprimé que cinq fichiers plus anciens de 14 jours. Pour confirmer que les fichiers plus récents que 14 jours existent toujours, exécutez à nouveau le code ci-dessous pour les répertorier.

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

Le résultat ci-dessous confirme que Remove-Item n’a pas supprimé les fichiers plus récents.

Newer files are left untouched

Utilisation de PowerShell pour faire correspondre et supprimer des modèles de fichiers

Supprimer tous les fichiers, quel que soit leur nom, type ou extension n’est pas toujours la meilleure approche. Parfois, vous devez explicitement exclure ou inclure certains fichiers dans le processus de suppression.

Cet exemple suivant ci-dessous montre comment supprimer les fichiers qui correspondent au nom de fichier *.LOG. Une façon de le faire est d’utiliser directement la cmdlet Remove-Item avec l’utilisation du paramètre -Include, comme indiqué ci-dessous.

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

Une autre façon est, peut-être, l’approche prudente consiste à utiliser d’abord Get-ChildItem pour collecter la liste des fichiers à supprimer. Ce n’est que lorsque vous êtes satisfait de la liste des fichiers à supprimer que vous pouvez enfin passer la collection à la cmdlet Remove-Item.

Par exemple, le code ci-dessous obtient les fichiers *.LOG dans c:\temp.

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

En conséquence du code ci-dessus, Get-ChildItem renvoie une liste de fichiers correspondant au nom de fichier *.LOG.

Only files matching the *.log filename is returned

Mais que se passe-t-il si vous voulez exclure un fichier contenant le chiffre 5 dans son nom ? Vous pouvez le faire en ajoutant le paramètre -Exclude comme dans le code suivant.

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

Comme vous avez exclu le fichier contenant le chiffre 5, le résultat est maintenant différent. Plus précisément, le fichier File_5.log ne figure plus dans la liste, comme indiqué ci-dessous.

The file File_5.log was excluded

Lorsque vous êtes satisfait de la collection de fichiers créée par votre code, vous pouvez alors envoyer la collection de fichiers à la commande Remove-Item pour enfin supprimer ces fichiers.

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

Après avoir exécuté votre code final, vous aurez atteint votre objectif de supprimer uniquement les fichiers que vous avez sélectionnés.

Deleting selected files

Suppression de fichiers à l’aide de WMI dans PowerShell

Maintenant que vous avez une bonne compréhension de l’utilisation courante de la commande Remove-Item pour supprimer des fichiers, passons à un cas d’utilisation plus avancé ; l’utilisation de WMI.

PowerShell prend en charge WMI. Et la prise en charge de WMI signifie que des requêtes et des méthodes WMI peuvent être appelées depuis PowerShell. Oui, WMI n’est pas seulement destiné aux scripts Visual Basic que les administrateurs utilisaient aux débuts de Windows.

Microsoft a publié des cmdlets CIM spécifiques à WMI dans PowerShell 3.0. Les cmdlets CIM qui seront utilisées pour supprimer des fichiers sont Get-CimInstance et Invoke-CimMethod.

Utilisation de PowerShell et de WMI pour supprimer un fichier

Cet exemple suppose que vous connaissez le chemin du fichier spécifique à supprimer. La cmdlet Get-CimInstance avec la classe Cim_DataFile est utilisée pour récupérer les informations sur le fichier à supprimer qui est C:\Temp\random.txt.

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

Dans le code ci-dessus, le paramètre -Filter accepte une requête au format WQL. L’utilisation de WQL nécessite l’échappement de certains caractères, y compris le backslash. Et, comme le caractère d’échappement WQL est également le backslash, cela entraîne la présence de caractères de double backslash – \\.

L’exécution du code ci-dessus produit le résultat affiché dans la démonstration ci-dessous. Les informations sur C:\Temp\random.txt sont enregistrées dans la variable $file2delete

Getting a file using WMI query and PowerShell

Maintenant que les informations pour le fichier C:\Temp\random.txt sont récupérées, l’objet résultant dans la variable $file2delete peut être transmis à la cmdlet Invoke-CimMethod. La cmdlet Invoke-CimMethod a un paramètre appelé -Name, qui représente le nom de la méthode de la classe Cim_DataFile.

$file2delete | Invoke-CimMethod -Name Delete

Comme vous pouvez le voir dans la capture d’écran ci-dessous, la valeur de ReturnValue montre 0, ce qui signifie que la commande a réussi.

File successfully deleted using WMI and PowerShell

Pour connaître les codes ReturnValue possibles, veuillez vous référer à ce lien – méthode Delete de la classe CIM_DataFile

De plus, la capture d’écran ci-dessous montre qu’après l’exécution de la méthode Invoke-CimMethod Delete(), CIM n’a supprimé que le fichier C:\Temp\random.txt. Il n’a pas supprimé les autres fichiers.

C:\Temp\random.txt file was deleted

Utilisation de PowerShell et WMI pour supprimer tous les fichiers dans un dossier

Dans cet exemple suivant, je vous montre comment supprimer tous les fichiers dans un dossier en utilisant PowerShell et WMI. Les mêmes cmdlets utilisés dans l’exemple précédent, à savoir Get-CimInstance et Invoke-CimMethod, seront utilisés. Mais, cette fois, la requête WQL récupérera tous les fichiers du dossier au lieu d’un seul fichier spécifique.

Dans le code suivant, le cmdlet Get-CimInstance récupère tous les fichiers situés dans C:\temp. Comme vous pouvez le voir ci-dessous, la requête filtre les propriétés Drive et Path de la classe Cim_DataFile.

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

En exécutant le code ci-dessus, les informations récupérées sur les fichiers dans C:\temp sont sauvegardées dans la variable $file2delete. La visualisation de la ou des valeur(s) de la variable $file2delete affiche la sortie ci-dessous.

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

Maintenant, les valeurs stockées dans la variable $file2delete peuvent être transmises au Invoke-CimMethod pour supprimer tous les fichiers dans c:\temp.

$file2delete | Invoke-CimMethod -Name Delete

N’oubliez pas, le code ReturnValue de 0 signifie réussi, et pour chaque fichier sur lequel la méthode de suppression a été appelée aura son propre code ReturnValue.

All files in c:\temp deleted using WMI

Utilisation de PowerShell et de WMI pour supprimer des fichiers par extension

Vous avez vu dans l’exemple précédent comment supprimer tous les fichiers dans un dossier indépendamment de l’extension. Cependant, vous pouvez également contrôler quels fichiers sont supprimés en fonction de l’extension.

Vous remarquerez dans le code ci-dessous, cette fois la requête a une condition ajoutée (Name LIKE '%.log). Cette condition ajoutée signifie que seuls les fichiers qui correspondent à l’extension .LOG sont renvoyés. Le pourcentage (%) est un opérateur WQL LIKE qui signifie « Une chaîne de zéro ou plusieurs caractères ». En termes de programmation, le % est l’équivalent d’un caractère générique, qui est l’astérisque (*).

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

$file2delete | Invoke-CimMethod -Name Delete

La démonstration ci-dessous montre qu’avant l’exécution du code ci-dessus, il y a neuf fichiers *.LOG et un seul fichier *.TXT. Une fois que le code a fini de s’exécuter, les fichiers *.LOG sont supprimés et le fichier *.TXT est le seul fichier restant dans le dossier.

Deleting files by extension using WMI

Comparaison de WMI et Remove-Item

Jusqu’à présent dans ce tutoriel, vous avez obtenu un aperçu général de comment utiliser PowerShell pour supprimer des fichiers. Vous avez appris sur Remove-Item et aussi WMI. Les deux effectuent des fonctions similaires mais de manière très différente.

Quelle méthode devez-vous utiliser pour supprimer des fichiers; Remove-Item ou WMI?

L’utilisation d’une cmdlet intégrée dans PowerShell comme Get-ChildItem et Remove-Item pour récupérer et supprimer des fichiers est beaucoup plus rapide que lorsque vous utilisez WMI.

L’exemple ci-dessous montre la comparaison entre l’utilisation de WMI et de la cmdlet intégrée PowerShell pour obtenir la liste des fichiers sous le répertoire C:\windows\web et ses sous-répertoires.

## Lister tous les fichiers dans C:\Windows\Web\ récursivement en utilisant Get-ChildItem
Measure-Command { Get-ChildItem C:\Windows\Web\ -Recurse}

## Lister tous les fichiers dans C:\Windows\Web\ récursivement en utilisant Get-CimInstance et la requête WMI
Measure-Command { Get-CimInstance -ClassName Cim_DataFile -Filter "Drive = 'c:' AND Path = '\windows\web\%'"}

Lorsque vous exécutez le code ci-dessus dans PowerShell, vous verrez une sortie similaire à celle ci-dessous.

Get-ChildItem vs. Get-CimInstance with WMI Query

Comme vous pouvez le voir à partir de la sortie affichée ci-dessus, la liste des fichiers dans C:\windows\web a presque pris dix fois plus de temps en utilisant Get-CimInstance que le temps qu’il a fallu pour que Get-ChildItem se termine!

Aussi, avez-vous remarqué comment la ligne Get-ChildItem est beaucoup plus courte que Get-CimInstance? Non seulement vous obtenez une exécution plus rapide en utilisant Get-ChildItem, mais vous bénéficiez également d’un code plus propre et plus court.

Étapes suivantes

Dans cet article, vous avez vu les deux différentes façons d’utiliser PowerShell pour supprimer des fichiers avec des cmdlets intégrées et WMI/CIM.

Sachez que vous devriez toujours utiliser les cmdlets Get-ChildItem et Remove-Item pour supprimer des fichiers. Ces cmdlets intégrées sont plus flexibles, plus faciles et plus rapides à utiliser que lorsque vous utilisez WMI.

Essayez de créer un script qui peut effectuer le nettoyage de l’espace disque pour vous. Bien sûr, certains scripts existent déjà à cette fin ; n’hésitez pas à les utiliser comme référence, mais si vous êtes prêt à pratiquer et à apprendre, vous devriez essayer de créer le vôtre.

Further Reading

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