gpt4 book ai didi

Powershell 动态添加成员

转载 作者:行者123 更新时间:2023-12-05 00:50:56 25 4
gpt4 key购买 nike

长话短说 - 似乎不可能在 ScriptProperty 中获得一个管道值来解析为纯文本,所以我正在寻找一种方法来做到这一点,或者在我以某种方式参数化时'正在向对象添加属性。我很乐意将这些值添加为 NotePropertyMembers 而不是 ScriptProperty;但是如果不多次循环整个对象,我就找不到这样做的方法。 ScriptProperty 的优点是能够使用 $this 变量,因此我不需要在每个成员上调用 Add-Member对象本身。

以下是我正在努力实现的目标以及失败的示例。

# This sample file contains the values that I'm interested in
@'
ID,CATEGORY,AVERAGE,MEDIAN,MIN,MAX
100,"",52,50,10,100
100,1,40,40,20,60
100,2,41,35,15,85
'@ > values.csv

# To access the values, I decided to create a HashTable
$map = @{}
(Import-Csv values.csv).ForEach({$map[$_.ID + $_.CATEGORY] = $_})

# This is my original object. In reality, it has several additional columns of data - but it is
# missing the above values which is why I want to pull them in
@'
ID,CATEGORY
100,""
100,1
100,2
'@ > object.csv

$object = Import-Csv object.csv

# This is the meat of my attempt. Loop through all of the properties in the HashTable that
# I need to pull into my object and add them
$map.Values | Get-Member -MemberType NoteProperty | Where-Object {$_.Name -NotIn 'ID', 'CATEGORY'} | ForEach-Object {$object | Add-Member -MemberType ScriptProperty -Name "$($_.Name)" -Value {$map[$this.ID + $this.CATEGORY]."$($_.Name)"}}

理论上,我知道它可以工作,因为我可以使用下面的代码显示对象的特定成员的值

$map.Values | Get-Member -MemberType NoteProperty | Where-Object {$_.Name -NotIn 'ID', 'CATEGORY'} | ForEach-Object {"$($_.Name) = " + $map[$object[0].ID + $object[0].CATEGORY]."$($_.Name)"}

展示

AVERAGE = 52
MAX = 100
MEDIAN = 50
MIN = 10

但是 - 很明显 $_.Name"$($_.Name)" 在它们位于ScriptProperty

PS> $object | GM -MemberType ScriptProperty

# Displays
TypeName: System.Management.Automation.PSCustomObject

Name MemberType Definition
---- ---------- ----------
AVERAGE ScriptProperty System.Object AVERAGE {get=$map[$this.ID + $this.CATEGORY]."$($_.Name)";}
MAX ScriptProperty System.Object MAX {get=$map[$this.ID + $this.CATEGORY]."$($_.Name)";}
MEDIAN ScriptProperty System.Object MEDIAN {get=$map[$this.ID + $this.CATEGORY]."$($_.Name)";}
MIN ScriptProperty System.Object MIN {get=$map[$this.ID + $this.CATEGORY]."$($_.Name)";}

对我来说,一个明显的解决方法是单独添加每一列,这仍然允许我在对象本身而不是每个单独的成员上使用 Add-Member。但是,整个想法是能够在不提前知道它们的名称的情况下动态添加值 - 为此,我需要找到一种方法来强制在 ScriptProperty 中解析名称>

# Workaround for this incredibly simple example
PS> $object | Add-Member -MemberType ScriptProperty -Name AVERAGE -Value {$map[$this.ID + $this.CATEGORY]."AVERAGE"}
PS> $object | Add-Member -MemberType ScriptProperty -Name MEDIAN -Value {$map[$this.ID + $this.CATEGORY]."MEDIAN"}
PS> $object | Add-Member -MemberType ScriptProperty -Name MIN -Value {$map[$this.ID + $this.CATEGORY]."MIN"}
PS> $object | Add-Member -MemberType ScriptProperty -Name MAX -Value {$map[$this.ID + $this.CATEGORY]."MAX"}

PS> $object | GM -MemberType ScriptProperty

# Displays

TypeName: System.Management.Automation.PSCustomObject

Name MemberType Definition
---- ---------- ----------
AVERAGE ScriptProperty System.Object AVERAGE {get=$map[$this.ID + $this.CATEGORY]."AVERAGE";}
MAX ScriptProperty System.Object MAX {get=$map[$this.ID + $this.CATEGORY]."MAX";}
MEDIAN ScriptProperty System.Object MEDIAN {get=$map[$this.ID + $this.CATEGORY]."MEDIAN";}
MIN ScriptProperty System.Object MIN {get=$map[$this.ID + $this.CATEGORY]."MIN";}

最佳答案

补充有用的answer from Mathias它会创建新对象,以下是动态更新对象本身的方法:

$exclude = 'ID', 'CATEGORY'
$map = @{}
$properties = $values[0].PSObject.Properties.Name | Where-Object { $_ -notin $exclude }
$values.ForEach{ $map[$_.ID + $_.CATEGORY] = $_ | Select-Object $properties }

foreach($line in $object) {
$newValues = $map[$line.ID + $line.CATEGORY]
foreach($property in $properties) {
$line.PSObject.Properties.Add(
[psnoteproperty]::new($property, $newValues.$property)
)
}
}

以上代码假定 Csv($values$object)都加载到内存中,并且您知道 $values 中的哪些属性> 应排除 CSV。

关于Powershell 动态添加成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73502701/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com