PowerShell – Variables, types et opérateurs logiques

Comme dans tout langage de programmation, PowerShell permet de stocker des données (ou des objets, qui possèdent des types particuliers) dans des variables, et d’effectuer des opérations logiques avec ces dernières.

Variables

En PowerShell une variable est instanciée de plusieurs manières différentes, comme ce qui suit.

New-Variable -Name "NOM" -Value "VALEUR"
 # si la variable existe déjà une erreur est levée
Set-Variable -Name "NOM" -Value "VALEUR"
$NOM = "VALEUR"

Dans le cas 3, le symbole « égal » peut être substitué pour faire une opération d’attribution:

  • +=, ajoute la valeur de droite à la variable.
  • -=, enlève la valeur de droite à la variable.
  • *=, multiplie la variable par la valeur à droite et sauvegarde le résultat.
  • /=, divise la variable par la valeur à droite et sauvegarde le résultat.
  • %=, sauvegarde le résultat de la division euclidienne de la variable par la valeur de droite.

Le nom d’une variable n’a pas de restrictions de nom, simplement s’il est choisi un nom déjà utilisé, cela changera sa valeur. Globalement en PowerShell les mots de sont pas sensibles à la casse (sauf les chaînes de caractères en cas de comparaison évidemment), donc $AbCd est égal à $abcd. Dans le cas où la variable est défini avec les méthodes une et deux, le nom n’est pas nécessairement imprimable. Si une variable n’a jamais été définie mais utilisée, aucune erreur ne sera levée, sa valeur sera $null. Pour obtenir la valeur contenue dans une variable, il faut simplement entrer son nom dans PowerShell, en précisant bien sûr le $. Il peut aussi être utilisé les cmdlets Write-Host ainsi que Write-Output en précisant le nom de la variable. Les variables créées à l’extérieur d’une fonction ou d’une classe sont par défaut global. Pour supprimer une Variable il faut utiliser la cmdlet Remove-Variable avec comme argument -Name NOM_DE_LA_VARIABLE. Par défaut les variables acceptent tous les types, si un type particulier est exigé, il faut le spécifier avant le nom de la variable entre crochet.

Types

Les différents types de bases sont les mêmes que ceux disponible en .NET, c’est à dire pour les plus communs « string » (des chaînes de caractères), « int » (« int16″, »int32″, »int64″, des nombres entier et négatifs/positifs), “double” (des nombres négatifs/positifs, décimaux), »boolean » (valeur soit vrai, soit fausse), « Array » (tableau, similaire au liste en python), et « hashtable » (similaire au dictionnaire dans le langage au serpent), et enfin les « PSCustomObject »/ »PSObject » (objet aux propriétés que nous définissons).

Les « String » issus de l’espace de nom System, sont des chaînes de caractères, de longueur multiple. Elle est définie entre apostrophes ou guillemets, il existe une différence entre les deux, qui est exactement la même qu’en C#: une variable peut être appelée dedans pour faire une concaténation. Une chaîne de caractères peut s’étendre sur plusieurs lignes pour cela, en plus des apostrophes ou guillemets, il faut ajouter un arobase. Il est à noter que la différence entre les deux manières de définition est toujours valable ici.

Il existe différentes méthodes autour de ce type, en voici quelques-unes:

  • $string.ToUpper() permet de mettre tous les caractères en majuscules.
  • $string.ToLower() permet de mettre tous les caractères en minuscules.
  • $string.Split('CHAR') permet de séparer la chaînes de caractères en tableau séparé tous les « CHAR.
  • $string.SubString(START, END), permet de récupérer un morceau de la chaîne, à partir deux index.
  • $string.IndexOf('STRING') permet d’obtenir un entier correspondant à l’index de « STRING » dans la chaîne.
  • $string.Replace('STRING1', 'STRING2'), permet de replacer tous les ‘STRING1’ présent dans la chaîne par ‘STRING2’.
  • $string.Length permet d’obtenir la longueur de la chaîne de caractères.
  • $string.Contains('STRING') permet d’obtenir un ‘boolean’ représentant la présence de ‘STRING’ dans la chaîne.

