Inbox: Expanding Properties in PowerShell

I received a great question via e-mail about accessing the contents of a property. I'd used Select-Object -expand property in an example the reader had seen, but he wondered why another way wouldn't work. Here's why.

Don Jones

July 6, 2011

3 Min Read
ITPro Today logo in a gray background | ITPro Today

I received this in my inbox this morning:

I have been reading your blog (http://blogs.technet.com/b/heyscriptingguy/archive/2011/06/13/use-powershell-invoke-command-for-remoting.aspx) with interest, and it raised a question that I have been puzzled by for some time now.

It is about this construct designed to get just one attribute of a list of objects and process that further:

Invoke-Command -computername (Get-ADComputer -filter * | Select -expand name) -script {dir c:}

Why does the following not work the same in this context:

Invoke-Command -computername (Get-ADComputer –filter * ).name -script {dir c:}

In some case this syntax seems to perform basically the same function: to present just one property of the object(s) to the pipe, and it does work.

e.g. here:

(Get-MailboxStatistics –Identity ‘tittesu’ –IncludeMoveHistory).MoveHistory | select  *time* | fl

Or in

(get-date).second


As a quick refresher, the -expandProperty parameter of Select-Object will grab the contents of a property. In this example:

Get-ADComputer -filter * | Select -expand Name


The "Name" property of an ADComputer object contains a string, so the -expandProperty parameter produces just that string. In other words, the above command produces a bunch of computer names as simple String objects.

However, if the property you give -expandProperty is a collection, you get the objects in the collection:

Get-Job | Select -expand ChildJobs


Because the ChildJobs property of a Job object contains one or more additional Job objects, the above command would list those jobs - usually in a table format.

So why doesn't this work to do the same thing?

(Get-ADComputer –filter * ).name


Because in that case, I would expect Get-ADComputer to return multiple objects, and this syntax won't work if the parenthetical expression has multiple objects. Now, if for some reason your domain only contained one computer object, then the above syntax would work. The idea is that the "dot notation," as its called, only works with individual objects. If the parenthetical expression evaluates to a single object, the dot notation works. Thats' why this will work:

(get-date).second


It works because Get-Date only ever returns a single object. Of course, I personally find the parenthetical dot notation stuff - like the above example - to be a bit programmer-y. I tend to stick with a command-line style of syntax:

Get-Date | Select -expand second


In this case, the command-line style of syntax is longer, but it's more consistent with using the shell as a shell and not a programming language, which is what I tend to do. Also, the above syntax, using Select-Object -expandProperty, will work with one object or multiple objects, so it's a syntax that works in a broader range of situations.

Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like