Home > Enterprise >  dynamically creating key/value of an object and exporting to CSV
dynamically creating key/value of an object and exporting to CSV

Time:12-09

After getting a search result from an LDAP Server, i need to create a pscustomobject dynamically.

The Problem here is that some of the attributes are not set for all users.

this is why i cannot create the pscustomobject the traditional way.

Name = $($item.Attributes['givenname'].GetValues('string'))
Surname = $($item.Attributes['sn'].GetValues('string'))

The Attribute Name does not exist for all users and doing this throws an error.

How can i create the pscustomobject in this case where i need to add both key and value dynamically.

Here is what i have so far:

$vals="cn","tel","email","sn","givenname","ou"
$c.Bind()
$r = New-Object System.DirectoryServices.Protocols.SearchRequest -ArgumentList  $baseDN,$Filter,$scope,$attrlist
$re = $c.SendRequest($r)

foreach ($item in $re.Entries) {

    foreach($attr in $vals){
   
        if($item.Attributes.Keys -contains $attr){
       
        $pskeys  = $attr
    }}

    foreach($pskey in $pskeys){
    
        $data  = [pscustomobject]@{
        $($pskey) = $($item.Attributes[$pskey].GetValues('string'))
    }}

    $pskeys = @()
}

givenname does not exist for all the users and this is why the pscustombject must be created dynamically.

I cannot use a HashTable or some kind of a List as duplicate values must be allowed. There are cases where the attributes sn and givenname are equal.

After hours of trying and failing i can only hope for the Wizards of Stackoverflow to show me how this can be achieved.

I need a pscustomobject where i can save the available attributes and skip the missing attributes dynamically. Is there a way to do this?

Regards

CodePudding user response:

Try following :

$table = [System.Collections.ArrayList]::new()
foreach ($item in $re.Entries) {
    $newRow = New-Object -TypeName psobject
    foreach($attr in $vals){
   
        if($item.Attributes.Keys -contains $attr){
       
        $pskeys  = $attr
    }}

    foreach($pskey in $pskeys){
        foreach($item in $item[$pskey].Attributes.GetValues('string'))
        {
           $newRow | Add-Member -NotePropertyName $item.Name -NotePropertyValue $item.Value
        }
        
    }

    $table.Add($newRow)  | Out-Null
}
$table | Format-Table

CodePudding user response:

Finally!

I have gotten it to work!

The Trick was to enclose $pskey and $item.Attributes[$pskey].GetValues('string') in $()

Without $() Add-Member was adding the properties as Arrays and not as Strings.

Here is the working Code:

$table = New-Object System.Collections.ArrayList
$c.Bind()
$r = New-Object System.DirectoryServices.Protocols.SearchRequest -ArgumentList  $baseDN,$Filter,$scope,$attrlist
$re = $c.SendRequest($r)

foreach ($item in $re.Entries) {

    $newRow = New-Object -TypeName psobject

    foreach($attr in $vals){
   
        if($item.Attributes.Keys -contains $attr){
       
        $pskeys  = $attr
    }}

    foreach($pskey in $pskeys){
    
        $newRow | Add-Member -NotePropertyName $($pskey) -NotePropertyValue $($item.Attributes[$pskey].GetValues('string'))
        
        }

    $table.Add($newRow) | Out-Null
    $pskeys = @()   
    
    }

$table | Export-Csv -Path $ExportPath -NoTypeInformation -Encoding UTF8 -Append -Delimiter ";"

Thank You jdweng for pointing me in the right direction.

$table | Format-Table on the console and the resulting CSV after the Export look flawless now.

My Problem is solved.

  • Related