Search code examples
powershellwindows-server-2012-r2powershell-5.0

Powershell evaluating against each member of collection rather than collection


I have the following code:

$a = gci .\Areas -Recurse
($a[0].EnumerateFileSystemInfos()).Count

This is its output

PS C:\> ($a[0].EnumerateFileSystemInfos()).Count
1
1
1
1
1
1

Why? When I run gm -InputObject $a[0], I clearly see that a collection is returned.

EnumerateFileSystemInfos  Method         System.Collections.Generic.IEnumerable[System.IO.FileSystemInfo] EnumerateF...

Why is it evaluating .Count against each member of the collection rather than the collection itself? Also worth noting is that

($a[0].EnumerateFileSystemInfos()).Count()

returns an error:

Method invocation failed because [System.IO.FileInfo] does not contain a method named 'Count'.
At line:1 char:1
+ ($a[0].EnumerateFileSystemInfos()).Count()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

Which is what I would expect if I were calling it against $a[0][0] but I'm not. What's going on and how can I retrieve the number of items in the collection?


Solution

  • EnumerateFileSystemInfos() returns an IEnumerable, more precisely, a System.IO.FileSystemEnumerableIterator'1, thus each query to it returns a single object. And when you're piping the output to Out-Default, that cmdlet checks if the IEnumerable has more data, if yes, queries it again. That's why you get a sequence of 1's, because each object behind an enumerable is a single object and not an array.

    You should instead use GetFileSystemInfos() to get your proper count, it returns an array.