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

Maintenir un espace disque libre est crucial lors de la gestion de serveurs et de 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 tout est en ordre, 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 envisagez 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 la Cmdlet Remove-Item. Cette Cmdlet est la norme de facto pour la suppression de fichiers avec PowerShell.

En utilisant Remove-Item combiné avec la Cmdlet Get-ChildItem pour lire les fichiers et dossiers, et le puissant pipeline PowerShell, tout devient vraiment simple.

Lié : Get-ChildItem : Listing Files, Registry, Certificates and More

Saviez-vous que la Cmdlet Remove-Item a un alias du nom de del? Lorsque vous travaillez dans PowerShell, l’utilisation de 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 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 dans PowerShell n’afficherait rien à l’écran à moins qu’une erreur ne soit rencontrée.

Utilisation de 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 seuls les fichiers doivent être inclus. Get-ChildItem ignore les dossiers.

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

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

Successfully deleted all files in a folder

Utilisation de PowerShell pour supprimer tous les fichiers récursivement

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

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

Exécuter le code ci-dessus force PowerShell à examiner tous les sous-dossiers et à récupérer la liste complète des 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

Contourner le problème du chemin long

L’erreur indiquée ci-dessus indique que PowerShell “n’a pas pu trouver une partie du chemin”. Cette erreur indique que le chemin auquel la commande tente d’accéder n’existe pas – ce qui est trompeur.

Dans ce cas, l’erreur s’est produite car le chemin que la commande 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 se trouve 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\<computername>\<share>\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 lu avec succès 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 nativement les noms de chemin longs.

Si les dossiers doivent également être supprimés, il suffit de supprimer le paramètre -File de la commande 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 ont plus d’un certain nombre de jours. Cet exemple est utile pour supprimer les anciens fichiers journaux, tels que 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 ont plus de 14 jours. En utilisant le script ci-dessous, le Nom, CreationTime et AgeInDays de chaque fichier dans c:\temp sont affichés.

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 jour.

List of files in c:\temp

Maintenant que vous connaissez les fichiers à supprimer, vous pouvez créer un script pour supprimer uniquement les fichiers qui ont plus d’un certain nombre de jours – dans ce cas, plus de 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 à rechercher par Get-ChildItem. Le chemin est enregistré dans la variable $path. Ensuite, la deuxième ligne est l’endroit où le seuil est spécifié. La valeur de la variable $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.
  • Redirigez la liste filtrée de fichiers vers 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 montré ci-dessous.

The script deleted the files older than 14 days

Remarquez que, d’après la capture d’écran ci-dessus, en fonction du message verbeux, le script a seulement supprimé cinq fichiers âgés de plus de 14 jours. Pour confirmer que les fichiers de moins de 14 jours existent toujours, exécutez le code ci-dessous pour les lister à nouveau.

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

Utiliser PowerShell pour Correspondre et Supprimer des Modèles de Fichiers

Supprimer tous les fichiers, indépendamment du nom, du type ou de l’extension n’est pas toujours la meilleure approche. Parfois, vous devez exclure ou inclure explicitement certains fichiers dans le processus de suppression.

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

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

Une autre manière, peut-être plus prudente, est d’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 finalement rediriger la collection vers 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 retourne une liste de fichiers correspondant au nom de fichier *.LOG.

Only files matching the *.log filename is returned

Mais, que faire si vous voulez exclure un fichier qui contient 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*

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

The file File_5.log was excluded

Lorsque vous êtes déjà satisfait de la collection de fichiers que votre code crée, vous pouvez alors transmettre la collection de fichiers à la cmdlet 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 en utilisant WMI dans PowerShell

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

PowerShell est livré avec le support de WMI. Et le support de WMI signifie que des requêtes et des méthodes WMI peuvent être appelées depuis PowerShell. Oui, WMI n’est pas seulement pour les scripts Visual Basic que les administrateurs utilisaient dans les premiers jours 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 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 d’échapper certains caractères, y compris le backslash. Et, comme le caractère d’échappement de WQL est également le backslash, cela entraîne la présence de caractères double-backslash – \\.

L’exécution du code ci-dessus produit le résultat illustré 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 sur le fichier C:\Temp\random.txt sont récupérées, l’objet résultant dans la variable $file2delete peut être envoyé à la cmdlet Invoke-CimMethod. La cmdlet Invoke-CimMethod dispose d’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 est de 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 consulter ce lien – méthode de suppression 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 vais vous montrer 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 dans le dossier au lieu d’un 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 enregistrées dans la variable $file2delete. En visualisant la ou les valeurs de la variable $file2delete, le résultat est le suivant.

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

Maintenant, les valeurs stockées dans la variable $file2delete peuvent être transmises à 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éussite et pour chaque fichier sur lequel la méthode de suppression a été appelée, il y aura son propre code ReturnValue.

All files in c:\temp deleted using WMI

Utilisation de PowerShell et WMI pour supprimer des fichiers par extension

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

Vous remarquerez dans le code ci-dessous que cette fois-ci, la requête a une condition supplémentaire (Name LIKE '%.log). Cette condition supplémentaire signifie que seuls les fichiers correspondant à l’extension .LOG sont renvoyés. Le signe pourcentage (%) est un opérateur WQL LIKE qui signifie « Une chaîne de caractères de zéro ou plusieurs caractères ». En termes de programmation, le signe pourcentage % équivaut à un caractère générique, qui est représenté par 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 le code exécuté, les fichiers *.LOG sont supprimés et il ne reste que le fichier *.TXT 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 l’utilisation de PowerShell pour supprimer des fichiers. Vous avez appris à utiliser Remove-Item et également WMI. Les deux effectuent des fonctions similaires, mais de manière bien différente.

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

Utiliser 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 lors de l’utilisation de WMI.

L’exemple ci-dessous montre la comparaison lors de 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 de manière récursive dans C:\Windows\Web\ en utilisant Get-ChildItem
Measure-Command { Get-ChildItem C:\Windows\Web\ -Recurse}

## Lister tous les fichiers de manière récursive dans C:\Windows\Web\ 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, lister les fichiers dans C:\windows\web a presque pris dix fois plus de temps en utilisant Get-CimInstance que le temps nécessaire à Get-ChildItem pour s’exécuter!

Avez-vous également 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 dont vous pouvez 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 lors de l’utilisation de WMI.

Essayez de créer un script qui peut effectuer une gestion de l’espace disque pour vous. Bien sûr, il existe déjà des scripts à 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.

Lecture complémentaire

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