Reputation: 14548
Given this:
$x = new-object psobject
$x | add-member noteproperty test 'xtest'
$x.test
$x | add-member noteproperty test2 'xtest2'
$x.test2
The output is what I'd expect:
xtest
xtest2
But given this:
$y = @{}
$y | add-member noteproperty test 'ytest'
$y.test
$y | add-member noteproperty test2 'ytest2'
$y.test2
I simply get:
ytest2
I'm confused. And if I do this:
$y = @{}
$y | add-member noteproperty test 'ytest'
$y | add-member noteproperty test2 'ytest2'
$y.test
$y.test2
Then there is no output at all. Running through get-members confirms that the methods are not actually being added.
What's going on here? This has to be something dumb on my end, but I can't see it.
Upvotes: 4
Views: 284
Reputation: 201652
IIRC this really has to do with PSObject wrappers which is a key piece of the extended type system in PowerShell 2.0. When you execute this:
$x = new-object psobject
$x | add-member noteproperty test 'xtest'
$x.test
It works because the object is already a PSOject so the Add-Member can add the new NoteProperty directly to the PSObject e.g.:
$y = @{}
$y | add-member noteproperty test 'ytest'
$y.test
This doesn't work because $y
isn't initially wrapped so when you execute Add-Member, it creates a new object that wraps the original hashtable. You can see this by using Get-Member e.g.:
$y | Get-Member
You won't see your test
property. To get this to work in v2, you have to do this:
$y = $y | add-member noteproperty test ytest -passthru
$y.test
ytest
FYI, this changes in V3 since it is based on the DLR it modifies the object directly without creating a new wrapper object e.g.:
# PowerShell V3 only
16# $y = @{}
17# Add-Member -InputObject $y test ytest
18# $y.test
ytest
Upvotes: 3
Reputation: 25495
This is due to power shell unrolling your list which is empty. If you want to add a property to the list use the inputobject paramater
add-member -input $y noteproperty test1 'ytest1'
the usage you described in the question would add a member to every item in the list which you can see in this example
C:(...)SequenceId>$y = @()
C:(...)SequenceId>$y += New-Object -t psobject
C:(...)SequenceId>$y += New-Object -t psobject
C:(...)SequenceId>$Y | Add-Member -type noteproperty -name hi -value you
C:(...)SequenceId>$Y
hi
--
you
you
@Joey raised this issue that I used a array which is directly iterable. To get the OP semantic to do what I said you would have to do the folowing
C:(...)SequenceId>$y = @{}
C:(...)SequenceId>$y["one"] = New-Object -t psobject
C:(...)SequenceId>$y["two"] = New-Object -t psobject
C:(...)SequenceId>$Y | Add-Member -type noteproperty -name hi -value you
C:(...)SequenceId>$y
Name Value
---- -----
two
one
C:(...)SequenceId>$Y.values | Add-Member -type noteproperty -name hi -value you
C:(...)SequenceId>$y
Name Value
---- -----
two @{hi=you}
one @{hi=you}
Upvotes: 0