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).
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
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: AD, AD cmdlets, Active Directory, Examples, KB, Knowledge Base, Known Issues, PowerGUI, PowerShell