[英]Powershell piping multiple PSCustomObjects drops all but first object
I'm making some modules to make RESTAPI calls easier for our software (since all resources use different logic to how I can find them and how they should be called but that's a separate story).我正在制作一些模块以使我们的软件更容易调用 RESTAPI(因为所有资源都使用不同的逻辑来找到它们以及应该如何调用它们,但这是一个单独的故事)。 I'm making Get-, Set-, New-, and Remove- for each resource and just found that you can't pipe more than one object to modules that takes arrays from the pipeline.
我正在为每个资源制作 Get-、Set-、New- 和 Remove-,只是发现您不能将 pipe 超过一个 object 到从管道中获取 arrays 的模块。 Here's an illustration of the problem that you can copy-paste into your environment:
这是您可以复制粘贴到您的环境中的问题的说明:
function Get-MyTest {
param(
[string[]]$MyInput
)
[array]$Output = @()
$i=0
foreach($Item in $MyInput){
$i++
$Output += [pscustomobject]@{
Name = $Item
Id = $i
}
}
return $Output
}
function Get-IncorrectResults {
param(
[parameter(ValueFromPipeline)][array]$MyIncorrectInput
)
foreach ($Item in $MyIncorrectInput) {
Write-Host "Current object: $Item `n "
}
}
The Get module can return more than one object. Get 模块可以返回多个 object。 Each object returned is a
PSCustomObject
, so if there are more than one returned it becomes an array of PSCustomObjects
.返回的每个 object 都是一个
PSCustomObject
,因此如果返回的不止一个,它将成为一个PSCustomObjects
数组。 Here's the problem:这是问题所在:
This works:这有效:
$Results = Get-MyTest -MyInput "Test1","Test2","Test3"
Get-IncorrectResults -MyIncorrectInput $Results
This only returns the first item:这仅返回第一项:
$Results = Get-MyTest -MyInput "Test1","Test2","Test3"
$Results | Get-IncorrectResults
If the Get part returns more than one object, only the first object is passed on to the Remove-MyModule
.如果 Get 部分返回多个 object,则仅将第一个 object 传递给
Remove-MyModule
。 I tried changing the parameter definition from [pscustomobject[]]
to [array]
but it's the same result.我尝试将参数定义从
[pscustomobject[]]
更改为[array]
但结果相同。 What is the reason for dropping all but the first array item when piping but not when using it as a parameter?在管道时删除除第一个数组项之外的所有项的原因是什么,但在将其用作参数时却没有?
The structure of an advanced PowerShell function is as follows:高级PowerShell function的结构如下:
function Function-Name {
param(
<# parameter definitions go here#>
)
begin {
<# this runs once when the pipeline starts #>
}
process {
<# this runs once for every input item piped to the function #>
}
end {
<# this runs once at the end of the pipeline #>
}
}
When you omit the begin
/ process
/ end
blocks, PowerShell assumes your function body is really the end
block - so this function definition:当您省略
begin
/ process
/ end
块时,PowerShell 假定您的 function 主体确实是end
块 - 所以这个 function 定义:
function Function-Name {
param()
Do-Something
}
... is the exact same as: ...与以下内容完全相同:
function Function-Name {
param()
begin {}
process {}
end {Do-Something}
}
Notice that the process
block - the only piece of the function body that repeats with new input - is assumed empty, and the Do-Something
statement will not be executed until after the last input item has been received.请注意,
process
块 - function 主体中唯一与新输入重复的部分 - 假定为空,并且在收到最后一个输入项之前不会执行Do-Something
语句。
This is why it looks like it "drops" everything but the last input object.这就是为什么它看起来“丢弃”除了最后一个输入 object 之外的所有内容。
Place the code that consumes the pipeline-bound variable inside the process
block and it'll work:将使用管道绑定变量的代码放在
process
块中,它将起作用:
Remove-MyModule{
param(
[parameter(ValueFromPipeline)][pscustomobject[]]$MyModules
)
process {
foreach($Module in $MyModules){
Invoke-RestMethod -Method Delete -Uri "MyURL" -Body (ConvertTo-Json $Module) -UseDefaultCredentials
}
}
}
For more information about the syntax and semantics of advanced functions, see the about_Functions_Advanced_Methods
help file有关高级函数的语法和语义的更多信息,请参阅
about_Functions_Advanced_Methods
帮助文件
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.