如何在 PowerShell 中向自定义对象动态添加新属性

YEM*_*slf 7 powershell

我有一个自定义对象,其中包含看起来像这样的设备信息。

name,model,sn
PC1,Elitebook 850, ABC123,
PC2,EliteDesk 600,123ABC
Run Code Online (Sandbox Code Playgroud)

我有一个功能可以检索防病毒产品检测到的威胁。它们作为对象数组返回。有比下面更多的属性,但这只是一个例子

file,md5
bad.exe,adfdfdfd
evil.exe,fdfdffdf
Run Code Online (Sandbox Code Playgroud)

我想将每个成员作为属性添加到自定义对象中,因此最终输出与此类似。

name,model,sn,01_file,01_md5,02_file,02_md5
Run Code Online (Sandbox Code Playgroud)

目前,我的脚本执行以下操作:

foreach($device in $devices){
    $threats = Get-Threats $device
    [pscustomobject] @{
        name = $device.device_name
        make = $device.make
        sn = $device.sn
        ThreatFileName = $threats.File -join ", "
        Threat_md5 = $threats.md5 -join ", "
    }
}
Run Code Online (Sandbox Code Playgroud)

这可以正常工作,但我真的希望“Get-Threats”函数返回的每个对象都作为其自己的一组属性列出。我需要动态生成这个,因为我不知道每个设备会返回多少威胁。

关于如何解决这个问题的任何想法?

小智 10

您可以随时使用Add-Membercmdlet向对象添加属性。也许从一个空对象开始,循环遍历 Get-Threats 返回的元素,每次添加一个成员?

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/add-member?view=powershell-6

编辑:示例代码以供参考。

$o = [pscustomobject]@{
    MemberA='aaa'
    MemberB='bbb'
    MemberC='ccc'
    MemberD='ddd'
}

"Before"
$o | ft

$o | Add-Member -MemberType NoteProperty -Name 'MemberE' -Value 'eee'
$o | Add-Member -MemberType NoteProperty -Name 'MemberF' -Value 'fff'

"After"
$o | ft
Run Code Online (Sandbox Code Playgroud)

  • 我没有自己发布答案...只是添加了一个示例,我必须@krome 回答。 (2认同)

YEM*_*slf 3

@krome 的答案为我指明了正确的方向,尽管这个答案对我来说不起作用,因为每个设备可能存在多种威胁。

我使用了 @scobi 在动态获取 PSCustomObject 属性和值上的答案来得到这个答案,它满足我动态生成新属性的要求。

foreach($device in $devices){
    $threats = Get-Threats $device
    if($null -ne $threats){
        $i = 1
        foreach($threat in $threats){
            $threat | Get-Member -MemberType NoteProperty | % Name | %{                
                Add-Member -InputObject $device -NotePropertyName ("Threat"+$i.ToString() + "_" + $_) -NotePropertyValue $threat.$_ -Force            
            }
            $i++
        }
    }
}
Write-Output $devices
Run Code Online (Sandbox Code Playgroud)
  • 我循环遍历devices数组中的每个设备并调用我的 Get-Threats函数。
  • if语句可防止循环在任何没有威胁的设备上运行。
  • $i用作我的计数器,以增加发现的每个威胁的属性名称,以便所有属性都具有唯一的名称
  • 然后,我循环遍历发现的每个威胁,以Get-Member检索属性名称和值
  • device我使用 Add-Member 为循环中发现的每个威胁添加附加属性,并使用计数器为每个属性赋予唯一的名称