Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Consider the following Powershell script, which searches for folders in C:\ with a 'og' in their name:

PS C:\> (ls | %{$_.Name} | ?{$_.Contains("og")})
Program Files

Now I narrow down the search to get only one item:

PS C:\> (ls | %{$_.Name} | ?{$_.Contains("Prog")})
Program Files

The strange thing is that the first operation yields an array, whereas the second operation (which is IMHO semantically the same operation, so it should yield the same type of result) yields a string. This can be seen in the following result:

PS C:\> (ls | %{$_.Name} | ?{$_.Contains("og")}).Length
PS C:\> (ls | %{$_.Name} | ?{$_.Contains("Prog")}).Length

This can be very irritating, since apparently there are less folders which match 'og' than those who match 'Prog'.

Evidently, PowerShell implicitly 'unboxes' a single-item array to a single object, and we never get an array of length 1. It seems that every time I want to count the results coming over the pipeline, I have to check if I'm dealing with an array or not.

How can I prevent this from happening? How do you deal with this?

share|improve this question
These from StackOverflow may help:…… If you were not piping to $_.Contains, then %{,,$_.Name} works... – Bob Apr 20 '12 at 8:59
up vote 32 down vote accepted

Evidently, PowerShell implicitly 'unboxes' a single-item array to a single object,

And zero item results to $null.

How can I prevent this from happening?

You can't.

How do you deal with this?

Use the array constructor (@(...)) to force a collection (possibly with zero or one elements) return:

$res = @(ls | %{$_.Name} | ?{$_.Contains("Prog")})
share|improve this answer
Thank you, this is perfect! I'll upvote as soon as I have 15 reputation. – cheeesus Apr 20 '12 at 11:23

This has been resolved in PowerShell v3:

On a side note, you can find if a name contains something using a wildcard:

PS> ls *og*
share|improve this answer
Shay, I cannot comment on answers yet, but your statement is not true. PowerShell still boxes elements, but they have, as you noted, given single items a "Count" value. Single item results are still unboxed, though. You can test the above example against PS 3 and see the results. – Tohuw Jul 17 '13 at 12:15
The behaviour is still the same in PS 5. – MEMark May 4 at 7:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .