3

I have six .txt files in a directory. So, I create a variable thus:

$foo = gci -Name *.txt

$foo is now an array of six strings. In my case I have

PS > $foo
Extensions.txt
find.txt
found_nots.txt
output.txt
proteins.txt
text_files.txt

PS > $foo.gettype()
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

PS > $foo.Count
6

I'd like to measure that object, so I pass it to Measure-Object:

PS > $foo | Measure-Object

Count    : 6
Average  :
Sum      :
Maximum  :
Minimum  :
Property :

That's what I was expecting. However, I might also pass $foo like this:

PS> Measure-Object -InputObject $foo

Count    : 1
Average  :
Sum      :
Maximum  :
Minimum  :
Property :

That's not what I was expecting. What's going on here?

5
  • Just a note: $foo is not an array of strings. It is an array of FileSystemInfos. Try $foo[0].getTYpe() Commented Aug 28, 2013 at 18:06
  • I'm definitely getting strings. $foo = gci -Name *.txt followed by $foo[0].gettype().Name gives String Commented Aug 28, 2013 at 18:15
  • However, If I do $foo = gci -Filter *.txt instead then $foo[0].gettype().Name gives FileInfo Commented Aug 28, 2013 at 18:17
  • The above were on PowerShell 2, in case its different in other versions. Commented Aug 28, 2013 at 18:22
  • 1
    I see what is going on. -Name is a switch that tells gci to only return the name. The *.txt is actually -Path *.txt Commented Aug 28, 2013 at 18:30

2 Answers 2

8

When you execute:

$foo | measure-object

PowerShell automatically unrolls collections/arrays and passes each element down the pipeline to the next stage.

When you execute:

measure-object -inputobject $foo

The cmdlet does not internally unroll the collection. This is often times helpful if you want to inspect the collection without having PowerShell do its automatic unrolling. BTW the same thing applies to Get-Member. If you want to see the members on the "collection" instead of each individual element do this:

get-member -inputobject $foo

One way to simulate this in the pipeline case is:

,$foo | Get-Member

This will wrap whatever foo is (collection in this case) in another collection with one element. When PowerShell automatically unrolls that to send elements down the pipeline, the only element is $foo which gets sent down the pipeline.

1
  • Thank you. I didn't know about this since I'm still rather wet behind the ears regarding PowerShell. I've now read the documentation via get-help about_pipelines and the relevant part of the text is "When you pipe multiple objects to a command, Windows PowerShell sends the objects to the command one at a time. When you use a command parameter, the objects are sent as a single array object." Commented Aug 28, 2013 at 18:13
0

PowerShell may be able to help you out here. Let's take a look at Get-Help Measure-Object -full and check out that parameter.

-InputObject <psobject>
    Specifies the objects to be measured. Enter a variable that contains 
    the objects, or type a command or expression that gets the objects.

    Required?                    false
    Position?                    named
    Default value
    Accept pipeline input?       true (ByValue)
    Accept wildcard characters?  false

Pipeline input is accepted by value, so that means that it counts each line of $foo and tallies them. For what it is worth, all of the example usages on Technet and in the Get-Help reference use pipeline input for this parameter.

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.