2015-05-07 18 views
1

我正在研究安排用戶主驅動器傳輸的功能,我將使用TabExpansion ++來允許用戶自動填充從CSV文件填充的服務器名稱。將會有參數OldServerNewServerPowershell:TabExpansion ++ ArgumentCompleter的多個參數

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

均未奏效。有另一種方法可以使這項工作?

回答

2

這樣的問題是爲什麼我喜歡這個網站。我沒有使用TabExpansion ++,但是我已經爲參數做了一些標籤擴展。我不記得在之前我是否會碰到這個確切的問題,所以我去查找並發現了一些在PowerShell世界中沒有遇到過的東西,DynamicParam。我以前怎麼沒見過這個?對於這種情況來說,它的真棒級別就在圖表之外!它允許你做的不是聲明一個參數,而是在該函數的實際腳本塊之前添加該參數,並對該參數進行腳本類型的驗證。

我問了Google一些幫助,它指出我this SO問題(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中它實際上彈出一個可供選擇的列表,而不僅僅是控制檯中的標籤完成)