14/11/2024

PowerShell

Obtenir la taille des dossiers avec PowerShell

I. Présentation

Pour obtenir la taille d'un dossier sous Windows, c'est très simple : on fait un clic droit sur le dossier puis un clic gauche sur "Propriétés" et l'information s'affiche à l'écran. Aujourd'hui, je vous propose d'obtenir cette information à l'aide de PowerShell, ce qui sera forcément intéressant pour nos scripts !

Nous allons principalement utiliser deux cmdlets : Get-ChildItem et Measure-Object.

D'autres articles au sujet de la manipulation des dossiers avec PowerShell :

Comment lister les dossiers vides en PowerShell ?

Comment déplacer un dossier en PowerShell ?

Comment vérifier si un dossier est vide en PowerShell ?

Tutoriel disponible au format vidéo :

II. Taille d'un dossier en PowerShell

Le dossier qui va nous servir de cobaye se nomme "DATA". Il contient des données à la racine, ainsi qu'un sous-dossier avec d'autres fichiers. Sa taille globale est de 378 Mo.

Pour lister tout simplement le contenu d'un dossier, je vous rappelle qu'en PowerShell on utilise le cmdlet "Get-ChildItem" ou son alias "gci" :

Get-ChildItem "C:\TEMP\DATA"

On va coupler l'utilisation de cette commande à une autre commande : Measure-Object. Elle sert à effectuer des calculs sur les propriétés d'un objet, d'un fichier, etc... par exemple obtenir la taille ou alors le nombre d'éléments. Intéressant !

Pour obtenir la taille totale, des éléments de notre dossier "DATA", on va faire la somme grâce au paramètre -Sum de la commande. Ainsi, pour obtenir la taille du dossier on fait :

Get-ChildItem "C:\TEMP\DATA" | Measure-Object -Property Length -Sum

La commande retourne un résultat en octets. Ici, nous obtenons : 389686349 octets.

Ce n'est pas très grave, on va faire un petit calcul mathématique en PowerShell pour obtenir cette valeur en Go ou Mo, au choix.

Pour obtenir la taille en Go :

(Get-ChildItem "C:\TEMP\DATA" | Measure-Object -Property Length -Sum).Sum / 1Gb

J'obtiens alors : 0,362923693843186 Go

Pour obtenir la taille en Mo :

(Get-ChildItem "C:\TEMP\DATA" | Measure-Object -Property Length -Sum).Sum / 1Mb

J'obtiens alors : 371,633862495422 Mo

Cette valeur est conforme à la réalité et correspond à la taille de mon dossier à un détail près. En effet, la commande Get-ChildItem telle qu'utilisée ici ne prend pas en compte les sous-dossiers. Si l'on veut prendre en compte les sous-dossiers avec récursivité, il faut ajouter le paramètre -Recurse.

(Get-ChildItem "C:\TEMP\DATA" -Recurse | Measure-Object -Property Length -Sum).Sum / 1Mb

J'obtiens bien la même valeur qu'à partir de l'explorateur de fichiers Windows : 378,316079139709 Mo

Enfin, pour que ce soit encore plus sympa à lire comme valeur, nous allons l'arrondir à deux décimales. Pour cela, on va utiliser la classe .NET [math] qui contient une vingtaine de méthodes. La méthode qui nous intéresse se nomme "Round" : on lui spécifie une valeur en entrée et le nombre de décimales que l'on souhaite.

[math]::Round((Get-ChildItem "C:\TEMP\DATA" -Recurse | Measure-Object -Property Length -Sum).Sum / 1Mb,2)

Le résultat obtenu est le suivant : 378,32 Mo

On peut le faire en deux temps également :

$FolderSize = (Get-ChildItem "C:\TEMP\DATA" -Recurse | Measure-Object -Property Length -Sum).Sum / 1Mb
[math]::Round($FolderSize,2)

III. Taille des fichiers d'une extension spécifique avec PowerShell

Maintenant, imaginons que l'on souhaite obtenir uniquement la taille des fichiers images avec l'extension JPG situé au sein du dossier "C:\TEMP\DATA" et de ses sous-dossiers.

Ce n'est pas très compliqué, on va reprendre la commande précédente et intégrer le paramètre "-Filter" pour filtrer le résultat de la commande "Get-ChildItem". Si on veut lister ces fichiers, cela donne :

Get-ChildItem "C:\TEMP\DATA" -Filter "*.jpg" -Recurse

Ensuite, pour calculer la taille, on reprend le même principe :

$FolderSize = (Get-ChildItem "C:\TEMP\DATA" -Filter "*.jpg" -Recurse | Measure-Object -Property Length -Sum).Sum / 1Mb
[math]::Round($FolderSize,2)

Vous allez me dire, comment faire pour se baser sur plusieurs extensions de fichiers ? Pour répondre à cette demande, nous allons plutôt utiliser le paramètre -Include que -Filter. Imaginons que l'on cherche à filtrer sur les extensions JPG et PNG, cela donne :

Get-ChildItem "C:\TEMP\DATA" -Include ("*.jpg","*.png") -Recurse

Dans le même esprit, on pourrait décider d'exclure tous les fichiers JPG du calcul. Il suffit de remplacer le paramètre -Filter/-Include par -Exclude.

Get-ChildItem "C:\TEMP\DATA" -Exclude "*.jpg" -Recurse

La commande pour faire le calcul reste la même, il suffit d'adapter la commande Get-ChildItem ?

IV. Rapport - Taille d'un ensemble de dossiers en PowerShell

