Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell .count function not working as expected

Tags:

powershell

I'm trying to get a list of all scheduled tasks on a server within a certian path that don't have a LastTaskResult of '0'. Just displaying all failures.

Simple bit of code I thought but it's not returning as expected, my code is:

$var = Get-ScheduledTask | Get-ScheduledTaskInfo | select * | where {$_.TaskPath -eq "\"} 
$var = $var | select * | where {$_.LastTaskResult -ne 0}
$var.count

If I remove the second line I can see that there is one value returned but the count is returning nothing (not even 0)

If I run the same but using -eq then it gives me a count of 2 which is correct, anyone come across this issue before?

I've had a look around but I can;t see anything.

(Just a note, I'm very new to Powershell)

like image 600
Will Ryan Avatar asked Apr 12 '16 13:04

Will Ryan


3 Answers

You are correct, Count is not always reliable for every situation. Especially not in the older versions of PowerShell.

Please use the following CmdLet:

$var | Measure-Object

This can be enhanced to:

if (($var | Measure-Object).Count -ne 0) {
    'We found stuff'
}

More information on this CmdLet can be found when typing:

Get-Help Measure-Command -ShowWindow

As in the answer of @Lieven, you can also force your result to be an Array:

@($var).count
$var = @(Get-Process | Select-Object -First 0); $var.count
like image 150
DarkLite1 Avatar answered Sep 23 '22 20:09

DarkLite1


When the pipe is returning a single result, $var becomes a PSCustomObject. A PSCustomObject doesn't have a count. When it's returning multiple results, you get an array of PSCustomObjects and you can use a count.

You can use GetType() to determine the resulting type like this

($var | select * | where {$_.LastTaskResult -ne 0}).GetType()

Now the easiest solution I know of to resolve this is by explicitly setting the type of the variable as such

$var = Get-ScheduledTask | Get-ScheduledTaskInfo | select * | where {$_.TaskPath -eq "\"} 
[PSCustomObject[]]$var = $var | select * | where {$_.LastTaskResult -ne 0}
$var.count
like image 34
Lieven Keersmaekers Avatar answered Sep 22 '22 20:09

Lieven Keersmaekers


If you strongly type your variable in advance you can avoid this.

PS C:> [array]$var = @()

PS C:> $var = Get-ScheduledTask | Get-ScheduledTaskInfo | select * | where {$_.TaskPath -eq "\"}

PS C:> $var = $var | select * | where {$_.LastTaskResult -ne 0}

PS C:> $var.count

1

This will ensure that $var is always an array and won't get changed by PS.

like image 35
Richard Avatar answered Sep 24 '22 20:09

Richard