1

編輯如何在Powershell中指定靜態和動態位置參數?

按瘋狂的技術員的建議,我已經提交錯誤報告這個在PowerShell的UserVoice的網站:https://windowsserver.uservoice.com/forums/301869-powershell/suggestions/20034763-dynamic-parameters-and-positional-parameters-do-no

原來的問題

我希望能夠指定PowerShell函數中的位置參數,包括靜態和動態參數。例如我有

function Test-Positional{ 
[CmdletBinding(PositionalBinding=$false)] 
param(
    [Parameter(Mandatory=$false,Position=3)][string]$Param4 
) 
dynamicparam { 
    $paramDictionary = new-object -Type System.Management.Automation.RuntimeDefinedParameterDictionary 

    $paramname1 = "Param1" 
    $values1 = 'some','list','of','values' #would normally get these dynamically 
    $attributes1 = new-object System.Management.Automation.ParameterAttribute 
    $attributes1.ParameterSetName = "__AllParameterSets" 
    $attributes1.Mandatory = $true 
    $attributes1.Position = 0 
    $attributeCollection1 = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute] 
    $attributeCollection1.Add($attributes1) 
    $ValidateSet1 = new-object System.Management.Automation.ValidateSetAttribute($values1) 
    $attributeCollection1.Add($ValidateSet1) 
    $dynParam1 = new-object -Type System.Management.Automation.RuntimeDefinedParameter($paramname1, [string], $attributeCollection1) 

    $paramname2 = "Param2" 
    $values2 = 'another','list','like','before' 
    $attributes2 = new-object System.Management.Automation.ParameterAttribute 
    $attributes2.ParameterSetName = "__AllParameterSets" 
    $attributes2.Mandatory = $true 
    $attributes2.Position = 1 
    $attributeCollection2 = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute] 
    $attributeCollection2.Add($attributes2) 
    $ValidateSet2 = new-object System.Management.Automation.ValidateSetAttribute($values2) 
    $attributeCollection2.Add($ValidateSet2) 
    $dynParam2 = new-object -Type System.Management.Automation.RuntimeDefinedParameter($paramname2, [string], $attributeCollection2) 

    $paramname3 = "Param3" 
    $values3 = 'yet','another','list' 
    $attributes3 = new-object System.Management.Automation.ParameterAttribute 
    $attributes3.ParameterSetName = "__AllParameterSets" 
    $attributes3.Mandatory = $true 
    $attributes3.Position = 2 
    $attributeCollection3 = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute] 
    $attributeCollection3.Add($attributes3) 
    $ValidateSet3 = new-object System.Management.Automation.ValidateSetAttribute($values3) 
    $attributeCollection3.Add($ValidateSet3) 
    $dynParam3 = new-object -Type System.Management.Automation.RuntimeDefinedParameter($paramname3, [string], $attributeCollection3) 

    $paramDictionary.Add($paramname1, $dynParam1) 
    $paramDictionary.Add($paramname2, $dynParam2) 
    $paramDictionary.Add($paramname3, $dynParam3) 
    return $paramDictionary 
} 

process{ 
    $PSBoundParameters.Param1 
    $PSBoundParameters.Param2 
    $PSBoundParameters.Param3 
    $PSBoundParameters.Param4 
} 
} 

,但如果我跑PS C:\Windows\System32\inetsrv> Test-Positional 'list' 'another' 'yet' 'so' 我得到的錯誤:

​​

它不會拋出,如果我從靜態參數(param4 $),這是很好的去除Position=3屬性除非我不能用它作爲位置參數,我必須直接命名它。我得到相同的錯誤,如果我保持Position=3和刪除PositionalBinding=$false

它是不可能有靜態和動態參數都是位置參數?還是我錯過了一些明顯的東西?

回答

2

位置與相同類型的參數有關。所以靜態參數將尊重其他靜態參數的位置,而動態參數將尊重其他動態參數的位置,但靜態參數將首先消耗參數,動態參數將消耗所剩下的任何參數。我知道的唯一例外情況是,如果使用參數屬性ValueFromRemainingArguments=$true,這會強制該特定參數成爲最後一個參數。所以,如果你真的只有1個靜態參數,你可以設置ValueFromRemainingArguments=$true,它會按照你的意願行事。如果您有其他靜態參數,則無論您指定的位置晚於動態參數的位置,它們仍會位於動態參數之前。

它看起來像你對我發現了一個錯誤,我會鼓勵你提交Bug這個在PowerShell的UserVoice的網站:https://windowsserver.uservoice.com/forums/301869-powershell

在我看來,他們應該或者更新的文件聲明,動態參數定位在統計參數定位後進行評估,並在針對函數/腳本運行Get-Help時更正語法部分,或者相應地更新行爲,以便在動態參數和靜態參數兩方面都考慮位置。我自己更喜歡後者,但這可能涉及不可行的引擎更改。

如果你確實創建了一個bug,請提供一個鏈接,以便其他人可以找到它並投票它(這樣它才能獲得關注並得到修復!)。