Dans cet article, nous verrons comment utiliser les paramètres dynamiques dans PowerShell Universal pour offrir un formulaire qui s’adapte à la saisie de l’utilisateur.
Que sont les paramètres dynamiques?
Les paramètres dynamiques permettent d’ajouter de nouveaux paramètres à une applet de commande ou à une fonction avancée selon les paramètres déjà fournis. Par exemple, si l’utilisateur indique que la valeur d’un paramètre -AuthenticationType est Credential, vous pouvez ensuite ajouter un paramètre -Credential à l’applet de commande. Même si c’est souvent mieux de le faire avec des jeux de paramètres, il peut être nécessaire d’ajouter un peu plus de logique pour décider quels paramètres afficher.
Les inconvénients des paramètres dynamiques sont généralement qu’ils sont moins découvrables que les paramètres statiques, car ils n’apparaissent qu’à l’exécution.
Voici un exemple de paramètres dynamiques dans un script PowerShell. Les paramètres dynamiques exigent de définir manuellement chaque aspect du paramètre: les attributs, le type et le nom, puis de les ajouter tous à un dictionnaire à retourner depuis le bloc DynamicParam.
[CmdletBinding()]
param(
[ValidateSet("Credential", "AppToken")]
[string]$AuthenticationType
)
DynamicParam {
$paramAttributes = [System.Management.Automation.ParameterAttribute]::new()
$paramAttributes.Mandatory = $true
$paramAttributesCollect = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
$paramAttributesCollect.Add($paramAttributes)
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
if ($AuthenticationType -eq 'Credential') {
$dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new("Credential", [PSCredential], $paramAttributesCollect)
$paramDictionary.Add("Credential", $dynParam1)
}
if ($AuthenticationType -eq 'AppToken') {
$dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new("AppToken", [SecureString], $paramAttributesCollect)
$paramDictionary.Add("AppToken", $dynParam1)
}
return $paramDictionary
}
Formulaires dynamiques dans PowerShell Universal
PowerShell Universal peut inspecter les scripts qui définissent des paramètres dynamiques. Cela permet de créer des formulaires dynamiques dont vos utilisateurs peuvent profiter. Ils ne sauront même pas que vous utilisez PowerShell en arrière-plan.
Dans cet exemple, nous définirons un script avec une configuration de paramètres dynamiques plus complexe. Nous aurons une liste de sélection pour la division et le système, et elles décideront si un ou plusieurs composants s’affichent selon leurs valeurs.
D’abord, nous définissons les paramètres statiques. Chacun est un ensemble de valeurs possibles dans notre organisation fictive.
param(
[ValidateSet("Sales", "HR", "Development")]
[string]$Division,
[ValidateSet("Entra ID", "Exchange", "Azure DevOps")]
[string]$System
)
Ensuite, nous définirons un bloc DynamicParam et mettrons en place la structure de base des paramètres dynamiques.
DynamicParam {
$paramAttributes = [System.Management.Automation.ParameterAttribute]::new()
$paramAttributesCollect = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
$paramAttributesCollect.Add($paramAttributes)
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
return $paramDictionary
}
Le script résultant affiche un formulaire avec les deux listes déroulantes.
D’abord, nous ajouterons de la logique pour décider ce qui se passe lorsqu’une division est sélectionnée. Dans notre entreprise fictive, nos divisions sont réparties sur plusieurs emplacements et afficheront une autre liste déroulante avec les valeurs possibles pour chaque division.
Selon la division sélectionnée, nous déciderons quels emplacements sont disponibles et assignerons un ValidateSetAttribute pour imposer certaines valeurs possibles.
$paramAttributes = [System.Management.Automation.ParameterAttribute]::new()
$paramAttributes.Mandatory = $true
if ($Division -eq 'Sales') {
$validateAttribute = [System.Management.Automation.ValidateSetAttribute]::new("Washington DC", "Phoenix", "Chicago")
} elseif ($Division -eq 'HR') {
$validateAttribute = [System.Management.Automation.ValidateSetAttribute]::new("London", "Seattle", "Orlando")
} elseif ($Division -eq 'Development') {
$validateAttribute = [System.Management.Automation.ValidateSetAttribute]::new("Madison", "Boise", "Denver")
}
Nous pouvons ensuite ajouter un paramètre Location à notre collection de paramètres d’exécution.
$paramAttributesCollect = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
$paramAttributesCollect.Add($paramAttributes)
$paramAttributesCollect.Add($validateAttribute)
$dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new("Location", [string], $paramAttributesCollect)
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
$paramDictionary.Add("Location", $dynParam1)
Le résultat est que notre formulaire change maintenant les valeurs de la liste déroulante d’emplacement selon la division sélectionnée.
Enfin, nous ajouterons de la logique pour vérifier à la fois les paramètres de division et de système afin d’ajouter un autre paramètre au formulaire. Nous pouvons utiliser le même dictionnaire de paramètres et y ajouter notre nouveau paramètre. Ce paramètre est défini comme un booléen plutôt qu’une chaîne.
if ($Division -eq 'Development' -and $System -eq 'Azure DevOps') {
$paramAttributes = [System.Management.Automation.ParameterAttribute]::new()
$paramAttributesCollect = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
$paramAttributesCollect.Add($paramAttributes)
$dynParam2 = [System.Management.Automation.RuntimeDefinedParameter]::new("RunPipeline", [bool], $paramAttributesCollect)
$paramDictionary.Add("RunPipeline", $dynParam2)
}
Le résultat est que notre formulaire s’adapte maintenant aux changements des paramètres de division et de système.
Après avoir saisi les paramètres dans le script et l’avoir exécuté, vous verrez que les valeurs des paramètres dynamiques sont passées en même temps que les valeurs statiques.
Limites
Même si les paramètres dynamiques sont utiles, leur portée est limitée. Cela devient surtout un problème lorsque vous voulez ajuster vos paramètres selon la valeur des paramètres dynamiques eux-mêmes. Par exemple, vous ne pourriez pas ajouter de nouveaux paramètres dynamiques selon les paramètres Location ou RunPipeline dans notre exemple ci-dessus.
Les paramètres dynamiques peuvent aussi réduire la découvrabilité des paramètres dans des fonctions comme le système d’aide et rendre vos fonctions plus difficiles à comprendre. Les définitions de paramètres dynamiques sont difficiles à lire et peuvent être dures à suivre pour les autres développeurs de votre équipe.
Envisagez d’utiliser des jeux de paramètres plutôt que des paramètres dynamiques, lorsque c’est possible. Dans PowerShell Universal, vous pourriez aussi utiliser des applis pour définir des formulaires plus robustes et laisser vos scripts avec des paramètres statiques.
Script
Vous trouverez le script complet de cet article ci-dessous.
param(
[ValidateSet("Sales", "HR", "Development")]
[string]$Division,
[ValidateSet("Entra ID", "Exchange", "Azure DevOps")]
[string]$System
)
DynamicParam {
$paramAttributes = [System.Management.Automation.ParameterAttribute]::new()
$paramAttributes.Mandatory = $true
if ($Division -eq 'Sales') {
$validateAttribute = [System.Management.Automation.ValidateSetAttribute]::new("Washington DC", "Phoenix", "Chicago")
} elseif ($Division -eq 'HR') {
$validateAttribute = [System.Management.Automation.ValidateSetAttribute]::new("London", "Seattle", "Orlando")
} elseif ($Division -eq 'Development') {
$validateAttribute = [System.Management.Automation.ValidateSetAttribute]::new("Madison", "Boise", "Denver")
}
$paramAttributesCollect = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
$paramAttributesCollect.Add($paramAttributes)
$paramAttributesCollect.Add($validateAttribute)
$dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new("Location", [string], $paramAttributesCollect)
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
$paramDictionary.Add("Location", $dynParam1)
if ($Division -eq 'Development' -and $System -eq 'Azure DevOps') {
$paramAttributes = [System.Management.Automation.ParameterAttribute]::new()
$paramAttributesCollect = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
$paramAttributesCollect.Add($paramAttributes)
$dynParam2 = [System.Management.Automation.RuntimeDefinedParameter]::new("RunPipeline", [bool], $paramAttributesCollect)
$paramDictionary.Add("RunPipeline", $dynParam2)
}
return $paramDictionary
}
Prêt à construire? Téléchargez PowerShell Universal.

Adam Driscoll