11

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)

5 Answers 5

28

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
Sign up to request clarification or add additional context in comments.

3 Comments

Perfect, who would have thought that .count wouldn't be very good at counting! Thanks for your help
You're welcome Will, keep exploring. The more you play with PowerShell the more fun it gets :)
This resolved the same issue for me. Anyone have any resources as to why ().count returns 0 in some cases. NVM, the result blow says it all ha ha
8

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

2 Comments

This is a little unrelated question but I 'd like to ask you one. Is count a function or method or property? When listed via get-member, there is no count in the list.
@SmartHumanism - Good question. The $var | get-member returns the member of the items in the array so that's not what you want. I know that the [System.Array] type has a count property but I have no idea how to make that visible through Get-Member.
6

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.

Comments

1

I find that if I declare the array as an empty array and then add items to it (+=)instead of assigning a result to it the count works.

$servers = @()

$Servers += Get-ADComputer -Server $domain -Filter {samaccountname -eq 'OneServer01$'} `
  -SearchBase $serverOU -SearchScope Subtree  | Select Name, DistinguishedName

$Servers.Count will now display as 1 where simply using = does not display anything at all as is seen as a PSCustomObject and not a collection.

1 Comment

Welcome to SO, and thanks for answering. However, please put code in code boxes and not in normal text.
-1
([object[]]$var).Count


@( ([psobject] $null), (New-Object psobject), (1..2 | % {New-Object psobject}) ) `
| % {"$( $_.Count ) : $( ([object[]]$_).Count )"}

3 Comments

Welcome to Stack Overflow. Code is a lot more helpful when it is accompanied by an explanation. Stack Overflow is about learning, not providing snippets to blindly copy and paste. Please edit your question and explain how it answers the specific question being asked. Please take the tour and see How to Answer.
Also, some decend formatting and indentation would improve the readability.
@Chris & @LaurenzAlbe. @WillRyan wrote that it doesn't work $var.count. The answer is one line of code ([object[]]$var).Count. It doesn't require decend formatting and indentation. The rest of the evil one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.