PowerShell ForEach / Piping confusion PowerShell ForEach / Piping confusion powershell powershell

PowerShell ForEach / Piping confusion


This is indeed confusing. For now a work-around is to grab the items like so:

$items = @(Get-TfsItemHistory . -r -Stopafter 25 |            Foreach {$_.WorkItems.Count > $null; $_})

This accesses the WorkItems collection which seems to cause this property to be populated (I know - WTF?). I tend to use @() to generate an array in cases where I want to use the foreach keyword. The thing with the foreach keyword is that it will iterate a scalar value including $null. So the if the query returns nothing, $items gets assigned $null and the foreach will iterate the loop once with $item set to null. Now PowerShell generally deals with nulls very nicely. However if you hand that value back to the .NET Framework, it usually isn't as forgiving. The @() will guarantee an array with with either 0, 1 or N elements in it. If it is 0 then the foreach loop will not execute its body at all.

BTW your last approach - foreach ($item in $items) { ... } - should work just fine.