Lorsque vous écrivez un script ou une fonction PowerShell, vous souhaitez souvent accepter les entrées de l’utilisateur via des paramètres. Si vous ne limitez pas les valeurs acceptées par ces paramètres, vous ne pouvez pas garantir qu’il n’y aura pas de situations où des valeurs inappropriées seront fournies. Dans cet article, apprenez comment utiliser l’attribut de validation des paramètres ValidateSet de PowerShell pour limiter ces valeurs aux seules que vous définissez.
En écrivant un script ou une fonction PowerShell, vous pouvez utiliser différentes attributs de validation pour vérifier que les valeurs fournies à vos paramètres sont acceptables et avertir l’utilisateur si ce n’est pas le cas.
Cet article se concentre sur l’attribut de validation ValidateSet. Vous apprendrez ce que fait ValidateSet, pourquoi vous pourriez vouloir utiliser ValidateSet dans votre code et comment le faire. Vous découvrirez également la fonctionnalité de complétion automatique activée par ValidateSet, qui aidera les utilisateurs de votre code à fournir des valeurs de paramètres valides.
PowerShell ValidateSet : Aperçu rapide
ValidateSet est un attribut de paramètre qui vous permet de définir un ensemble d’éléments acceptables comme valeur pour ce paramètre.
Par exemple, supposez que vous ayez un script conçu pour fonctionner avec des contrôleurs de domaine Active Directory. Ce script a un paramètre qui spécifie le nom d’un contrôleur de domaine. Ne serait-il pas logique de limiter la liste des valeurs acceptables aux noms réels des contrôleurs de domaine? Il n’y a aucune raison pour que l’utilisateur puisse utiliser « foobar » comme valeur lorsque vous connaissez à l’avance les valeurs nécessaires au script. ValidateSet vous offre cette possibilité.
Exigences
Cet article sera un guide d’apprentissage. Si vous prévoyez de suivre, vous aurez besoin des éléments suivants :
- Visual Studio Code ou tout autre éditeur de code. Je vais utiliser Visual Studio Code.
- Au moins PowerShell 5.1 pour la majorité du code dans cet article. Il y a une section qui nécessite PowerShell 6.1 ou ultérieur et je l’identifierai lorsque nous y arriverons.
Tout le code de cet article a été testé dans les environnements suivants :
Operating System | PowerShell Versions |
---|---|
Windows 7 SP1 | 5.1, Core 6.2 |
Windows 10 1903 | 5.1, Core 6.2 |
Linux Mint 19.2 | Core 6.2 |
Pour aider à expliquer les concepts autour de ValidateSet, vous allez construire un petit script appelé Get-PlanetSize.ps1. Ce script renvoie des informations sur les tailles des planètes de notre système solaire.
Vous commencerez avec un script simple et améliorerez progressivement sa capacité à gérer les entrées de l’utilisateur final et à faciliter la découverte de ses valeurs de paramètres possibles pour eux.
Commencer
Pour commencer, copiez d’abord et collez le code PowerShell ci-dessous dans votre éditeur de texte préféré et enregistrez-le sous le nom de Get-PlanetSize.ps1.
Exécutez le script à partir d’une invite PowerShell et vous devriez obtenir ce qui suit :
Informatif mais pas très flexible ; les informations pour chaque planète sont renvoyées, même si vous ne voulez que les informations pour Mars.
Peut-être souhaitez-vous avoir la possibilité de spécifier une seule planète au lieu de toutes les retourner. Vous pouvez le faire en introduisant un paramètre. Voyons comment y parvenir prochainement.
Accepter une entrée en utilisant un paramètre
Pour permettre au script d’accepter un paramètre, ajoutez un bloc Param()
en haut du script. Appelez le paramètre Planet
. Un bloc Param()
approprié ressemble à ce qui suit.
Dans l’exemple ci-dessous, la ligne [Parameter(Mandatory)]
garantit qu’un nom de planète est toujours fourni au script. S’il est manquant, le script demandera un.
La manière la plus simple d’incorporer ce paramètre Planet
dans le script est de changer la ligne $planets.keys | Foreach-Object {
en $Planet | Foreach-Object {
. Maintenant, vous ne vous fiez pas statiquement à la table de hachage définie précédemment, mais vous lisez plutôt la valeur du paramètre Planet
.
Maintenant, si vous exécutez le script et spécifiez une planète en utilisant le paramètre Planet
, vous ne verrez que des informations sur cette planète en particulier.
Excellent. Le script est-il terminé ? Peut-être pas.
Les options sont trop ouvertes
Que se passe-t-il si vous essayez de trouver le diamètre de la planète Barsoom en utilisant Get-PlanetSize.ps1 ?
Hmm, ce n’est pas correct. Barsoom n’est pas dans la liste des planètes, mais le script s’exécute quand même. Comment pouvons-nous résoudre cela ?
Le problème ici est que le script accepte n’importe quelle entrée et l’utilise, peu importe si c’est une valeur valide ou non. Le script a besoin d’un moyen de limiter les valeurs acceptées pour le paramètre Planet
. Entrez ValidateSet !
Assurer que seules certaines valeurs sont utilisées
A ValidateSet list is a comma-separated list of string values, wrapped in single or double-quotes. Adding a ValidateSet attribute to a script or function parameter consists of adding a line of text to the Param()
block, as shown below. Replace the Param()
block in your copy of Get-PlanetSize.ps1 with the one below and save the file.
Essayez d’exécuter à nouveau le script en utilisant Barsoom comme paramètre Planet
. Maintenant, un message d’erreur utile est retourné. Le message est spécifique sur ce qui s’est mal passé et fournit même une liste de valeurs possibles pour le paramètre.
Rendre ValidateSet de PowerShell sensible à la casse
Par défaut, l’attribut ValidateSet est insensible à la casse. Cela signifie qu’il acceptera n’importe quelle chaîne, pourvu qu’elle soit dans la liste autorisée avec n’importe quel schéma de capitalisation. Par exemple, l’exemple ci-dessus acceptera Mars
aussi facilement qu’il accepterait mars
. Si nécessaire, vous pouvez forcer ValidateSet à être sensible à la casse en utilisant l’option IgnoreCase
.
L’option IgnoreCase
dans ValidateSet est un attribut de validation qui détermine si les valeurs fournies au paramètre correspondent exactement à la liste des valeurs valides. Par défaut, IgnoreCase
est défini sur $True
(ignorer la casse). Si vous définissez ceci sur $False
, fournir mars comme valeur pour le paramètre Planet
pour Get-PlanetSize.ps1
générerait un message d’erreur.
Vous utiliseriez l’option IgnoreCase
en lui attribuant une valeur $true
à la fin de la liste des valeurs valides comme indiqué ci-dessous.
Maintenant, lorsque vous tentez d’utiliser une valeur pour Planet
qui n’est pas exactement comme une valeur dans la liste, la validation échouera.
Utilisation de la complétion automatique
Un autre avantage de l’utilisation de ValidateSet est qu’elle vous offre une complétion automatique. Cela signifie que vous pouvez parcourir les valeurs possibles pour un paramètre en utilisant la touche TAB. Cela améliore grandement la convivialité d’un script ou d’une fonction, surtout à partir de la console.
Dans les exemples ci-dessous, il y a quelques points à noter :
- La complétion automatique revient à la première valeur après avoir affiché la dernière.
- Les valeurs sont présentées dans l’ordre alphabétique, même si elles ne sont pas répertoriées dans ValidateSet alphabétiquement.
- Taper une lettre initiale et appuyer sur TAB restreint les valeurs offertes par la complétion automatique à celles commençant par cette lettre.


Vous pouvez également profiter de la complétion automatique de ValidateSet dans l’Environnement de Scripting Intégré PowerShell (ISE), comme le montre l’exemple ci-dessous. La fonctionnalité Intellisense de l’ISE vous montre la liste des valeurs possibles dans une belle boîte de sélection.
Intellisense renvoie toutes les valeurs contenant la lettre que vous tapez, plutôt que seulement celles qui commencent par elle.

Maintenant que nous avons couvert les attributs de validation ValidateSet tels qu’ils sont dans Windows 5.1, regardons ce qui a été ajouté dans PowerShell Core 6.1 et voyons si cela peut donner à notre script plus de capacités de validation.
Comprendre les modifications apportées à ValidateSet dans PowerShell 6.1
Avec l’arrivée de PowerShell Core 6.1, deux nouvelles fonctionnalités ont été ajoutées aux attributs de validation ValidateSet :
- La propriété
ErrorMessage
- L’utilisation de classes dans ValidateSet via l’accès à
System.Management.Automation.IValidateSetValuesGenerator
La propriété ErrorMessage
Le message d’erreur par défaut généré lorsque vous fournissez un nom de planète incorrect à Get-PlanetSize.ps1 est utile, mais un peu verbeux:
Utilisez la propriété ErrorMessage
de l’attribut de validation ValidateSet
pour définir un message d’erreur différent, comme illustré dans l’exemple ci-dessous. {0}
est automatiquement remplacé par la valeur soumise et {1}
est automatiquement remplacé par la liste des valeurs autorisées.
Remplacez le bloc Param()
dans le fichier de script et enregistrez-le. Ensuite, essayez à nouveau Get-PlanetSize.ps1 -Planet Barsoom
. Remarquez ci-dessous que l’erreur est beaucoup moins verbeuse et plus descriptive.
Ensuite, examinez une nouvelle façon de définir les valeurs acceptables dans ValidateSet via une classe PowerShell classe.
Classes PowerShell
Les types personnalisés, connus dans PowerShell sous le nom de classes, sont disponibles depuis la version 5. Avec l’arrivée de PowerShell Core 6.1, une nouvelle fonctionnalité permet l’utilisation d’une classe pour fournir les valeurs de ValidateSet.
En utilisant une classe, vous pouvez contourner la principale limitation d’un ValidateSet, à savoir qu’il est statique. Autrement dit, il est intégré en tant que partie de la fonction ou du script et ne peut être modifié qu’en éditant le script lui-même.
La nouvelle fonctionnalité qui fonctionne avec ValidateSet
est la possibilité d’utiliser la classe System.Management.Automation.IValidateSetValuesGenerator. Nous pouvons utiliser cela comme base pour nos propres classes en utilisant l’héritage. Pour travailler avec ValidateSet
, la classe doit être basée sur System.Management.Automation.IValidateSetValuesGenerator et elle doit implémenter une méthode appelée GetValidValues()
.
La méthode GetValues()
renvoie la liste des valeurs que vous souhaitez accepter. Un bloc Param()
avec la liste statique des planètes remplacée par une classe [Planet]
ressemblerait à ce qui suit. Cet exemple ne fonctionnera pas encore. Continuez à lire pour apprendre comment implémenter cela.
Utilisation d’une classe pour une liste de valeurs ValidateSet : Un exemple concret
Pour démontrer l’utilisation d’une classe pour une liste de valeurs ValidateSet, vous allez remplacer la liste statique des planètes utilisée précédemment par une liste chargée à partir d’un fichier texte CSV. Vous n’aurez plus besoin de maintenir une liste statique de valeurs à l’intérieur du script lui-même !
Création d’une source de données pour la classe
Tout d’abord, vous devrez créer un fichier CSV contenant chacune des valeurs valides. Pour ce faire, copiez et collez cet ensemble de données dans un nouveau fichier texte et enregistrez-le sous le nom de planets.csv dans le même dossier que le script Get-PlanetSize.ps1.
Ajout de la classe au script
Toute classe utilisée par ValidateSet doit déjà être définie avant que ValidateSet essaie de l’utiliser. Cela signifie que la structure de Get-PlanetSize.ps1 telle quelle ne fonctionnera pas.
La classe [Planet]
doit être définie avant de pouvoir être utilisée, donc elle doit être placée au début du script. Une définition de classe squelette appropriée ressemble à ce qui suit:
À l’intérieur de la méthode GetValidValues()
de la classe, utilisez le cmdlet Import-CSV
pour importer le fichier texte planets.csv créé précédemment. Le fichier est importé dans une variable à portée globale, appelée $planets
, afin d’y accéder plus tard dans le script.
Utilisez l’instruction return
pour retourner la liste des noms de planètes via GetValidValues()
. Après ces changements, la classe devrait maintenant ressembler à ce qui suit.
Ensuite, supprimez la déclaration du tableau de hachage $planets
du script comme indiqué ci-dessous. La variable globale $planets
qui est remplie par la classe [Planet]
contient les données de la planète à la place.
Enveloppez maintenant le code original restant dans une fonction et appelez-la Get-PlanetDiameter
pour la différencier du nom du script. Placez le bloc Param()
qui se trouvait au début du script à l’intérieur de la fonction. Remplacez la liste statique de planètes par une référence à la classe [Planet]
, comme indiqué ci-dessous.
Remplacez la ligne $output = "Le diamètre de la planète {0} est de {1} km" -f $_, $planets[$_]
par les deux lignes suivantes. Celles-ci permettent au script de rechercher une planète dans le tableau d’objets créé par Import-CSV
, plutôt que dans la table de hachage que vous avez créée précédemment et que vous avez supprimée du script :
Après cet ensemble de modifications, votre script final doit ressembler à ceci :
N’oubliez pas, à partir de ce moment-là, le script fonctionne uniquement sous PowerShell 6.1 ou ultérieur
Maintenant, comment utiliser ce script ?
Exécution du script
Vous ne pouvez pas utiliser la nouvelle version du script directement en l’exécutant simplement. Tout le code utile est maintenant enveloppé dans une fonction. Vous devez charger le fichier plutôt pour permettre l’accès à la fonction depuis la session PowerShell.
Une fois chargé, vous avez désormais accès à la nouvelle fonction Get-PlanetDiameter
dans la session PowerShell, avec la complétion par tabulation.
« Quel est l’avantage de tout ce travail ? », vous demandez-vous. « Le script semble fonctionner de la même manière, mais il est plus difficile d’utiliser le code ! »
Essayez ceci :
- Ouvrez le fichier
planets.csv
que vous avez créé précédemment. - Ajoutez une nouvelle ligne avec un nouveau nom et un diamètre.
- Enregistrez le fichier CSV.
Dans la même session où vous avez initialement intégré votre script, essayez de rechercher le diamètre de la nouvelle planète en utilisant Get-PlanetDiameter
. Ça fonctionne !
Utiliser une classe de cette manière nous offre plusieurs avantages :
- La liste des valeurs valides est maintenant séparée du code lui-même, mais toutes les modifications apportées aux valeurs dans le fichier sont détectées par le script.
- Le fichier peut être maintenu par quelqu’un qui n’accède jamais au script.
- A more complex script could look up information from a spreadsheet, database, Active Directory or a web API.
Comme vous pouvez le voir, les possibilités sont presque infinies lors de l’utilisation d’une classe pour fournir des valeurs ValidateSet.
Conclusion
Nous avons parcouru beaucoup de chemin en construisant Get-PlanetSize.ps1
, alors récapitulons.
Dans cet article, vous avez appris :
- Qu’est-ce qu’un attribut de validation ValidateSet et pourquoi vous pourriez vouloir l’utiliser
- Comment ajouter ValidateSet à une fonction PowerShell ou à un script
- Comment fonctionne l’achèvement automatique avec ValidateSet
- Comment utiliser la propriété
IgnoreCase
pour contrôler la sensibilité à la casse de votre ValidateSet - Comment utiliser la propriété
ErrorMessage
avec votre ValidateSet et PowerShell 6.1 - Comment utiliser une classe pour créer un ValidateSet dynamique avec PowerShell 6.1
Qu’attendez-vous ? Commencez à utiliser ValidateSet dès aujourd’hui !
Lecture complémentaire
Source:
https://adamtheautomator.com/powershell-validateset/