Cmdlet通过管道一次传递参数列表,而不是单个列表项

时间:2015-02-04 11:05:21

标签: c# powershell pipeline cmdlet pscmdlet

我正在创建一个Powershell System.Management.AutomationCmdlet.Cmdlet,用于通过管道将字符串列表传递给Cmdlet:

  [Cmdlet(VerbsCommon.Add, "Signature")]
  public class AddSignature : Cmdlet
...
    [Parameter(Position = 0, ValueFromPipeline = true)]
    public List<string> Items { get; set; }
...

现在,在重载的“ProcessRecord”方法中,我一次只获得一个项目Items.Count == 1 3次(而不是一次性通过管道获取完整的List)。

'item1','item2','item3' | Add-Signature

是否有可能立即传递整个项目列表(由Get-ChildItem返回)?我一次只能得到一件物品。

基本上我希望使用管道具有相同的行为,就好像我使用这样的命令(Items.Count == 3

Add-Signature -Items "item1","item2","item3"

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我一直想知道同样的事情,虽然我的重点是直接从Powershell使用它,而不是在C#中。我认为会有一些属性或官方方式来做到这一点。

我见过的术语是 stall ,如“拖延管道”或有时缓冲区。有两个官方cmdlet,我可以想到这样做:Sort-Object停止,因为它需要所有对象才能对它们进行排序。 Format-Table -Autosize停顿,因为它需要所有对象才能弄清楚如何调整列的大小。

我在Powershell中提出了这个解决方法:

function Stall-Pipeline {
[CmdletBinding()]
param(
    [Parameter(
        ValueFromPipeline
    )]
    [String]
    $Msg
)

    Begin {
        Write-Verbose "Begin"
        $all = @()
    }

    Process {
        Write-Verbose "Process"
        $all += $Msg
    }

    End {
        Write-Verbose "End"
        foreach($item in $all) {
            # processing 
            $item # processed item
        }
    }
}

基本上我使用begin块来初始化一个包含所有结果的变量。 process块添加到该变量,然后end块执行所有实际处理并将项目发送到管道。

您可以使用-Verbose调用此方法,以查看何时调用每个块。

如果有更好的方式,更正式或更受支持的方式,我很想知道那是什么。