How to add properties to a PowerShell object from an array

grisha picture grisha · Jan 8, 2015 · Viewed 73.6k times · Source

I have a two-dimensional array of property names and values, which I need to add to a PowerShell object.

I have NO issues creating and displaying an object like this using New-Object and Add-Member:

$obj = New-Object PSObject
$obj | Add-Member NoteProperty IName($fiel.IName)
$obj | Add-Member NoteProperty SName($fiel.SName)
$obj | Add-Member NoteProperty Taggy($fiel.Taggy)
$obj | Add-Member NoteProperty Title($fiel.Title)

Write-Output $obj

Enter image description here

But when I try something like this:

for ($k=0; $k -lt $fieldsArray.Count; $k++)
{
    $itemobj | Add-Member –MemberType NoteProperty –Name $fieldsArray[$k].InternalName –Value $itemki[$j][$fieldsArray[$k].InternalName]
    #Write-Host $k
    #Write-Host $fieldsArray[$k].InternalName.ToString()
    #Write-Host $itemki[$j][$fieldsArray[$k].InternalName]
}

Write-Output $itemobj

The Write-Output $itemobj will return only one property member that should be added without any neat column names.
The commented out parts were added for testing purposes and return correct values for all items.

I also tried

$itemobj | Add-Member NoteProperty $fieldsArray[$k].InternalName.ToString()($fieldsArray[$k].InternalName)

without any improvement.

Why are the other property members not added?

I have the data I need. If I write:

for ($k=0; $k -lt $fieldsArray.Count; $k++)
{
    Write-Host $k
    Write-Host $fieldsArray[$k].InternalName.ToString()
    Write-Host $itemki[$j][$fieldsArray[$k].InternalName]
}

I get:

0 ID 1
1 ContentTypeId 0x0108007345CD807822EA4E85691E5C642F3A27
2 ContentType
3 Title Task0
4 Modified 11/24/2014 12:29:30 PM

And these are exactly the values that I expect and want. The problem is adding them as properties to an object. I think I cannot have a variable as a NotePropertyName, but it's a wild guess based on the results I am getting.

Some of the values in $itemki[$j][$fieldsArray[$k].InternalName] are empty - could it be it?

Forget all the arrays. They were just for the context:

Write-Host $fieldsArray[$k].InternalName.ToString() # Writes out the correct value
Write-Host $itemki[$j][$fieldsArray[$k].InternalName] # writes out the correct value
$itemobj | Add-Member NoteProperty $fieldsArray[$k].InternalName.ToString()($fieldsArray[$k].InternalName) # The values/property are not added

The question is: WHY NOT? Are there any restrictions in Add-Member on passing values as variables? Empty values?

Answer

Matt picture Matt · Jan 8, 2015

I am still not sure completely, but if you are just focusing on the Add-Member then consider the following.

$fieldsarray = "ID", "ContentTypeID", "ContentType", "Title", "Modified"
$itemki = "1", "0x0108007345CD807822EA4E85691E5C642F3A27", "", "Task0", "11/24/2014 12:29:30 PM"
$itemobj = New-Object pscustomobject
for($k=0;$k -lt $fieldsArray.Count ; $k++)
{
    $itemobj | Add-Member NoteProperty $fieldsarray[$k] $itemki[$k]
}

$itemobj

Notice the empty string entry in the array $itemki. This would generate the output.

ID            : 1
ContentTypeID : 0x0108007345CD807822EA4E85691E5C642F3A27
ContentType   :
Title         : Task0
Modified      : 11/24/2014 12:29:30 PM

Change the "" to an empty element: "1","0x0108007345CD807822EA4E85691E5C642F3A27",,"Task0","11/24/2014 12:29:30 PM", and you get this output:

ID            : 1
ContentTypeID : 0x0108007345CD807822EA4E85691E5C642F3A27
ContentType   : {Task0}
Title         : 11/24/2014 12:29:30 PM
Modified      :

Which is wrong. Then if you change the empty element to $null your output looks much like the first:

ID            : 1
ContentTypeID : 0x0108007345CD807822EA4E85691E5C642F3A27
ContentType   :
Title         : Task0
Modified      : 11/24/2014 12:29:30 PM

Concerning your output

You say you only get the last element when you do $itemobj outside the loop. What does $itemobj look like after each pass? for(;;){} loops don't send data to the output stream in the same way that a ForEach-Object{} would which is worth mentioning.