@MikeSchinkel's answer is almost correct for Powershell 5.1 (which is realistically what most machines have on them, PS7 is not useful if it's not installed), but it fails in a specific edge-case:
Powershell will coerce the result of the if expression into $null if it is an empty collection.
For example,
$test = $(if($true) {@()})
$test.GetType()
fails with You cannot call a method on a null-valued expression.
The correct trick is to use the aggressively-ugly powershell unary-comma operator.
$test = $(if($true) {,@()})
$test.GetType()
So, the full example code:
$trueValue = "foo","bar","baz","quux"
$falseValue = @()
($false, $true) | foreach-object {
$condition = $_
# meat is here
$result = $(If ($condition) {,$trueValue} Else {,$falseValue})
Write-Host "Length of result where condition is '$_': $($result.Count)"
}
yields
Length of result where condition is 'False': 0
Length of result where condition is 'True': 4
This appears to work for all possible cases of $trueValue and $falseValue, where they're an array, an object, or $null.
Same applies to switch-statements-as-expressions.
for($i = 0; $i -lt 7; $i++) {
# meat is here
$result = $(switch ($i) {
0 {,$null}
1 {,"example test"}
2 {,@()}
3 {,@('foo','bar','baz')}
4 {,@{}}
5 {,@{One=1; Two=2; Three=3}}
6 {,[Collections.ArrayList]::new()}
default {,"default"}
})
$resultDesc = if($result -eq $null) {
'$null'
} elseif($result -is [Collections.IEnumerable]) {
#note: measure-object for hashtables always returns count of 1
"[$($result.GetType())] with $(($result | measure-object).Count) members: $result"
} else {
"[$($result.GetType())]: $result"
}
"$i = $resultDesc"
}
yields
0 = $null
1 = [string] with 1 members: example test
2 = [System.Object[]] with 0 members:
3 = [System.Object[]] with 3 members: foo bar baz
4 = [hashtable] with 1 members: System.Collections.Hashtable
5 = [hashtable] with 1 members: System.Collections.Hashtable
6 = [System.Collections.ArrayList] with 0 members:
So, the general rule:
if and switch can be used for expressions! It's great! But, you have to wrap them in $() and prepend all return values with , to prevent weird edge-cases in Powershell's "helpful" language.