Author Posts

January 1, 2012 at 12:00 am

by nohandle at 2012-11-05 01:24:06

Hi,
user on Powershell com forum asked why is the original object modified when using select -property and -expandProperty . At first I thought there must be an error in the source code but I rewrote it and was able to replicate the issue. I was trying to figure it out, but it seems like a bug to me (I cannot find anyone mentioning it or reporting it on Microsoft Connect.)

Is there any explanation for that behavior or should I report it?

Here is an example:
$hash = @{category="Users";objects=""}
$category = New-Object psobject -Property $hash

Function Create-UserObject ([string]$userName)
{
New-object psObject -Property @{name=$userName}
}
$category.objects= (create-userObject "john"),(create-userObject "jane")
cls
"`n:::original Object:::"
$category | fc

$category | Select-Object -Property "WhyOhWhy" -ExpandProperty objects > $null
"`n:::modified object:::"
($category.objects[0]).whyOhWhy = "this works"
$category | fc

($category.objects[0]).nonExistingProperty = "this will produce error"

:::original Object:::

class PSCustomObject
{
objects =
[
class PSCustomObject
{
name = john
}
class PSCustomObject
{
name = jane
}
]

category = Users
}

:::modified object:::

class PSCustomObject
{
objects =
[
class PSCustomObject
{
name = john
WhyOhWhy = this works
}
class PSCustomObject
{
name = jane
WhyOhWhy =
}
]

category = Users
}

Exception setting "nonExistingProperty": "Property 'nonExistingProperty' cannot be found o
n this object; make sure it exists and is settable."
At line:19 char:1
+ ($category.objects[0]).nonExistingProperty = "this will produce error"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : ExceptionWhenSetting

by DonJ at 2012-11-05 12:10:41

I'm not entirely sure I'm following what you're after. But, let me try.

By design, Select-Object won't barf if you ask it to select a property which doesn't exist. This can be confusing, but it's intentional, and not a bug. Select-Object will implicitly create the "missing" property. That's why, after Selecting the property, you can subsequently access it. That's what Select-Object does.

However, that behavior doesn't extend globally throughout the shell – it's a behavior of Select-Object (and Where-Object, and a couple of others). When you try to do $object.BadProperty, you get an error because PowerShell looks for a Get method on $object, doesn't find one, and barfs. Again, that's expected behavior.

So it isn't a bug, but it's darned confusing. I get this all the time when I teach classes:

Get-Process | Select -Property Nmae,ID,PM,VM

Notice the typo in Name? Select won't complain – it just creates a blank column called "Nmae." Confusing. But, once you realize what's happening, it's less likely to trip you up.

by nohandle at 2012-11-05 13:36:40

Hi Don thanks for the reply. I am aware of the standard behavior of the Select-Object cmdlet.
The problem is that in this case the collection of custom objects is add a property and the change is not just output to pipeline, the original object is modified.

If I have object $user that has property name and surname and I do Select name, surname, telephone the output is psobject that has all these three properties. If the output is not captured (assigned to property for example) it is lost. the $user still has only two properties (name, surname).

In the described case I have custom (parent) object. one of its properties is a collection of custom objects. if the parent object is pipelined to select, and both property (name, surname, telephone) and expandproperty ($collection.objects) are specified then the not existing property "telephone" is STORED to the collection in the parent object.