La plupart de ces méthodes sont encore une fois issue de C#. Pour avoir la liste complète de toutes les méthodes, il faudra effectuer Get-Member -inputObject $string (cette opération est valide pour tous les types).

Les « Int » sont issus de l’espace de nom System, les « int » sont des nombres plus ou moins grands. Ils sont définis par le simple fait de les écrire, par défaut, ce sera un « Int32 ». Il est possible de faire différentes opérations entre des nombres en utilisant des opérateurs, + sert à additionner, - sert à soustraire, / à diviser, * à multiplier, % est le modulo ou le résultat d’une division euclidienne. Pour d’autres calculs plus complexes tels l’exponentiation, les racines et autres calculs trigonométriques, il faudra interagir avec System.Math. Il existe très peu de méthodes sur les entiers, mais en voici deux:

  • $int.ToString() permet de convertir l’entier en chaîne de caractères.
  • $int.Equals(Int) permet d’obtenir un « boolean » représentant la comparaison égalitaire entre $int et Int.

Le reste étant surtout des méthodes liées à la conversion des objets.

Les « doubles » sont issus de l’espace de nom System, toutes leurs caractéristiques sont identiques aux « int ».

Les « boolean » sont issus de l’espace de nom « System ». La particularité de PowerShell sur ces derniers c’est qu’ils ne représentent pas une valeur particulière mais une variable: il existe $true et $false. Les méthodes disponibles pour les « boolean » sont les mêmes que celles pour les entier pour les « double ».

Les « Array » sont issus de l’espace de nom System (oui encore). Les tableaux sont des collections de valeurs, de longueur initiale définie. On définit un tableau avec un arobase suivi de parenthèses dans lesquelles on place les valeurs souhaitées (elles peuvent être des variables) séparées par des virgules. Le tableau accepte par défaut tous les types possibles (System.Object[], les crochets signifient qu’il s’agit d’un tableau), si un type précis est exigé il faut ajouter entre crochet, avant le nom de la variable lors de sa définition, le type souhaité sans oublier les crochets. Pour ajouter une entrée au tableau, comme la taille du tableau est définie, il est impossible d’utiliser la méthode .Add(). Il faut donc utiliser l’opérateur += , ce qui aura pour effet de créer un tableau qui sera l’addition du précédent et d’un de longueur 1 contenant la valeur à ajouter. Pour trier les éléments d’un tableau il faut utiliser la cmdlet Sort-Object qui les triera par défaut dans l’ordre suivant: booléen, nombre par ordre croissant, chaîne de caractère par ordre alphabétique. Pour accéder aux objets d’un tableau il faut utiliser l’indexation qui est effectuée comme en python: en ouvrant des crochets après l’appel de la variable ou du tableau, puis de son index. On peut aussi y accéder avec la cmdlet ForEach-Object, les valeurs passées dans la « pipeline » seront individuellement stockées chacune leur tour dans une variable qui est nommée $_.

Pour pallier à certains problèmes liés au tableau, il existe plusieurs alternatifs dont les « ArrayList » ainsi que les « List ». Ces dernières sont issues de l’espace de nom System.Collections. Microsoft l’a défini comme étant un tableau créée de manière dynamique, ce qui permet de pouvoir ajouter des éléments après la définition d’une liste. Toutes les opérations vues sur les tableaux restent valides mais de nouvelles méthodes sont désormais disponibles. La création d’une liste est effectuée avec la cmdlet New-Object qui permet de créer un objet .NET dans PowerShell la syntaxe sera la suivante: $list = New-Object System.Collections.Generic.List[] entre crochet sera le type de chaque élément de la liste (si il est souhaité n’importe quel type il faudra spécifier System.Object). Les « ArrayList » sont issu du même espace de nom et possèdent des caractéristiques similaires. On les définit avec New-Object et leur chemin System.Collections.ArrayList. Quand on ajoute une valeur à un « ArrayList », son index est retourné, pour éviter ce comportement, il faut rediriger le résultat vers $null avec $null = $ArrayList.Add(1) ou $ArrayList.Add(1) | Out-Null, la première méthode est sensiblement plus rapide (cette astuce est aussi valide pour ne pas afficher le résultat de n’importe quelle Cmdlet).

