使用ValueFromPipelineByPropertyName

时间:2018-07-25 11:30:28

标签: powershell pipeline

我在使用ValueFromPipelineByPropertyName从管道中获取价值时遇到一些问题。

当我运行Get-Input -ComputerName 'PC-01' | Get-Data时,cmdlet Get-Input应该只返回计算机名称“ PC-01”,而Get-Data函数应返回“从Get-Input传递的值:PC- 01“。相反,我收到此错误:

Get-Data : The input object cannot be bound to any parameters for the command
either because the command does not take pipeline input or the input and its
properties do not match any of the parameters that take pipeline input.
At line:1 char:33
+ Get-Input -ComputerName PC-01 | Get-Data
+                                 ~~~~~~~~
    + CategoryInfo          : InvalidArgument: (PC-01:PSObject) [Get-Data], ParameterBindingException
    + FullyQualifiedErrorId : InputObjectNotBound,Get-Data

我已经构建了这两个小示例cmdlet,只是为了摆脱使用管道的麻烦。

function Get-Input {
    [CmdletBinding()]
    Param(
        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true
        )]
        [string]$ComputerName
    )

    Process {
        Write-Output -InputObject $ComputerName
    }
}

function Get-Data {
    [CmdletBinding()]
    Param(
        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true
        )]
        [string]$ComputerName
    )

    Process {
        Write-Output -InputObject "Value passed from Get-Input: $($ComputerName)."
    }
}

如果我将$ComputerName更改为$Name并运行以下命令,它将起作用:

PS C:\Users\frede> Get-Service -Name AdobeARMservice | Get-Data
Value passed from Get-Input: AdobeARMservice.

如果我掌握了PowerShell中管道的概念,则应该能够运行以下命令Get-Input -ComputerName 'PC-01' | Get-Data,并将ComputerName传递给Get-Data

我需要在某处声明什么吗?

3 个答案:

答案 0 :(得分:2)

正如名称(ValueFromPipelineByPropertyName所示,您要告诉解析器绑定基于属性名称的值。

Get-Input函数将需要输出一个名为ComputerName的具有属性的对象,以使其正常工作:

function Get-Input
{
    [CmdletBinding()]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true
        )]
        [string]$ComputerName
    )

    process
    {
        Write-Output $(New-Object psobject -Propert @{ComputerName = $ComputerName})
    }
}

现在您可以这样做:

Get-Input -ComputerName 'PC-01' |Get-Data

如果您希望Get-Data支持从Get-Service输入的计算机名称,则必须在Get-Service输出的对象类型上添加一个与适当的属性名称匹配的别名,即。 MachineName

function Get-Data
{
    [CmdletBinding()]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true
        )]
        [Alias('MachineName')]
        [string]$ComputerName
    )

    process
    {
        Write-Output -InputObject "Value passed from Get-Input: $($ComputerName)."
    }
}

现在这两个都可以工作:

Get-Service -Name AdobeARMService |Get-Data
Get-Input -ComputerName PC-01 |Get-Data

答案 1 :(得分:0)

您还必须编写ValueFromPipeline = $ true:

 Mandatory = $true,
 ValueFromPipeline=$true,
 ValueFromPipelineByPropertyName = $true

问候 詹尼克

答案 2 :(得分:0)

您将需要这个芽。

ValueFromPipelineByPropertyName用于布尔值($ True / $ False),并且不在寻找您的字符串。

[CmdletBinding()]
param
(
    [Parameter(
        Mandatory = $true,
        ValueFromPipeline = $true
    )]
    [string]$ComputerName
)