简体   繁体   中英

How does pipeline and $_ work in PowerShell?

  1. Get-Process|Get-Member $_ , why doesn't this work? If $_ represents current object in pipeline, shouldn't the above output be returning members of each process object?
  2. Will a cmdlet pipeline all its output objects at once to the next cmdlet or as and when there is an object available?
  3. As #1 does not work, when exactly can I use $_ variable? The conditions under which this variable gets created will be more helpful rather than just a cmdlet example to demonstrate the use of $_ .

$_ is an automatic variable that is available for use within the scriptblock input of certain cmdlets to represent the current item in the pipeline.

Get-Process | Get-Member $_ Get-Process | Get-Member $_ doesn't work because you send the pipeline object in to Get-Member via the | , but you then don't have any way to access the internals of Get-Member .

You could do this:

Get-Process | ForEach-Object {
    $_ | Get-Member
}

You would then get a Get-Member output for every item in the collection of objects output by Get-Process , although this would be redundant as each would be the same.

Cmdlets do send the objects down the pipeline one at a time. You can see that with this example:

Get-Process | ForEach-Object {
   $_
   Start-Sleep 1
}

You can see with the added delay that the results are arriving in the ForEach-Object one at a time as soon as they are available.

Other places you can use the $_ variable are in Where-Object and Select-Object . For example:

Get-Process | Where-Object { $_.name -like 'win*' }

Here the Where-Object cmdlet is taking each item of the pipeline and we're using $_ to access the name property of that item to see if it's like the string win . If it is, then it gets sent onwards (and so comes out to the console) if it's not, Where-Object discards it.

You can use $_ in a Select-Object when doing calculated properties. For example:

Get-Process | Select-Object name,@{N='WorkingSetGB';E={$_.WorkingSet / 1GB}}

Here we use $_ to get at the WorkingSet property of each item and then convert it to a GB value by using / 1GB .

Yes, $_ represents the current object in the pipeline but since Get-Member takes a pipeline input you just have to pipe the result to the cmdlet:

Get-Process | Get-Member

Another example is

Get-Process | Export-Csv MyFile.csv

Here again, $_ is not needed, because Export-Csv takes pipeline input, and receives the output of Get-Process, one process at a time, through the pipeline. There is a loop inside the implementation of Export-csv, but that need not concern you here.

You typically use $_ when you pipe an object to the ForEach-Object cmdlet:

Get-Process | ForEach-Object {
    Write-Host $_.Name
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM