当我的powershell cmdlet参数接受ValueFromPipelineByPropertyName并且我有别名时,如何获取原始属性名称?

时间:2017-08-11 16:52:40

标签: powershell pipeline

函数如何判断参数是作为别名传入,还是管道属性中的对象被匹配为别名?如何获得原始名称?

假设我的Powershell cmdlet接受管道输入,并且我想使用ValueFromPipelineByPropertyName。我有一个别名设置,因为我可能会得到一些不同类型的对象,我希望能够根据我收到的内容做一些略有不同的事情。

这不起作用

function Test-DogOrCitizenOrComputer
{
    [CmdletBinding()]
    Param
    (
        # Way Overloaded Example
        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [Alias("Country", "Manufacturer")] 
        [string]$DogBreed,

        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=1)]
        [string]$Name

    )
    # For debugging purposes, since the debugger clobbers stuff
    $foo = $MyInvocation
    $bar = $PSBoundParameters

    # This always matches.
    if ($MyInvocation.BoundParameters.ContainsKey('DogBreed')) {
        "Greetings, $Name, you are a good dog, you cute little $DogBreed"
    }
    # These never do.
    if ($MyInvocation.BoundParameters.ContainsKey('Country')) {
        "Greetings, $Name, proud citizen of $Country"
    }
    if ($MyInvocation.BoundParameters.ContainsKey('Manufacturer')) {
        "Greetings, $Name, future ruler of earth, created by $Manufacturer"
    }

}

执行它,我们看到问题

起初,它似乎有效:

PS> Test-DogOrCitizenOrComputer -Name Keith -DogBreed Basset
Greetings, Keith, you are a good dog, you cute little Basset

当我们尝试Alias

时,问题就很明显了
PS> Test-DogOrCitizenOrComputer -Name Calculon -Manufacturer HP
Greetings, Calculon, you are a good dog, you cute little HP

奖金失败,不通过管道工作:

PS> New-Object PSObject -Property @{'Name'='Fred'; 'Country'='USA'} | Test-DogOrCitizenOrComputer
Greetings, Fred, you are a good dog, you cute little USA

PS> New-Object PSObject -Property @{'Name'='HAL'; 'Manufacturer'='IBM'} | Test-DogOrCitizenOrComputer
Greetings, HAL, you are a good dog, you cute little IBM

$ MyInvocation.BoundParameters和$ PSBoundParameters都包含已定义的参数名称,而不包含任何匹配的别名。我没有看到通过别名获得参数真实名称的方法。

PowerShell似乎不仅仅是“有帮助”而且#39;通过别名静默地按压参数到正确的参数给用户,但它也是“有用的”#39;通过将所有别名输入折叠到主参数名称来给程序员。没关系,但是我无法弄清楚如何确定传递给Cmdlet的实际原始参数(或通过管道传入的对象属性)

函数如何判断参数是作为别名传入,还是管道属性中的对象被匹配为别名?如何获得原始名称?

1 个答案:

答案 0 :(得分:4)

我不认为功能有任何方法可以知道是否使用了别名,但关键是它不重要。在函数内部,您应始终将参数引用为它所使用的主要名称。

如果您需要使用参数来执行不同的操作,具体取决于它是否使用了Alias不是Alias的Alias,您应该使用不同的参数,或者使用第二个充当开关的参数。

顺便说一下,如果你因为要将多个参数用作ValueFromPipelineByPropertyName而执行此操作,那么您已经可以使用单个参数,并且不需要使用别名来实现此目的。

对于每个不同的输入类型,通过Value接受来自管道的值确实是唯一的(例如,只有一个字符串可以是值,一个是逐个值等)。但是可以为每个参数启用按名称接受管道(因为每个参数名称都是唯一的)。