尝试将新成员添加到 powershell 对象数组中,无法获取要计算的表达式。下面是一些示例代码:
$testData =
@([pscustomobject]@{Name="Cat";Legs=4},
[pscustomobject]@{Name="Parrot";Legs=2},
[pscustomobject]@{Name="Snake";Legs=0})
# this works
$testData | Select-Object Name, Legs, @{N='CopyName';E={$_.Name}}
# why doesnt this work?
$testData | Add-Member -NotePropertyName "CopyName" -NotePropertyValue $_.Name
$testData
(使用 Powershell 7)
最佳答案
this works:
$testData | Select-Object Name, Legs, @{N='CopyName';E={$_.Name}}
这是有效的,因为您使用 calculated property 来定义 CopyName
属性,以及 script block ({ ... }
)在您的 E
(Expression
) 条目中,您可以引用手边输入对象的 .Name
属性通过 automatic $_
variable 。
注意:
只有少数 cmdlet 实现了对计算属性的支持,特别是
Select-Object
、Sort-Object
、Group-Object
、Compare-Object
和Format-*
cmdlet,通过明确命名为-Property 的特定参数
(其类型为[object[]]
,或者在Measure-Object
的情况下,仅支持 PowerShell 中的计算属性(Core ) 7+、[pspropertyexpression[]]
,这些 cmdlet 在内部使用反射来确定给定值是否是属性名称>(字符串)或计算属性(哈希表/脚本 block )。相比之下,延迟绑定(bind)脚本 block 功能(见下文)是基础设施的一部分(参数绑定(bind)器),并且可能与任何参数,前提是它 (a) 声明为管道绑定(bind)并且 (b) 既不是
[object]
也不是[scriptblock]
类型 -再次,请参见下文。
顺便说一句:您不必显式枚举现有属性(Name, Legs
):您可以将它们抽象地引用为 *
,因为 wildcard expressions因为支持属性名称:
$testData |选择对象 *, @{N='CopyName';E={$_.Name}}
why doesnt this work?:
$testData | Add-Member -NotePropertyName "CopyName" -NotePropertyValue $_.Name
这不起作用,因为使用$_
来引用当前管道输入对象只能在脚本 block 内。
但是,-NotePropertyValue { $_.Name }
也不起作用:
由于
-NotePropertyValue
的参数类型为[object]
(System.Object
),{ $_ .Name }
将成为属性值按原样,作为脚本 block 。还有另一种机制(除了计算属性之外)可以动态确定参数值: delay-bind script blocks 。
但是,有两个先决条件,
Add-Member
的-NotePropertyValue
参数均无法满足这两个先决条件:目标参数必须声明为管道绑定(bind)(接受来自管道的输入)。
目标参数的类型不得为
[object]
或[scriptblock]
类型,因为您无法区分意味着按原样使用,作为脚本 block 而不是辅助。脚本 block ,其目的是计算实际值。
在
Add-Member
的情况下,-NotePropertyValue
是[object]
类型(以支持 < em>任何值)单独排除对此功能的支持。
鉴于上述情况,您必须$testData
单独中的对象调用Add-Member
,例如通过ForEach-Object
:
$testData |
ForEach-Object {
# Due to being inside the ForEach-Object script block, $_.Name
# now refers to the current input object's .Name property.
# Add -PassThru to also *output* the modified object.
Add-Member -InputObject $_ -NotePropertyName "CopyName" -NotePropertyValue $_.Name
}
关于带有值表达式的 Powershell Add-Member,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74070542/