Select-Object vs Add-Member

Let me be clear on this one: Select is bad, Add-Member is good. 😉

OK, OK, this is not a one-size-fits-all answer, and there are plenty of scenarios in which Select-Object is useful, but in a lot of cases it is being misused. The most frequent one, when someone tries to use Select-Object or Format-Table to add a new attribute to the displayed objects. In that particular scenario these two cmdlets basically create one-time-use disposable objects for a quick output, while Add-Member adds an additional property and preserves the original objects for subsequent use.

A quick example, let’s say you want to see the Primary Group for your AD users. Primary group can be calculated by merging account domain SID and primary group ID so you probably end up with something like:

$PrimaryGroup = Get-QADGroup $($user.Sid.AccountDomainSid)-$($user.PrimaryGroupId)

Now, to add a column to the user output you could use Select-Object or Format-Table and supply the additional value using a hash-table parameter:

Get-QADUser | Select Name, @{Name=PrimaryGroup;Expression={(Get-QADGroup $($_.Sid.AccountDomainSid)-$($_.PrimaryGroupId)).Name}}

Get-QADUser | Format-Table Name, @{Label=PrimaryGroup;Expression={(Get-QADGroup $($_.Sid.AccountDomainSid)-$($_.PrimaryGroupId)).Name}}

(Note a small gotcha by the way: the column name is Name for Select-Object but Label for Format-Table ;))

However, both of these operations have a very important side effect – they kill the original objects and create new disposable ones instead. The collection you get is basically just a formatting thing which you can no longer use in other operations (e.g. pipe to yet another cmdlet).

Select-Object cmdlet changing the object type and losing all other properties

Select-Object cmdlet changing the object type and losing all other properties

For example if I use the Select code above in a PowerGUI script node I will indeed get the output in the grid, however, if you pay close attention (click the image to see the detail) you will see that I cannot add any other columns to the grid (and see for example users’ phone numbers), and the Actions pane to your right is empty – the usual actions for user objects are not there. 😦

Enter Add-Member. This cmdlet is a complete opposite to Select and Format-* – it adds a new member to the objects while preserving all other properties and the object type.

So if instead of the code above we use something like:

Get-QADUser | Add-Member -Name PrimaryGroup -Value {(Get-QADGroup $($this.Sid.AccountDomainSid)-$($this.PrimaryGroupId)).Name} -MemberType ScriptProperty -Force -PassThru

Add-Member adds a new property to PowerShell objects while preserving everything else

Add-Member adds a new property to PowerShell objects while preserving everything else

We get a nice set of objects with all user properties there and the new one added. As a result, inside PowerGUI admin console you see this new column, but can still add any other columns and perform any usual actions – check out the right-hand pane!

Tags: , , , , , , , ,


7 Responses to “Select-Object vs Add-Member”

  1. 1 Richard Siddaway August 27, 2008 at 12:53 pm

    Select is bad, Add-Member is good – to my mind they fulfil two different roles.

    Add-Member is when you want to do further processing as you show

    Select & calculated field when only want to display.

    Lots of times I only want to display so use select or format

    Good example of using Add-Member though

  2. 2 dmitrysotnikov August 27, 2008 at 1:09 pm

    * Select is a quick and dirty way to get the values.
    * Add-Member if you want the thing to be further re-usable.

    The problem is that today most examples in the blogs/forums/etc. use Select, and people start looking at it as a universal solution, which it is not.

  3. 3 halr9000 August 27, 2008 at 6:21 pm

    I’m a huge proponent of the bad form of Select-Object. 🙂 As such let me say that every time I use it, it’s because I either do not care what the original object was, or I actively did not want the original object.

    Even in cases when I _should_ do a script using add-member, I will usually shy away from doing so. Why? I find the steps required to create a custom object very tedious and lacking in clarity of the written code.

    This is why I submitted a connect feature suggestion to MSFT to ask them to make the creation of a custom object with a large set of properties easier to do by expanding the syntax of add-member and/or new-object.

    Please check out the suggestion here and vote for it if you agree, or leave comments there to ensure that MSFT sees the discussion.

  4. 4 halr9000 August 29, 2008 at 8:20 pm

    I guess my reply from a few days ago got lost in the ether. I’m a big proponent of using Select-Object to construct synthetic objects. I understand your point, however in my own usage it is much more common that I don’t need or don’t want the rest of an original object. In many cases, there *was* no original object. In these cases, Add-Member provides the exact same end result as Select-Object.

    Even outside of these cases, I find the Add-Member cmdlet very awkward to the point that I created a Connect bug to address usability issues.

  5. 5 Dmitry Sotnikov August 31, 2008 at 1:05 pm

    Found and despammed your comment. Will go and vote for the submission at the connect site (which I hope others will do as well) – this cmdlet is indeed very hard to use.

  6. 6 December 30, 2011 at 2:43 pm

    Thanks for the post. I am trying to learn to think “on the next level” and this kind of writing helps me get my head around some different ways of looking at my scripts. I added on Twitter that a series of posts exploring the various ways in which Add-Member could be used would be very helpful to those still learning the language like myself.

  1. 1 Episode 40 - Poshboard part duex « PowerScripting Podcast Trackback on September 8, 2008 at 3:12 am

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

My Recent Tweets


The posts on this blog are provided “as is” with no warranties and confer no rights. The opinions expressed on this site are mine and mine alone, and do not necessarily represent those of my employer - WSO2 or anyone else for that matter. All trademarks acknowledged.

© 2007-2014 Dmitry Sotnikov

August 2008

%d bloggers like this: