Custom Objects within an Array explanation

I read this article in Powershell online magazine and I am having a hard time getting my mind wrapped around it as to what it means.

It gives the following example code:

$groups = 'Group1', 'Group2'
$users = 'User1', 'User2'
$object = New-Object PSObject
Add-Member -InputObject $object -MemberType NoteProperty -Name Group -Value ""
Add-Member -InputObject $object -MemberType NoteProperty -Name User -Value ""
$groups | ForEach-Object {
$groupCurrent = $_
   $users | ForEach-Object {
      $userCurrent = $_
         $object.Group = $groupCurrent
         $object.User = $userCurrent
         $objectCollection += $object

It shows the output as this:

Group  User 
-----  ---- 
Group2 User2
Group2 User2
Group2 User2
Group2 User2

It then explains why we are getting this output. The is the paragraph I am having a problem understanding as well as the link to the article.

We assign the information to the object and add it to the collection, but we still use the same object. When we added it to the collection we added just a 'reference' to the object, not the object itself. What we ended up with was just four 'shortcuts' to the same object.


I don’t understand they mean by 'reference to the object and not the object itself. When you are using the using the statement,
$object.Group = $groupCurrent and $object.User = $userCurrent, are you not adding those values to that object? I don’t understand what they mean by ‘reference’.

This gets into some fairly esoteric programming concepts, specifically, ByValue and ByReference.

When you assign something ByValue, you’re passing the contents of whatever it is. So if I have $a=4, and I set $b=$a ByValue, I can then set $a=5 but $b will still be 4.

Conversely, setting something ByReference just passes a reference to, basically, the same memory location. So if $a=4 and I set $b=$a, changing $a=5 will also set $b to 5, because $a and $b are really both pointers to the same memory location.

Add-Member works that way with its -InputObject parameter. It doesn’t create a new object having whatever properties you added; it adds the property to the original copy, so whatever variable was referencing that copy ($object in this case) will now reference the updated object.

As a side note, that is an old example of creating an object in Powershell and the results that you posted are incorrect (not the intention of the code or example, I’m guessing). This should be much easier to implement and read:

$groups = 'Group1', 'Group2'
$users = 'User1', 'User2'
#Collect all results from the for loops and place them in $objectCollection
$objectCollection =  foreach ($group in $groups)  {
    foreach ($user in $users)  {
        New-Object -TypeName PSObject -Property @{
            Group = $group
            User  = $user


User  Group 
----  ----- 
User1 Group1
User2 Group1
User1 Group2
User2 Group2