Nous pouvons exploiter les commandes vues précédemment pour aller plus loin : obtenir la taille des dossiers situé à la racine d'un autre dossier, le dossier racine, disons. Par exemple, prendre le dossier "C:\TEMP" et calculer la taille de tous les sous-dossiers de cette racine. À partir de là, générer un tableau avec le chemin du dossier et la taille, en Mo (ou Go si vous voulez).

Avec le code ci-dessous, vous pouvez effectuer cette opération facilement. Il suffit de modifier le chemin de la racine : variable $RootFolder (ligne 2).

# Dossier racine
$RootFolder = "C:\TEMP\"
$FoldersSizeList = @()

Get-ChildItem -Force $RootFolder -ErrorAction SilentlyContinue -Directory | foreach{

   # Pour chaque dossier de notre racine, on calcul la taille
   $Size = 0
   $Size = (Get-ChildItem $_.Fullname -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum

   # Récupérer le nom complet du dossier (chemin)
   $FolderName = $_.fullname

   # Calculer la taille en Mb
   $FolderSize= [math]::Round($Size / 1Mb,2)

   # Ajouter un membre à notre objet global
   $FoldersSizeListObject = New-Object PSObject
   Add-Member -InputObject $FoldersSizeListObject -MemberType NoteProperty -Name "Dossier" -value $FolderName
   Add-Member -InputObject $FoldersSizeListObject -MemberType NoteProperty -Name "Taille-Mb" -value $FolderSize
   $FoldersSizeList += $FoldersSizeListObject
}

# Afficher le résultat dans un tableau
$FoldersSizeList | Out-GridView -Title "Taille des dossiers sous $RootFolder"

Voici le résultat obtenu :

taille des dossiers avec PowerShell

Sur l'interface ci-dessus, vous pouvez cliquer sur les en-têtes de colonne pour trier les résultats, par exemple du plus gros dossier au plus petit, ou l'inverse.

Voir le script sur GitHub

Vous avez désormais quelques billes pour calculer la taille des dossiers en PowerShell.

author avatar
Florian BURNEL Co-founder of IT-Connect
Ingénieur système et réseau, cofondateur d'IT-Connect et Microsoft MVP "Cloud and Datacenter Management". Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.
Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Envoyer par mail

10 commentaires sur “Obtenir la taille des dossiers avec PowerShell

  • Merci beaucoup pour cet article qui va bien m’aider 🙂

    Répondre
    • Bonjour serait -il possible d’avoir un peu d’aide svp en PowerShell je cherche à obtenir le deviceID de VM de puis un hôte hyper-v

      Répondre
  • On est bien d’accord que tout ça est équivalent à un simple `du -hs` avec bash ? ?

    Répondre
  • Bonjour, merci pour votre le partage de vos connaissances. En exécutant le script, j’ai reçu ces messages. Pourriez-vous les expliquer ?

    Measure-Object : The property « Length » cannot be found in the input for any objects.
    At line:9 char:80
    + … orAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [Measure-Object], PSArgumentException
    + FullyQualifiedErrorId : GenericMeasurePropertyNotFound,Microsoft.PowerShell.Commands.MeasureObjectCommand
    Measure-Object : The property « Length » cannot be found in the input for any objects.
    At line:9 char:80
    + … orAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [Measure-Object], PSArgumentException
    + FullyQualifiedErrorId : GenericMeasurePropertyNotFound,Microsoft.PowerShell.Commands.MeasureObjectCommand
    Measure-Object : The property « Length » cannot be found in the input for any objects.
    At line:9 char:80
    + … orAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [Measure-Object], PSArgumentException
    + FullyQualifiedErrorId : GenericMeasurePropertyNotFound,Microsoft.PowerShell.Commands.MeasureObjectCommand

    Répondre
    • Bonjour, j’ai eu ça aussi en le lançant sur mon dossier utilisateur. Je pense que ça vient de droit restreins de certains fichiers auquel on n’a pas accès en tant qu’utilisateur classique, genre les fichiers cachés et/ou contenues dans le dossier AppData par exemple dans mon cas. En lançant ces commandes sur mon dossier Downloads ça a très bien fonctionné.

      Répondre
  • Bonjour Florian et merci pour ce script. Je l’ai un peu modifié pour ajouter la date du moment où je l’exécute : l’idée est de pouvoir constater ou pas l’évolution de la taille de mes dossiers. Et en mettant en commentaire la 3ième ligne à partir de sa 2ième exécution je concatène à la suite dans le tableau $FoldersSizeList la suite de mes tests de taille de dossier.
    Bon c’est un début. En fait je voudrais savoir si en partant de ce script y’aurait pas moyen de créer un rapport journalier me listant les dossiers ayant grossi/maigri par rapport à la veille de + ou – 100 Mo par exemple.
    Si vous avez une idée je suis preneur !!
    En attendant je vais déjà essayer de le lancer en auto toutes les heures et historiser les résultats puis j’irais dans Excel !
    Bonne journée,
    Fred

    Répondre
    • Bonjour,
      Pourrais-tu partager ton code?
      Merci

      Répondre
  • La commande est fausse. Ne prends pas en compte les fichiers cachés. Cest improtant quand même. Si je lance la commande sur un dossier users je n’aurais pas le comptage de appdata par exemple.

    Je donne la bonne version pour le total d’un dossier:
    (get-childitem -Path $path -Recurse -Force | Measure-Object Lenght -sum).sum / 1Gb

    Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.