PowerShell : comment créer une propriété calculée avec Select-Object ?
Sommaire
I. Présentation
PowerShell est un langage orienté objet où chaque commande contient ses propres propriétés. Chacune de ces propriétés à son propre format par défaut : une simple chaîne de caractère, un chiffre, un booléen, une date ou encore une taille de fichiers. Ce format par défaut ne convient pas forcément aux besoins de tous les utilisateurs, et dans certains cas, la propriété que l'on souhaite n'existe pas au sein de la commande de base. C'est là que la notion de propriété calculée entre en jeu : PowerShell offre la possibilité de créer des propriétés personnalisées, notamment par l'intermédiaire de Select-Object, pour agir directement sur la sortie de la commande et créer un objet personnalisé.
II. Syntaxe d'une propriété calculée en PowerShell
Pour commencer, nous allons manipuler la commande Get-Process (mais on aurait pu en prendre une autre). Cette commande permet de lister les processus actifs sur une machine : elle contient de nombreuses propriétés telles que le nom du processus, son identifiant unique, la consommation des ressources, le propriétaire du processus, etc.
Tout simplement, si l'on couple Get-Process à Select-Object, on peut sélectionner seulement la propriété "ProcessName" pour obtenir la liste des processus avec seulement le nom comme information. Ce qui donne :
Get-Process | Select-Object ProcessName
Maintenant, si l'on veut commencer à s'intéresser à la notion de propriété calculée, sachez que l'on pourrait créer une propriété calculée qui retourne le même résultat :
Get-Process | Select-Object -Property @{Name = 'ProcessName'; Expression = {$_.ProcessName}}
Il n'y a pas trop d'intérêt, je suis d'accord, puisque la commande retourne exactement le même résultat. L'idée c'est plus de vous montrer la syntaxe pour commencer. Grâce à -Property on va pouvoir spécifier des propriétés existantes d'une part, et d'autre part déclarer nos propriétés calculées.
Pour déclarer une propriété calculée, la syntaxe est la suivante :
@{Name = '<nom de la propriété>'; Expression = {<code pour calculer la valeur>}}
Pour créer la propriété calculée, il faut au minimum deux paramètres : le nom (Name) et l'expression qui va permettre de calculer la valeur (Expression). Il y a d'autres paramètres, un peu secondaires pour gérer la mise en forme : Alignment, Width, etc.
Tout bêtement, on pourrait renommer le nom de la propriété d'origine en français :
Get-Process | Select-Object -Property @{Name = 'NomProcessus'; Expression = {$_.ProcessName}}
Ce qui donne :
Vous connaissez maintenant la syntaxe, nous pouvons passer à la suite et voir quelques exemples concrets.
III. Propriété calculée en PowerShell : exemples
A. Calculer l'espace disque en Gigaoctets
Dans un précédent tutoriel, je vous ai expliqué "comment calculer l'espace disque restant en PowerShell ?" : j'avais utilisé la notion de propriété calculée pour obtenir l'espace disque restant en Gigaoctets, ainsi que l'espace disque utilisé avec un simple calcul. Reprenons cet exemple.
La commande ci-dessous retourne l'espace disque restant avec une valeur en octets : pas des plus faciles à lire... Il faut l'avouer.
Get-CimInstance -Class Win32_LogicalDisk
Par exemple :
DeviceID DriveType ProviderName VolumeName Size FreeSpace
-------- --------- ------------ ---------- ---- ---------
C: 3 254824558592 47007928320
On va créer une propriété calculée qui reprendre le nom d'origine (FreeSpace), sauf que par l'intermédiaire de l'expression nous allons convertir la valeur en Gigaoctets et l'arrondir à deux décimales. On retiendra seulement deux autres propriétés existantes : DeviceID et Name.
Ce qui donne :
Get-CimInstance -Class Win32_LogicalDisk |
Select-Object -Property DeviceID, Name, @{
label='FreeSpace'
expression={($_.FreeSpace/1GB).ToString('F2')}
}
Le résultat est quand même beaucoup plus sympa avec une valeur en Gigaoctets :
DeviceID Name FreeSpace -------- ---- --------- C: C: 43,77
Passons à l'exemple suivant.
Note : l'expression peut faire appel à d'autres commandes PowerShell, ce qui offre des possibilités supplémentaires.
B. Classer les fichiers par catégorie en fonction de l'extension
Dans ce nouvel exemple, nous allons utiliser Get-ChildItem, la commande qui sert à lister le contenu d'un dossier. L'idée est la suivante : à partir de la liste des fichiers et des extensions, créer une nouvelle propriété nommée "Catégorie" qui va permettre d'affecter une catégorie à chaque fichier.
Par exemple, la catégorie "Image" pour un fichier avec l'extension ".PNG" ou ".JPG" et la catégorie "Script PowerShell" pour un fichier ".PS1". On va s'appuyer sur un switch pour affecter une valeur à notre propriété en fonction de l'extension (on s'appuie sur la propriété existante Extension de Get-ChidlItem).
Ce qui donne la commande suivante en prenant le dossier "C:\TEMP\Fichiers" comme référence :
Get-ChildItem -Path "C:\TEMP\Fichiers" -File | Select-Object Name, Length, @{ name='Catégorie' expression={ switch ($_.extension) { '.ps1' {'Script PowerShell'} '.png' {'Image'} '.jpg' {'Image'} '.docx' {'Document Word'} '.doc' {'Document Word'} '.xlsx' {'Tableur Excel'} default {'Autre'} } } }
Voici le résultat :
Si l'on stocke la commande ci-dessus dans une variable, par exemple $Category, on peut ensuite faire quelques calculs rapides. Par exemple, identifier le nombre de fichiers qui appartiennent à la catégorie "Image" : ce qui va permettre de compter le nombre de fichiers JPG et PNG.
($Category | Where{ $_.Catégorie -eq "Image" }).Count
La valeur retournée sera 3, ce qui est correct.
Au travers ces deux exemples, j'ai pu illustrer facilement l'intérêt des propriétés calculées en PowerShell. Nous avons vu comment utiliser les propriétés calculées avec Select-Object, mais on peut également les utiliser avec d'autres cmdlets comme Format-Table et Format-List. L'avantage de Select-Object, c'est que l'on peut générer une sortie dans la console, mais aussi récupérer le contenu dans une variable pour exploiter le contenu dans un script.
La documentation Microsoft liste les différents cmdlets compatibles avec les propriétés calculées : About_Calculated_Properties