Les « hashtable » sont issus de l’espace de nom System.Collections. Les « hashtable » sont une liste d’objets, qui sont définis chacun par une clef et une valeur associée. On définit une « hashtable » par un arobase suivi d’entre accolades les objets; une clef est séparée de sa valeur par un égal, chaque objet doit être séparé d’un autre par un point-virgule. Une clef et sa valeur peuvent tous deux adopter n’importe quelle type valeur. Les valeurs seront affichées dans un ordre plus ou moins aléatoires, pour les garder dans celui de définition, il faut ajouter l’accélérateur de type [ordered] (le chemin complet serait System.Collections.Specialized.OrderedDictionary) juste avant l’arobase. Il existe plusieurs méthodes autour des « hashtable » en voici quelques-unes:

  • $hash.Add('Key1', 'Value1'), permet d’ajouter une nouvelle entrée à la hashtable $hash la clef ‘Key1’ et sa valeur ‘Value1’ (il existe d’autres méthode qui sont identique à celle des tableaux).
  • $hash.Remove('Key1'), permet de supprimer l’entrée ‘Key1’ de la hashtable $hash.
  • $hash.keys, permet de retourner un tableau contenant les clefs de la hashtable $hash.
  • $hash.values, permet de retourner un tableau contenant les valeurs de la « hashtable » $hash.

Les « hashtable » peuvent aussi être utilisés comme argument de cmdlet. C’est une fonctionnalité originale mais très pratique pour simplifier le code et/ou le rendre plus lisible/beau; pour cela il faut la sauvegarder dans une variable et appeler la fonction comme ceci Invoke-MyCmdlet @hash. Enfin les « hashtable » peuvent aussi être utilisés pour caractériser un objet .NET comme par exemple les « PSCustomObject ». Il existe une alternative au « hashtable », mais sont dans l’essence la même chose. Les « dictionnary » sont issus de l’espace de nom System.Collection.Generic, on l’a défini comme ceci $dict = New-Object 'System.Collections.Generic.Dictionary``2[]', entre crochet il est nécessaire de passer 2 types correspondants aux clés (en 1) et aux valeurs (en 2). Les dictionnaires sont en de très nombreux points similaires aux « hashtable », on peut, elles aussi, les passer en argument à une cmdlet, de la même manière.

Les « PSCustomObject » sont issus de l’espace de nom System.Management.Automation. Les « PSCustomObject » sont des objets spécifiques à PowerShell. Ils permettent de créer une forme de « hashtable » dans laquelle, les noms de propriétés sont choisis (au lieu de clé et valeur par exemple). En réalité ils servent de base aux « PSObject ». On définit un « PSCustomObject » de deux manières différentes. En utilisant New-Object suivi des arguments -TypeName psobject" et "-Property $hash (ou bien en utilisant directement le type littéral System.Management.Automation.PSObject). En utilisant un accélérateur de type [PSCustomObject] suivi d’une « hashtable »; dans les deux cas, les clés des « hashtable » serviront de nom de propriété, et leur valeur, la valeur associée. Pour ajouter un « membre » à un « PSObject » il faut utiliser la cmdlet Add-Member comme ceci: Add-Member -InputObject $psobject 'property1' 'value1'. Pour supprimer un « membre » d’un « PSObject » il faut accéder à ses propriétés intrinsèques et le supprimer: $psobject.PSObject.Properties.Remove('property1').

Les objets de ce type sont hautement personnalisables. Il est possible notamment de changer le PSTypeName d’un « PSCustomObject ». Ils permettent de représenter un type qu’il soit réel ou non, cependant ils n’apparaissent pas en utilisant la méthode .GetType() mais on y accède avec $psobject.PSTypeNames ou Get-Member -InputObject $psobject. Il existe trois manières de faire:

