Powershell:TabExpansion ++ ArgumentCompleter的多个参数

时间:2015-05-07 20:51:48

标签: powershell

我正在开发一个用于安排用户家庭驱动器传输的功能,我将使用TabExpansion ++来允许用户自动填充服务器名称,该名称是从CSV文件填充的。 OldServerNewServer都有参数。

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' }

两者都没有效果。还有其他方法可以让这项工作吗?

1 个答案:

答案 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中它实际上弹出一个列表可供选择,而不仅仅是在控制台中完成选项卡)。