带有值表达式的 Powershell Add-Member

标签 powershell calculated-property

尝试将新成员添加到 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-ObjectSort-Object Group-ObjectCompare-ObjectFormat-* 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/

相关文章:

regex - Powershell正则表达式以匹配特定的文本顺序,并且仅将它们包括在结果中

windows - 如何在 Powershell 和 nano 下保存 git commit 消息? (Ctrl+O 无效)

powershell - 如何在 PowerShell 中跨列添加数字?

PowerShell单行内存使用量巨大

c# - 从另一个应用程序添加/启动/停止 IoT Core 应用程序