在互联网上有很多例子展示了如何编写一个基本的动态参数,我只见过一个如何在一个函数中有多个动态参数的例子,但我还没有看到任何如何在动态参数中实现参数完成器的例子。
下面是一个基本动态参数的例子:
Param(
[Parameter( Position = 0, Mandatory = $True, HelpMessage = 'Choose a VM host for the VM(s).' )]
[ValidateScript( {
If ($null -eq $global:DefaultVIServer) {
Write-Host -BackgroundColor Yellow -ForegroundColor Red -Object 'Connect to vCenter!'
Break
}
Else {
If ($PSItem -in ((Get-VMHost).Name)) {
$True
}
Else {
Throw "Accepted values: $(((Get-VMHost).Name) -join ', ')"
}
}
} )]
[ArgumentCompleter( {
Param ($Cmd, $Param, $ParamComplete)
[Array]$ValidValues = (Get-VMHost | Sort-Object CpuUsageMhz).Name
$ValidValues -like "$ParamComplete*"
} )]
[String]$VMHost
)
DynamicParam {
## Dynamic DataStore.
$DynamicDataStore = 'DataStore'
$Attributes = New-Object -TypeName System.Management.Automation.ParameterAttribute
$Attributes.Position = 1
$Attributes.Mandatory = $True
$AttributeCollection = New-Object -TypeName 'System.Collections.ObjectModel.Collection[System.Attribute]'
$AttributeCollection.Add($Attributes)
$HostDataStores = (Get-VMHost -Name $VMHost | Get-Datastore | Sort-Object FreeSpaceGB -Descending).Name
$ValidateSetAttribute = New-Object -TypeName System.Management.Automation.ValidateSetAttribute($HostDataStores)
$AttributeCollection.Add($ValidateSetAttribute)
$DynamicParamater = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter($DynamicDataStore, [String], $AttributeCollection)
$DynamicParameterDictionary = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary
$DynamicParameterDictionary.Add($DynamicDataStore, $DynamicParamater)
Return $DynamicParameterDictionary
}
Begin {
# Make the dynamic parameter available for the auto-complete.
$DataStore = $PSBoundParameters[$DynamicDataStore]
}
这个实现的问题是,正如您所看到的,我试图首先列出具有最大空间的数据存储,但validateset数组并不关心我的顺序,而是按字母顺序排列值(参数制表符完成在这里工作)。
所以我想到使用argumentcompleter,它确实以我想要的方式在常规参数中工作(参见第一个示例中的VMHost参数),但看起来我无法让它在动态参数中工作,我希望其他人已经解决了这个问题,或者可以指导我正确的方向。
到目前为止我尝试过的:
DynamicParam {
## Dynamic DataStore.
$DynamicDataStore = 'DataStore'
$Attributes = New-Object -TypeName System.Management.Automation.ParameterAttribute
$Attributes.Position = 1
$Attributes.Mandatory = $True
$AttributeCollection = New-Object -TypeName 'System.Collections.ObjectModel.Collection[System.Attribute]'
$AttributeCollection.Add($Attributes)
$ValidateScriptAttribute = New-Object -TypeName System.Management.Automation.ValidateScriptAttribute({
If ($PSItem -in (Get-VMHost -Name $VMHost | Get-Datastore).Name) {
$True
}
Else {
Throw "Accepted values: $(((Get-VMHost -Name $VMHost | Get-Datastore).Name) -join ', ')"
}
})
$DynamicArgumentCompleter = New-Object -TypeName System.Management.Automation.ArgumentCompleterAttribute({
Param ($Cmd, $Param, $ParamComplete)
[Array]$ValidValues = (Get-VMHost -Name $VMHost | Get-Datastore | Sort-Object FreeSpaceGB -Descending).Name
$ValidValues -like "$ParamComplete*"
})
$AttributeCollection.Add($ValidateScriptAttribute)
$AttributeCollection.Add($DyamicArgumentCompleter)
$DynamicParamater = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter($DynamicDataStore, [String], $AttributeCollection)
$DynamicParameterDictionary = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary
$DynamicParameterDictionary.Add($DynamicDataStore, $DynamicParamater)
Return $DynamicParameterDictionary
}
这似乎是一个合乎逻辑的方法。
ValidateScriptBlock部件可以工作。我输入了一个不正确的值,并得到一个错误:“接受值:list of comma-delimited values”,但是argumentcompleter不做任何事情。
我期望它做的是当我在-DataStore参数后按tab键时显示接受的值,但是根本没有tab完成,没有按字母顺序排序,或者其他任何东西。
1条答案
按热度按时间x8diyxa71#
最简单和健壮的方法是使用
Register-ArgumentCompleter
,我不能访问你的完成集,但使用Get-Process
作为完成源和一个动态参数,下面是实现的样子:演示: