像这样的问题就是我喜欢这个网站的原因。我没有使用 TabExpansion++,但我已经为参数做了一些制表符扩展。我不记得以前是否遇到过这个确切的问题,所以我去寻找并发现了一些我以前在 PowerShell 世界中从未遇到过的东西,DynamicParam
。我以前怎么没见过这个?在这种情况下,它的出色程度简直是超乎想象的!它允许您做的不是声明参数,而是在函数的实际脚本块之前添加该参数,并执行脚本类型的操作来验证该参数。
我向谷歌寻求一点帮助,它给我指出了thisSO问题(Shay Levy给出了推荐TabExpansion++的公认答案),但下一个答案是关于DynamicParam的。所以我查了一下发现thisMicrosoft 网站上的博客进一步解释了这一点。基本上根据您的需求,您会执行以下操作:
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 参数添加到您的函数中。两者都将以制表符方式完成位于 CSV 的“站点”列中列出的服务器$global:ServerList
。当然,它不像 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
and -NewServer
,当我设置$global:ServerList
到“C:\Temp\new.csv”并填充具有 3 个值的“站点”列,这些值会立即弹出供我选择(在 ISE 中,它实际上会弹出一个列表可供选择,而不仅仅是选项卡完成就像在控制台中一样)。