tags:

views:

133

answers:

3

Apologies for what is probably a newbish question.

I am writing some Powershell scripts that run various queries against AD. They will usually return a bunch of results, which are easy to deal with, ie:

$results = myQuery
write-host "Returned " + $results.Count + " results."
foreach ($result in $results) { doSomething }

No worries. However, if there is only 1 result, Powershell automagically translates that result into a single object, rather than an array that contains 1 object. So the above code would break, both at the Count and the foreach. I'm sure the same problem would occur with 0 results.

Could someone suggest an elegant way to handle this? Perhaps some way to cast the results so they are always an array?

A: 

This has bitten me as well. No clever ideas on how to fix $results.Count, but the foreach can be fixed by switching to a pipeline.

$scalar = 1
$list = (1,2)
$list | % { $_ }

prints 1 2

$scalar | % { $_ }

prints 1

Scott Weinstein
+9  A: 

Change the first line of code to

$results = @(myQuery)

This will always return an array. See this blog entry for additional details.

Robert Harvey
You little beauty!
Neobyte
(That's Australian for "thanks!" ;) )
Neobyte
Could you tell me why it was designed like this? My colleague asked and I didn't know..
stej
The blog entry referenced above explains in some detail.
Robert Harvey
The @ means "string literal" in C#. I guess it means "array literal" here.
Robert Harvey
Pretty certain it's not Powershell - I think it's AD itself. When I do LDAP queries in VBScript, it returns an array for multiple values, a single object for a single user, and (I think) a null string for a null value.VERY annoying.Make sure you check what happens if the query matches nothing.
ChristianLinnell
+1  A: 

Actually, the foreach works just fine. All uses of foreach (the foreach keyword, the Foreach-Object cmdlet, and Foreach-Object's aliases "foreach" and "%") all have the same behavior of "wrapping" the object in question in an array if needed. Thus, all uses of foreach will work with both scalar and array values.

Annoyingly, this means they work with null values too. Say I do:

$x = $null
foreach ($y in $x) {Write-Host "Hello world 1"}
$x | Foreach-Object {Write-Host "Hello world 2"}

I'll get

"Hello world 1"
"Hello world 2"

out of that.