我正在创建一个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"
有什么想法吗?
答案 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
调用此方法,以查看何时调用每个块。
如果有更好的方式,更正式或更受支持的方式,我很想知道那是什么。