我正在开发一个用于安排用户家庭驱动器传输的功能,我将使用TabExpansion ++来允许用户自动填充服务器名称,该名称是从CSV文件填充的。 OldServer
和NewServer
都有参数。
TabExpansion ++是否可以为单个自动填充器指定多个参数?
这就是我所拥有的:
function HomeDriveSiteCompletion {
[ArgumentCompleter(
Parameter = 'OldServer',
Command = { 'Schedule-HomeTransfer' },
Description = 'Home drive transfer tool server name autocomplete')]
param($commandName,$parameterName,$wordToComplete,$commandAst,$fakeBoundParameter)
Import-Csv -Path $Global:ServersList | % {New-CompletionResult -ToolTip $_.Site -completiontext $_.Site}
}
适用于OldServer
。如果我可以通过在同一个地方指定两个参数来保存代码,那将是理想的。我试过了两个
Parameter = @('OldServer','NewServer')
和
Parameter = { 'OldServer','NewServer' }
两者都没有效果。还有其他方法可以让这项工作吗?
答案 0 :(得分:2)
这样的问题是我喜欢这个网站的原因。我没有使用TabExpansion ++,但我已经为参数做了一些标签扩展。我不记得我之前是否遇到过这个问题,所以我去寻找并发现了之前在PowerShell世界中遇到的一些事情DynamicParam
。我以前怎么没见过这个?对于像这样的情况,它的令人敬畏的水平就在图表之外!它允许你做的不是声明一个参数,而是在函数的实际scriptblock之前添加该参数,并为验证该参数做了大量的事情。
我向谷歌寻求了一些帮助,它向我指出this所以问题(Shay Levy给出了推荐TabExpansion ++的接受答案),但下一个答案是关于DynamicParam的。所以我查了一下,发现微软网站上的this博客进一步解释了这一点。基本上可以满足您的需求:
DynamicParam {
$SrvList = Import-CSV $Global:ServerList | Select -Expand Site
$ParamNames = @('OldServer','NewServer')
#Create Param Dictionary
$ParamDictionary = new-object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
ForEach($Name in $ParamNames){
#Create a container for the new parameter's various attributes, like Manditory, HelpMessage, etc that usually goes in the [Parameter()] part
$ParamAttribCollecton = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute]
#Create each attribute
$ParamAttrib = new-object System.Management.Automation.ParameterAttribute
$ParamAttrib.Mandatory = $true
$ParamAttrib.HelpMessage = "Enter a server name"
#Create ValidationSet to make tab-complete work
$ParamValSet = New-Object -type System.Management.Automation.ValidateSetAttribute($SrvList)
#Add attributes and validationset to the container
$ParamAttribCollecton.Add($ParamAttrib)
$ParamAttribCollecton.Add($ParamValSet)
#Create the actual parameter, then add it to the Param Dictionary
$MyParam = new-object -Type System.Management.Automation.RuntimeDefinedParameter($Name, [String], $ParamAttribCollecton)
$ParamDictionary.Add($Name, $MyParam)
}
#Return the param dictionary so the function can add the parameters to itself
return $ParamDictionary
}
这会将OldServer和NewServer参数添加到您的函数中。两者都可以选项卡填写位于$global:ServerList
的CSV的“网站”列中列出的服务器。当然,它不像TabExpansion ++的上下文那么简短和甜蜜,但另一方面,它不需要任何额外的模块或任何东西加载到系统上,因为它都是自包含的仅使用基本的PowerShell功能。
现在,这会添加参数,但它实际上并没有将它们分配给变量,因此我们必须在函数的Begin
部分执行此操作。我们将列出PSBoundParameters.Keys
中的参数并检查当前作用域中是否已存在变量,如果不存在,我们将在当前作用域中创建一个变量,以便混淆当前作用域内的任何内容。功能。因此,使用-User
的基本参数,两个动态参数以及动态参数变量的添加,我们会为您的函数查看类似的内容:
Function Schedule-HomeTransfer{
[CmdletBinding()]
Param([string]$User)
DynamicParam {
$SrvList = Import-CSV $Global:ServerList | Select -Expand Site
$ParamNames = @('OldServer','NewServer')
#Create Param Dictionary
$ParamDictionary = new-object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
ForEach($Name in $ParamNames){
#Create a container for the new parameter's various attributes, like Manditory, HelpMessage, etc that usually goes in the [Parameter()] part
$ParamAttribCollecton = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute]
#Create each attribute
$ParamAttrib = new-object System.Management.Automation.ParameterAttribute
$ParamAttrib.Mandatory = $true
$ParamAttrib.HelpMessage = "Enter a server name"
#Create ValidationSet to make tab-complete work
$ParamValSet = New-Object -type System.Management.Automation.ValidateSetAttribute($SrvList)
#Add attributes and validationset to the container
$ParamAttribCollecton.Add($ParamAttrib)
$ParamAttribCollecton.Add($ParamValSet)
#Create the actual parameter, then add it to the Param Dictionary
$MyParam = new-object -Type System.Management.Automation.RuntimeDefinedParameter($Name, [String], $ParamAttribCollecton)
$ParamDictionary.Add($Name, $MyParam)
}
#Return the param dictionary so the function can add the parameters to itself
return $ParamDictionary
}
Begin{$PSBoundParameters.Keys | Where{!(Get-Variable -name $_ -Scope 0 -ErrorAction SilentlyContinue)} | ForEach{New-Variable -Name $_ -Value $PSBoundParameters[$_]}}
Process{
"You chose to move $User from $OldServer to $NewServer"
}
}
这样就可以在-OldServer
和-NewServer
上完成标签,并且当我将$global:ServerList
设置为" C:\ Temp \ new.csv'并填充了一个网站'有3个值的列,那些弹出窗口供我选择(在ISE中它实际上弹出一个列表可供选择,而不仅仅是在控制台中完成选项卡)。