PowerShell | How to cross-reference parameters between 2 argument completers?
My PowerShell module has 2 argument completers. The 2 parameters with argument completers are related to each other in a way that by calculating the value of one of them, we can get the value of the other one.
I want to use this relation to make sure when both of those parameters are being used, they only suggest unique values.
Remove-WDACConfig -UnsignedOrSupplemental -PolicyIDs a244370e-44c9-4c06-b551-f6016e563076,d3645984-47a0-4c8e-be75-1c06840e13e6,38734d8a-4bc4-4dd3-b23f-57f536814426,e63679a6-ae84-4d27-b842-258217562941 -PolicyNames 'Microsoft Windows Driver Policy - Enforced','Supplemental Policy 1 - 05-16-2023','Supplemental Policy 2 - 05-16-2023','Allow Microsoft Plus Block Rules - 05-16-2023'
As you can see in the command above, there are 4 policies deployed. I selected 4 of them by their IDs and then selected the same 4 with their names. Running that command throws an error for the next 4 since PowerShell can't find them anymore when they are already removed by IDs.
I want to change the argument completers so that when I specify say 2 of them by name, the ID of those 2 shouldn't appear when argument completing the IDs.
The values are Code Integrity policy IDs and names. This is related to a previous question.
I did try to modify it but couldn't get it to work exactly the way I want.
[ArgumentCompleter({
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
$candidates = [PolicyIDz]::new().GetValidValues() | ForEach-Object { if ($_ -notin $fakeBoundParameters) { $_ } }
$existing = $commandAst.FindAll({
$args[0] -is [System.Management.Automation.Language.StringConstantExpressionAst]
},
$false
).Value
#$existing = $existing | ForEach-Object { if ($_ -notin $fakeBoundParameters) { $_ } }
Compare-Object -PassThru $candidates $existing | Where-Object SideIndicator -eq '<='
})]
[ValidateScript({
if ($_ -notin [PolicyIDz]::new().GetValidValues()) { throw "Invalid policy ID: $_" }
$true
})]
[Parameter(Mandatory = $false, ParameterSetName = "Unsigned Or Supplemental")]
[System.String[]]$PolicyIDs,
[ArgumentCompleter({
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
$candidates = [PolicyNamez]::new().GetValidValues() | ForEach-Object { $CurrentActiveLoop = $_; if ((((CiTool -lp -json | ConvertFrom-Json).Policies | Where-Object { $_.FriendlyName -eq $CurrentActiveLoop }).PolicyID) -notin $fakeBoundParameters) { $_ } }
$existing = $commandAst.FindAll({
$args[0] -is [System.Management.Automation.Language.StringConstantExpressionAst]
},
$false
).Value
# $existing = $existing | ForEach-Object { $CurrentActiveLoop = $_; if ((((CiTool -lp -json | ConvertFrom-Json).Policies | Where-Object { $_.FriendlyName -eq $CurrentActiveLoop }).PolicyID) -notin $fakeBoundParameters) { $_ } }
(Compare-Object -PassThru $candidates $existing | Where-Object SideIndicator -eq '<=').
ForEach({ if ($_ -match ' ') { "'{0}'" -f $_ } else { $_ } })
})]
[ValidateScript({
if ($_ -notin [PolicyNamez]::new().GetValidValues()) { throw "Invalid policy name: $_" }
$true
})]
[Parameter(Mandatory = $false, ParameterSetName = "Unsigned Or Supplemental")]
[System.String[]]$PolicyNames,
My goal was to cross-refence all of the values stored in the $fakeBoundParameters
by policy ID. I'm not sure what I'm missing.
They use class based ValidateSets too
# argument tab auto-completion and ValidateSet for Policy names
Class PolicyNamez : System.Management.Automation.IValidateSetValuesGenerator {
[System.String[]] GetValidValues() {
$PolicyNamez = ((CiTool -lp -json | ConvertFrom-Json).Policies | Where-Object { $_.IsOnDisk -eq "True" } | Where-Object { $_.IsSystemPolicy -ne "True" }).Friendlyname | Select-Object -Unique
return [System.String[]]$PolicyNamez
}
}
# argument tab auto-completion and ValidateSet for Policy IDs
Class PolicyIDz : System.Management.Automation.IValidateSetValuesGenerator {
[System.String[]] GetValidValues() {
$PolicyIDz = ((CiTool -lp -json | ConvertFrom-Json).Policies | Where-Object { $_.IsOnDisk -eq "True" } | Where-Object { $_.IsSystemPolicy -ne "True" }).policyID
return [System.String[]]$PolicyIDz
}
}
}
Comments
Post a Comment