I det her indlæg ser vi på, hvordan du bruger dynamiske parametre i PowerShell Universal til at lave en formular, der tilpasser sig brugerens input.
Hvad er dynamiske parametre?
Dynamiske parametre gør det muligt at føje nye parametre til en cmdlet eller en avanceret funktion ud fra de parametre, der allerede er angivet. Hvis brugeren for eksempel angiver, at værdien af parameteren -AuthenticationType er Credential, kan du derefter tilføje en ny parameter -Credential til cmdlet’en. Det opnås ofte bedre med parametersæt, men nogle gange skal der mere logik til, når du beslutter, hvilke parametre der skal vises.
Ulempen ved dynamiske parametre er typisk, at de er sværere at opdage end statiske, fordi de først dukker op under kørsel.
Nedenfor er et eksempel på dynamiske parametre i et PowerShell-script. Dynamiske parametre kræver, at du definerer hvert aspekt af parameteren manuelt. Det omfatter attributter, type og navn, og at du derefter lægger det hele i en ordbog, som returneres fra blokken 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
}
Dynamiske formularer i PowerShell Universal
PowerShell Universal kan inspicere scripts, der definerer dynamiske parametre. Det gør det muligt at oprette dynamiske formularer, som dine brugere kan få glæde af. De opdager ikke engang, at du bruger PowerShell i baggrunden.
I eksemplet definerer vi et script med en mere kompleks opsætning af dynamiske parametre. Vi har en valgliste for division og system, og de afgør, om en eller flere komponenter vises, ud fra deres værdier.
Først definerer vi de statiske parametre. Hver er et sæt mulige værdier i vores opdigtede organisation.
param(
[ValidateSet("Sales", "HR", "Development")]
[string]$Division,
[ValidateSet("Entra ID", "Exchange", "Azure DevOps")]
[string]$System
)
Derefter definerer vi en DynamicParam-blok og sætter den grundlæggende struktur for dynamiske parametre op.
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
}
Det færdige script viser en formular med de to rullemenuer.
Først tilføjer vi noget logik, der afgør, hvad der sker, når en division vælges. I vores opdigtede virksomhed er divisionerne fordelt på nogle lokationer, og der vises endnu en rullemenu med mulige værdier for hver division.
Ud fra den valgte division beslutter vi, hvilke lokationer der er tilgængelige, og tildeler en ValidateSetAttribute for at gennemtvinge nogle mulige værdier.
$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")
}
Derefter kan vi tilføje en Location-parameter til vores samling af runtime-parametre.
$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)
Resultatet er, at formularen nu ændrer værdierne i lokationsrullemenuen ud fra den valgte division.
Til sidst tilføjer vi mere logik, der tjekker både division- og systemparametrene for at føje endnu en parameter til formularen. Vi kan bruge den samme parameterordbog og tilføje den nye parameter. Parameteren er defineret som en boolesk værdi og ikke en streng.
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)
}
Resultatet er, at formularen nu tilpasser sig ændringer i både division- og systemparametrene.
Når du har indtastet parametrene i scriptet og kørt det, kan du se, at værdierne for de dynamiske parametre sendes med sammen med de statiske.
Forbehold
Dynamiske parametre er nyttige, men de er begrænsede i omfang. Det bliver især et problem, når du vil justere dine parametre ud fra værdien af de dynamiske parametre selv. Du kan for eksempel ikke tilføje nye dynamiske parametre ud fra parametrene Location eller RunPipeline i eksemplet ovenfor.
Dynamiske parametre kan også gøre parametre sværere at opdage i funktioner som hjælpesystemet og gøre det sværere at forstå dine funktioner. Definitioner af dynamiske parametre er svære at læse og kan være svære for andre udviklere på teamet at forstå.
Overvej at bruge parametersæt frem for dynamiske parametre, hvor det er muligt. I PowerShell Universal kan du også overveje at bruge apps til at definere mere robuste formularer og lade dine scripts beholde statiske parametre.
Script
Du finder hele scriptet fra indlægget nedenfor.
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
}
Klar til at bygge? Hent PowerShell Universal.

Adam Driscoll