Thursday, August 22, 2013

Force Powershell to always create an array

Imagine you have a file called buildLog.txt, which contains

1
2
3
22

Now, also imagine you want to find out if a line contains a specific number in this text file.

You can run a command like this:


$allWarnings = Select-String build.log.txt -Pattern "2"  | Select-Object Line,LineNumber,FileName | Sort-Object -Property Line -Unique ; if ($allWarnings.Count -gt 0) { $allWarnings | Format-List; }

This works correctly and returns:

Line       : 2
LineNumber : 2
Filename   : build.log.txt

Line       : 22
LineNumber : 4
Filename   : build.log.txt


But if you run it to check if any sentences contain a 1, something weird happens:

$allWarnings = Select-String build.log.txt -Pattern "1"  | Select-Object Line,LineNumber,FileName | Sort-Object -Property Line -Unique ; if ($allWarnings.Count -gt 0) { $allWarnings | Format-List; }

This returns no results. This is very weird and unexpected behaviour, to say the least. But the reason can be understood once you break the steps down.

In the first case, we have multiple results, which creates an array. Then we do a .Count on this array, and we get the result.
In the second case, we only have one result. This is an object, and not an array. Therefore this has no .Count property, so .Count will return null.

The fix is luckily very easy. Simply force the result to always be an array. This is done by simply adding one keyword in front.

[array]$allWarnings = Select-String build.log.txt -Pattern "1"  | Select-Object Line,LineNumber,FileName | Sort-Object -Property Line -Unique ; if ($allWarnings.Count -gt 0) { $allWarnings | Format-List; }

This now works as expected.


Line       : 1
LineNumber : 1
Filename   : build.log.txt


Success!

No comments: