【问题标题】:Get value from pipeline with ValueFromPipelineByPropertyName使用 ValueFromPipelineByPropertyName 从管道中获取值
【发布时间】:2018-07-25 11:30:28
【问题描述】:

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

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

Get-Data :输入对象不能绑定到命令的任何参数 要么是因为该命令不接受管道输入,要么是因为输入及其 属性与任何接受管道输入的参数都不匹配。 在行:1 字符:33 + 获取输入-计算机名 PC-01 |获取数据 + ~~~~~~~~ + 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

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

【问题讨论】:

  • 我会敦促你做进一步的调试;您可能会发现从您的函数返回到 Get-Member 的管道对象将具有教育意义。
  • 你的 Get-Input 函数没有做任何事情 - 它接受一个字符串参数并输出相同的字符串 - 结果字符串将没有 ComputerName 属性

标签: powershell pipeline


【解决方案1】:

正如名称 (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

【讨论】:

  • 感谢您的详细解释和示例!
【解决方案2】:

你还必须写 ValueFromPipeline=$true:

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

问候 詹尼克

【讨论】:

    【解决方案3】:

    你需要这个芽。

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

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

    【讨论】:

    • ValueFromPipelineByPropertyName 是布尔值”是什么意思?
    • 我很抱歉,不仅仅是布尔值,而是值。他的$ComputerName 需要有一个值,例如$ComputerName.Name.
    猜你喜欢
    • 2018-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 2017-09-16
    相关资源
    最近更新 更多