1

When using Powershell the Add-Member function can be used for manipulation of the object tree.

Following Function should read a CSV with Customers and their corresponding domain names and build a object tree as follows :

Customer1--- some attributes
   |__ Domainname1---some attributes
   |__ Domainname2---some attributes
Customer2--- some Attribute 
   |__ Domainname3---some attributes
Customer3--- some attributes
   |__ Domainname1---some attributes
   |__ Domainname2---some attributes
   |__ Domainname3---some attributes

The CSV File is a unsorted list of customers with their domains and looks like :

Kunde,Domain
"Customer1", "DomainName1"
"Customer2", "DomainName3"
"Customer1", "DomainName2"
"Customer3", "DomainName4"

After adding the domainname3 to the customer2 the domainname3 is seen also on the customer1 object as possible child.

the result tree looks like this in the debugger :

Customer1--- some attributes
   |__ Domainname1---some attributes
   |__ Domainname2---some attributes
   |__ Domainname3---some attributes
Customer2--- some Attribute 
   |__ Domainname1---some attributes
   |__ Domainname2---some attributes
   |__ Domainname3---some attributes

How can I get the planned result ?

The powershell function :

Function ReadCustomerDomains([string]$File )
{
    $CSVData = Import-Csv  $File -Delimiter ","
    $CustomerListObject = New-Object PSObject 
    

    ForEach ($Item in $CSVData)   
    {
        if ( Get-Member -InputObject $CustomerListObject -name $($Item.Kunde) )
        {
        }
        else
        {
            $CustomerListObject | Add-Member -NotePropertyName "$($Item.Kunde)" -NotePropertyValue $Customer_Properties
        }
    }

    ForEach ($Item in $CSVData)   
    {
        $CustomerItem = $CustomerListObject.$($Item.Kunde)
        Add-Member -InputObject $CustomerItem -NotepropertyName "$($Item.Domain)"  -NotePropertyValue $Customer_Domain_Properties
        $CustomerItem =$Null 
    }
    $CustomerList += $CustomerListObject
    return  $CustomerList
}
Wolfgang
  • 11
  • 2
  • 1
    Need to see sample of csv. I like to use class objects when create trees. Do get tree structure you need to group by customer. I do not know why you have two foreach loops. – jdweng Apr 07 '23 at 08:37
  • The second loop was for isolating the problem with the Add-Member Domain Item. Is the child visibility of the domain items normal behavior in the object tree ? – Wolfgang Apr 07 '23 at 15:50

1 Answers1

0

Try following :

$filename = "c:\temp\test.csv"
$headers = 'Customer', 'Domain'
$csv = Import-Csv -Path $filename -Header $headers
$customers = $csv | Group-Object -Property 'Customer'

$table = [System.Collections.ArrayList]::new()
foreach($customer in $customers)
{
   $newRow = New-Object -TypeName psobject
   $newRow | Add-Member -NotePropertyName Customer -NotePropertyValue $customer.Name

   $domainObj = New-Object -TypeName PSObject
   foreach($domain in $customer.Group)
   {
      $attributes = [System.Collections.Generic.Dictionary[string,object]]::new()
      for($i = 0; $i -lt 4; $i++)
      {
         $attributes.Add('Attribute' + $i, $i)
      }
      $domainObj | Add-Member -NotePropertyName $domain.Domain -NotePropertyValue $attributes
   }
   $newRow | Add-Member -NotePropertyName Domains -NotePropertyValue $domainObj
   $table.Add($newRow) | Out-Null
}
$table | foreach { $_.Customer; $_.Domains | foreach {$_ | Format-List} }
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • Thank you very much for your code, this is the solution I was looking for. The only change I had to do : $Attributes = [System.Collections.Generic.Dictionary[string,object]]::new() ==> $Attributes = New-Object "System.Collections.Generic.Dictionary[string,object]" , The ::new Constructor was not working on my version of Powershell – Wolfgang Apr 11 '23 at 20:05
  • Just verify that you go first row of CSV. I wasn't sure if your CSV had a header row. Using -Headers with Import-CSV will treat the header rows as data instead of headers. – jdweng Apr 11 '23 at 21:07