Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically add new properties to custom object in PowerShell

Tags:

powershell

I have a custom object that contains device information that looks something like this.

name,model,sn
PC1,Elitebook 850, ABC123,
PC2,EliteDesk 600,123ABC

I have a function that retrieves threats detected by an antivirus product. These are returned as an array of objects. There are more properties than below but this is just an example

file,md5
bad.exe,adfdfdfd
evil.exe,fdfdffdf

I would like to add each member as properties to the custom object so the final output is similar to this.

name,model,sn,01_file,01_md5,02_file,02_md5

Currently, my script does this:

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 ", "
    }
}

This works ok but I'd really like each object returned by the 'Get-Threats' function to be listed as its own set of properties. I need this to be generated dynamically because I don't know how many threats will be returned for each device.

Any thoughts on how to go about this?

like image 633
YEMyslf Avatar asked Feb 13 '19 02:02

YEMyslf


People also ask

How do I add a property to a PowerShell object?

The Add-Member cmdlet lets you add members (properties and methods) to an instance of a PowerShell object. For instance, you can add a NoteProperty member that contains a description of the object or a ScriptMethod member that runs a script to change the object.

Can we add dynamically named properties to JavaScript object?

In JavaScript, you can choose dynamic values or variable names and object names and choose to edit the variable name in the future without accessing the array. To do, so you can create a variable and assign it a particular value.

What is PSCustomObject PowerShell?

The [pscustomobject] type accelerator was added in PowerShell 4.0. Prior to adding this type accelerator, creating an object with member properties and values was more complicated. Originally, you had to use New-Object to create the object and Add-Member to add properties. For example: PowerShell Copy.


2 Answers

You can add properties to objects at any time with the Add-Member cmdlet. Maybe start with an empty object and loop through the elements returned by Get-Threats, adding a member each time?

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

Edit: Example code to answer for reference.

$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
like image 68
elkromer Avatar answered Oct 14 '22 13:10

elkromer


The answer from @krome got me pointed in the right direction although that answer wouldn't work for me as there could be multiple threats for each device.

I used the answer from @scobi on Dynamically get PSCustomObject property and values to arrive at this answer which meets my requirement that the new properties be generated dynamically.

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
  • I loop over each device in the devices array and call my Get-Threats function.
  • The if statement prevents the loop from running for any devices that don't have threats.
  • $i is used as my counter to increment the property name for each threat found so the properties will all have unique names
  • I then loop over each threat found piping to Get-Member to retrieve the property name and values
  • I use Add-Member to add additional properties for each threat found to each device in the loop, using the counter to give each propery a unique name
like image 42
YEMyslf Avatar answered Oct 14 '22 15:10

YEMyslf