# méthode 1
$psobject.PSObject.TypeNames.Insert(0, 'MyType')
# méthode 2
$psobject.PSTypeNames.Clear()
$psobject.PSTypeNames.Add('MyType')
# méthode 3
$psobject = New-Object System.Management.Automation.PSObject -Property @{PSTypeName = 'MyType'; name = "toto"}

Les conversions entre type peuvent se faire de différentes manières:

  • en précisant entre crochet le type suivit d’une variable.
  • en utilisant l’opérateur -as suivi du type entre crochet.

Attention cependant, parfois il n’est pas possible de convertir deux objets !

Ici ont été présentés les types principaux en PowerShell, il ne faut cependant pas oublier que PowerShell prend en charge TOUS les types .NET ainsi que leurs différentes méthodes. Pour beaucoup, il vous sera plus aisé de trouver les informations dans la documentation Microsoft sur C#.

Opérateurs

Commençons par les opérateurs arithmétiques. Il faut savoir que c’est le TYPE de l’objet à gauche de l’opérateur qui définira le type du résultat, ce qui veut dire que l’on peut additionner un entier avec une chaine de caractère. Il existe + qui exprime une addition, - la soustraction, % modulo qui est le reste d’une division euclidienne, / qui permet de diviser, et * qui multiplie. Pour d’autres opérations mathématiques, il est obligatoire de passer par l’espace de nom System.Math. Les opérateurs logiques permettent d’ajouter des conditions, ou de la changer. Voici une liste des opérateurs disponibles ainsi que leur utilisation:

  • -and, renvoie $true si l’expression de gauche et l’expression de droite sont vraies.
  • -or, renvoie $true si l’expression de gauche ou l’expression de droite est vraie.
  • -not, renvoie l’inverse du booléen renvoyé par l’expression de droite, son alias est !.
  • -xor, se comporte comme -or, seulement si les deux expressions sont vraies, alors il sera retourné $false, si les deux expressions sont faussent, il sera retourné $false.

Les opérateurs de comparaison renvoie un booléen si une condition est remplie:

  • -eq, renvoie $true si l’expression de gauche est égale à l’expression de droite.
  • -ne, renvoie $true si l’expression de gauche n’est pas égale à l’expression de droite.
  • -lt, renvoie $true si l’expression de gauche est inférieure à l’expression de droite.
  • -le, renvoie $true si l’expression de gauche est inférieure ou égale à l’expression de droite.
  • -gt, renvoie $true si l’expression de gauche est plus grande que l’expression de droite.
  • -ge, renvoie $true si l’expression de gauche est plus grande ou égale à l’expression de droite.
  • -match, renvoie $true si la chaîne de caractère de gauche remplit les conditions regex de droite.
  • -notmatch, renvoie $true si la chaîne de caractère de gauche ne remplit pas les conditions regex de droite.
  • -like, renvoie $true si la chaîne de caractère de gauche remplit une « wildcard » à droite de l’opérateur.
  • -notlike, renvoie $true si la chaîne de caractère de gauche ne remplit pas une « wildcard » à droite de l’opérateur.
  • -contains, renvoie $true si la chaîne de caractère de gauche contient la chaîne de caractère de droite.
  • -notcontains, renvoie $true si la chaîne de caractère de gauche ne contient pas la chaîne de caractère de droite.

Les opérateurs de type permettent d’effectuer des opérations logiques sur les types des objets comparés:

  • -is, renvoie $true si le type de gauche est le même que le type de droite.
  • -isnot renvoie $true si le type de gauche n’est pas le même que le type de droite.

Il existe encore d’autres opérateurs comme par exemple:

  • -join suivit d’un tableau, permet de faire une concaténation.
  • -split, possède un comportement analogue à la méthode sur « string » .Split().

Le prochain article traitera des boucles, des structures conditionnelles, et de la gestion des exceptions.

Laisser un commentaire