首页 > 解决方案 > Powershell函数从管道接收多个参数

问题描述

我正在编写如下函数:

Function Display-ItemLocation {
   Param(
      [ Parameter ( 
         Mandatory   = $True,
         Valuefrompipeline = $True ) ]
         [ String ]$stringItem,
      [ Parameter ( 
         Mandatory   = $False,
         Valuefrompipeline = $True ) ]
         [ String ]$stringLocation = 'unknown' 
   )
     Echo "The location of item $stringItem is $stringLocation."
}

Display-ItemLocation 'Illudium Q-36 Explosive Space Modulator' 'Mars'
Display-ItemLocation 'Plumbus'

它像书面一样工作正常。

The location of item Illudium Q-36 Explosive Space Modulator is Mars.
The location of item Plumbus is unknown.

我希望能够预加载一个包含多个数据对的数组,并通过管道将其发送到函数中。

$Data = @(
           @('Bucket','Aisle 1'),
           @('Spinach Pie','Freezer 4')
         )
$Data | Display-ItemLocation

我找不到让它工作的神奇语法。该函数可以同时接受来自管道的一对值吗?

标签: powershellparameter-passingpipeline

解决方案


将您的管道绑定参数定义为按属性名称绑定-ValuefromPipelineByPropertyName然后通过管道(自定义)具有此类属性的对象

Function Display-ItemLocation {
   Param(
      [ Parameter ( 
         Mandatory,
         ValuefromPipelineByPropertyName ) ]
         [ String ]$stringItem,
      [ Parameter ( 
         Mandatory = $False,
         ValuefromPipelineByPropertyName ) ]
         [ String ]$stringLocation = 'unknown' 
   )
   
   process { # !! You need a `process` block to process *all* input objects.
     Echo "The location of item $stringItem is $stringLocation."
   }

}

顺便说一句:Display不是PowerShell 中批准的动词

现在您可以按如下方式通过管道传递给该函数;请注意,属性名称必须与参数名称匹配:

$Data = [pscustomobject] @{ stringItem = 'Bucket'; stringLocation = 'Aisle 1' },
        [pscustomobject] @{ stringItem = 'Spinach Pie'; stringLocation = 'Freezer 4' }

$Data | Display-ItemLocation

以上产生:

The location of item Bucket is Aisle 1.
The location of item Spinach Pie is Freezer 4.

  • 以上使用[pscustomobject]实例,很容易构建即席。

    • 请注意,哈希表(例如,just @{ stringItem = 'Bucket'; stringLocation = 'Aisle 1' }不起作用-尽管此 GitHub 问题正在讨论更改。
  • 在 PSv5+ 中,您也可以定义一个自定义class

# Define the class.
class Product {
  [string] $stringItem
  [string] $stringLocation
  Product([object[]] $itemAndLocation) { 
    $this.stringItem = $itemAndLocation[0]
    $this.stringLocation = $itemAndLocation[1]
  }
}

# Same output as above.
[Product[]] (
  ('Bucket', 'Aisle 1'), 
  ('Spinach Pie', 'Freezer 4')
) | Display-ItemLocation

推荐阅读