Why is this strange behavior with the addition of built-in types in Powershell happening?

Considering this:

$x = new-object psobject $x | add-member noteproperty test 'xtest' $x.test $x | add-member noteproperty test2 'xtest2' $x.test2 

The result is what I expect:

 xtest xtest2 

But with this in mind:

 $y = @{} $y | add-member noteproperty test 'ytest' $y.test $y | add-member noteproperty test2 'ytest2' $y.test2 

I just 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 conclusion. Running through get-members confirms that the methods are not actually added.

What's going on here? It should be something dumb at my end, but I don't see it.

+4
source share
2 answers

IIRC is really connected with PSObject wrappers, which is a key element of the extended type system in PowerShell 2.0. When you do this:

 $x = new-object psobject $x | add-member noteproperty test 'xtest' $x.test 

This works because the object is already a PSOject, so the Add-Member can add a new NoteProperty directly to PSObject, for example:

 $y = @{} $y | add-member noteproperty test 'ytest' $y.test 

This does not work because $y not initially wrapped, so when you execute the Add-Member, it creates a new object that wraps the original hash table. You can see this using Get-Member, for example:

 $y | Get-Member 

You will not see your test property. To make this work in v2, you must do this:

 $y = $y | add-member noteproperty test ytest -passthru $y.test ytest 

FYI, this changes in V3, since it is based on DLR, it directly modifies the object without creating a new wrapper object, for example:

 # PowerShell V3 only 16# $y = @{} 17# Add-Member -InputObject $y test ytest 18# $y.test ytest 
+3
source

This is because the power shell is unpacking your empty list. If you want to add a property to the list, use the inputobject paramater parameter

 add-member -input $y noteproperty test1 'ytest1' 

the use described in the question will add an item to each 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 an array that is direct iterable. To get the semantics of OP, to do what I said, you will need to do the following

 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} 
0
source

Source: https://habr.com/ru/post/1403986/


All Articles