gpt4 book ai didi

PowerShell 管道参数绑定(bind)顺序

转载 作者:行者123 更新时间:2023-12-01 03:08:00 25 4
gpt4 key购买 nike

我有一个可以接受两种管道数据的高级功能:

  • PSTypeName 为“MyType”
  • 的自定义对象
  • 任何具有 ID 属性的对象

  • 这是我的功能:
    function Test-PowerShell {
    [CmdletBinding(DefaultParameterSetName = "ID")]
    param (
    [Parameter(
    Mandatory = $true,
    ParameterSetName = "InputObject",
    ValueFromPipeline = $true
    )]
    [PSTypeName('MyType')]
    $InputObject,

    [Parameter(
    Mandatory = $true,
    ParameterSetName = 'ID',
    ValueFromPipelineByPropertyName = $true
    )]
    [int]
    $ID
    )

    process {
    if ($InputObject) {
    $objects = $InputObject
    Write-Verbose 'InputObject binding'
    }
    else {
    $objects = Get-MyType -ID $ID
    Write-Verbose 'ID binding'
    }

    # Do something with $objects
    }
    }

    我可以像这样使用这个功能:
    $obj = [PSCustomObject]@{
    PSTypeName = 'MyType'
    ID = 5
    Name = 'Bob'
    }
    $obj | Test-PowerShell -Verbose

    请注意,此对象同时满足上述两个条件:它是 MyType,并且具有 ID 属性。在这种情况下,PowerShell 始终绑定(bind)到 ID 属性。这在性能方面并不理想,因为管道对象被丢弃,我必须使用 ID 重新查询它。我的问题是这样的:

    如果可能,如何强制 PowerShell 将管道绑定(bind)到 $InputObject?

    如果我将默认参数集更改为 InputObject,PowerShell 将绑定(bind)到 $InputObject。但是,我不希望这样,因为当不带参数运行时,我希望 PowerShell 提示输入 ID,而不是 InputObject。

    最佳答案

    简单的答案:删除 Mandatory Parameter 的参数$InputObject 上的属性获得您想要的功能。我对参数绑定(bind)的工作原理没有足够的知识来解释为什么会这样。

    function Test-PowerShell {
    [CmdletBinding(DefaultParameterSetName = 'ID')]
    param(
    [Parameter(ParameterSetName = 'InputObject', ValueFromPipeline)]
    [PSTypeName('MyType')]
    $InputObject,

    [Parameter(ParameterSetName = 'ID', Mandatory, ValueFromPipelineByPropertyName)]
    [int]
    $ID
    )

    process {
    $PSBoundParameters
    }
    }

    $o = [pscustomobject]@{
    PSTypeName = 'MyType'
    ID = 6
    Name = 'Bob'
    }


    PS> $o | Test-PowerShell

    Key Value
    --- -----
    InputObject MyType


    PS> [pscustomobject]@{ID = 6} | Test-PowerShell

    Key Value
    --- -----
    ID 6

    下面的想法和实验。

    这是您的问题的解决方法(定义您自己的类型):
    Add-Type -TypeDefinition @'
    public class MyType
    {
    public int ID { get; set; }
    public string Name { get; set; }
    }
    '@

    然后您将参数标记为 [MyType] ,创建对象,就像您从 [pscustomobject] :
    [MyType]@{ ID = 6; Name = 'Bob' }

    事后看来,这种方法是行不通的。您遇到的是 DefaultParameterSet 的行为。 .我建议更改您作为管道输入的内容。与仅使用 Test-PowerShell -ID 5 的用户相比,是否有将 ID 作为管道输入的用例?或 Test-PowerShell并被提示输入 ID?

    以下是我的测试中可能会如您所愿的建议:
    function Test-PowerShell {
    [CmdletBinding(DefaultParameterSetName = 'ID')]
    param(
    [Parameter(ParameterSetName = 'InputObject', Mandatory = $true, ValueFromPipeline = $true)]
    [PSTypeName('MyType')]
    $InputObject,

    [Parameter(ParameterSetName = 'ID', Mandatory = $true, ValueFromPipeline = $true)]
    [int]
    $ID
    )

    process {
    $PSBoundParameters
    }
    }

    以现有的内置 cmdlet 为例,它们不会对多个参数使用对象上的相同名称或属性。在 Get-ChildItem , LiteralPathPath采用管道输入,但 LiteralPath仅按 PropertyName LiteralPath 获取或 PSPath (别名)。 Path是 ByValue 和 PropertyName,但仅作为 Path .

    关于PowerShell 管道参数绑定(bind)顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54935147/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com