簡體   English   中英

位置綁定和參數集

[英]Postional Binding and ParameterSets

我正在努力理解參數集和位置綁定的行為。 這是示例 function。

function Test-PositionBinding {
    [CmdletBinding(DefaultParameterSetName = 'ParamSet2')]
    param (
        [Parameter(ParameterSetName='ParamSet1',Position = 0)]
        [int]
        $param1,

        [Parameter(ParameterSetName='ParamSet1',Position = 1)]
        [int]
        $param2,

        [Parameter(ParameterSetName='ParamSet2',Position = 0)]
        [int]
        $param3
    )    
    process {
        $PSCmdlet.ParameterSetName
        $param1
        $param2
        $param3
    }
}

根據 output 的幫助,似乎用單個 int 調用 function 應該使用 paramset1,用 2 int 調用它應該使用 paramset2,這正是我所期望的。

SYNTAX
    Test-PositionBinding [[-param3] <int>] [<CommonParameters>]

    Test-PositionBinding [[-param1] <int>] [[-param2] <int>] [<CommonParameters>]

但是,我收到以下 output。

PS C:\> Test-PositionBinding 1
ParamSet2
0
0
1
PS C:\> Test-PositionBinding 1 2

Test-PositionBinding: A positional parameter cannot be found that accepts argument '2'.

我會期待以下。

PS C:\> Test-PositionBinding 1 2
ParamSet1
1
2
0

如果我們將 param1 的類型更改為字符串,則 function 將按預期工作。

PS C:\> Test-PositionBinding 1
ParamSet2

0
1
PS C:\> Test-PositionBinding 'abc'
ParamSet1
abc
0
0
PS C:\> Test-PositionBinding 'abc' 2
ParamSet1
abc
2
0

我對 PS 解釋參數集的方式有什么誤解?

最終我的問題是,如果第一個參數在集合之間的類型相同,為什么 PS 無法區分具有位置綁定和不同參數計數的 2 個參數集。

如果添加 IF,您可以在選擇參數 1 或 2 時看到您在參數集 1 中

如果你選擇 param1 或 2 你不能 select 參數 3 或 4

如果你運行 Test-postionbinding 1

然后,由於 param1 被定義為 0,因此 powershell 將自動將傳遞給 function 的第一個參數綁定到 position 0。
如果你通過 0 -param4 1
Param3 的值為 0,param4 為 1,您將進入 paramset2。

如果您指定 param1,那么您唯一的其他參數是 param2,因為它是 Paramset1 的成員

如果您選擇 param3,那么唯一可用的其他參數是 param4,因為它是 paramset2 的一部分

function Test-PositionBinding {
    [CmdletBinding(DefaultParameterSetName = 'ParamSet2')]
    param (
        [Parameter(ParameterSetName='ParamSet1',Position = 0)]
        [int]
        $param1,

        [Parameter(ParameterSetName='ParamSet1',Position = 1)]
        [int]
        $param2,

        [Parameter(ParameterSetName='ParamSet2',Position = 0)]
        [int]
        $param3
    )    
    process {
        if($PSCmdlet.ParameterSetName -eq "paramset1")
        {
            write-output "Paramset1"
            $param1
            $param2
        }

        if($PSCmdlet.ParameterSetName -eq "paramset2")
        {
            write-output "Paramset2"
            $param3
            $param4
        }
    }
}

觀察 position 2 綁定

Test-PositionBinding -param1 1 10
Paramset1
1
10

觀察參數集2

Test-PositionBinding -param3 10
Paramset2
10

不使用參數名稱並強制 powershell 使用指定的綁定:Test-PositionBinding 0 1 Test-PositionBinding:A position

al parameter cannot be found that accepts argument '1'.
At line:1 char:1
+ Test-PositionBinding 0 1
+ ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Test-PositionBinding], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Test-PositionBinding


PS C:\WINDOWS\system32> Test-PositionBinding 0
Paramset2
0

根據 MS Docs:

參數集要求 以下要求適用於所有參數集。

每個參數集必須至少有一個唯一參數。 如果可能,請將此參數設置為強制參數。

包含多個位置參數的參數集必須為每個參數定義唯一的位置。 沒有兩個位置參數可以指定相同的 position。

一組參數中只有一個參數可以聲明 ValueFromPipeline 關鍵字的值為 true。 多個參數可以定義值為 true 的 ValueFromPipelineByPropertyName 關鍵字。

如果沒有為參數指定參數集,則該參數屬於所有參數集。

這是一篇關於這個主題的好文章,對我有幫助。 在這里剪掉它,而不是只給你一個跳轉到的鏈接。 盡管這不是特定於參數集的,但適用相同的規則。

指定 PowerShell 參數 Position

對於某些命令來說,允許您通過 position 而不是通過名稱傳遞內容是有意義的,尤其是在省略參數名稱(如本例中)的情況下,會造成一些混亂。

function Test-Position
{
    [CmdletBinding()]
    Param
    (
        [parameter(Position=0)]$parm1,
        [parameter(Position=1)]$parm2,
        [parameter(Position=2)]$parm3,
        [parameter(Position=3)]$parm4
    )
}

我應該怎么辦?

> 根據幫助(about_Functions_CmdletBindingAttribute),您應該使用 CmdletBinding() 屬性的 PositionalBinding 可選參數,並將其設置為 $false。

這將導致 position 不允許所有參數默認。 然后,> 您可以為您希望 position 使用的任何(希望只有一兩個)參數指定 Position。

例如,這將只允許 position 使用 $parm1:

function Test-Position
{
    [CmdletBinding(PositionalBinding = $false)]
    Param([parameter(Position=0)]$parm1,
                                    $parm2,
                                    $parm3,
                                    $parm4)
}

但是等等,它變得更容易了

盡管幫助說明默認情況下所有參數都是位置參數,但事實證明,在一個參數上使用 Position 意味着您必須在 position 訪問的任何參數上使用它。

例如,在這個版本的 function 中,我沒有在 CmdletBinding 屬性中指定 ositionalBinding=$False,但 position 只能使用第一個參數。

function Test-Position2
{
    [CmdletBinding()]
    Param
    (
        [parameter(Position=0)]$parm1, 
                                $parm2, 
                                $parm3, 
                                $parm4
    )
}

這對我來說很有趣,因為它似乎與幫助中的內容相矛盾。 具體來說,幫助說所有參數都是位置的。 然后它說為了禁用這個默認值,你應該使用 PositionalBinding 參數。 這表明您不需要這樣做,除非您不想要任何位置參數。

作為最后一個示例,為了確保我們了解如何使用 Position 值,請考慮以下 function 和語法幫助:

function Test-Position3
{
    [CmdletBinding()]
    Param
    (
        $parm1,
        $parm2,
        [parameter(Position=1)]$parm3,
        [parameter(Position=0)]$parm4
    )
}

通過在其中兩個參數中包含 Position,我們確保了其他兩個參數只能通過名稱獲得。 此外,分配的位置與 function 中定義的參數順序不同,這反映在語法幫助中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM