1

In Powershell, a pipeline can contain filters such as ForEach-Object:

get-process | %{$_.name}

Within the script block of the foreach filter, it's possible to use the $_ auto variable to refer to the current object of the script block.

What does the $_ variable bind to when used at the top level of the pipeline? For example, the following doesn't work:

"common" | get-verb -group $_

I would have thought that it was bound to the resulting object from the previous section of the pipeline -- in the above case, to the "common" string.

I've been looking online for info about how this $_ is bound, but haven't found that type of info. Virtually all examples that I see use $_ within script blocks.

For example, this doesn't answer this question: What does $_ mean in PowerShell?

mklement0
  • 382,024
  • 64
  • 607
  • 775
Dess
  • 2,064
  • 19
  • 35
  • 1
    I'm failing to understand your question, `$_` will only be bound in the context of a scriptblock, more specifically when involving pipelines, in the `process` block of a scriptblock. In other context __does not mean anything__ – Santiago Squarzon Dec 04 '22 at 19:19
  • 2
    There is no "resulting object" in your pipeline -- in a pipeline, even a single object is packaged as an enumerable. Per Santiago, `$_` has no meaning outside script blocks -- attempts to assign to it are ignored and attempts to get its value are either ignored or result in an error (if `Set-StrictMode` is on). – Jeroen Mostert Dec 04 '22 at 19:41
  • @JeroenMostert assigning to it is possible, tho not recommended, since the variable will hold no value after enumerated: `$_ = 'hello'; $_`... this happens to all automatic variables afaik – Santiago Squarzon Dec 04 '22 at 20:09
  • 1
    @SantiagoSquarzon: yes -- I suppose assigning to the value *within* a script block is technically possible, though it makes for inscrutable scripting. Outside of it, however, assigning does nothing since it can't be retrieved (i.e. `$_ += 1` is legal within a script block, but a bad idea; outside it is illegal if strict mode is on). (The above all assumes PowerShell 6+, incidentally.) – Jeroen Mostert Dec 04 '22 at 20:18
  • Dess, it's a good point that the official description of the [automatic `$_` variable](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Automatic_Variables#_) is woefully lacking, as of this writing. I've added a bottom section to the linked duplicate that tries to provide a systematic overview of all contexts in which `$_` and its alias `$PSItem` are meaningfully defined, and I've [opened an issue](https://github.com/MicrosoftDocs/PowerShell-Docs/issues/9521) to get the docs amended based on that information. – mklement0 Dec 04 '22 at 21:36

1 Answers1

1

$_ is only valid inside scriptblocks. Note that -group is a powershell 7 only parameter. You can do something like this, but you have to specify something for the verb:

'comm' | get-verb -group { $_ + 'on' } -verb *


Verb     AliasPrefix Group  Description
----     ----------- -----  -----------
Add      a           Common Adds a resource to a container, or attaches an item to another item
Clear    cl          Common Removes all the resources from a container but does not delete the container
Close    cs          Common Changes the state of a resource to make it inaccessible, unavailable, or unusable
...
js2010
  • 23,033
  • 6
  • 64
  • 66
  • 1
    I would add that passing `{…}` as an argument of a pipeline command is called a [_delay-bind_ script block](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_script_blocks?view=powershell-7.2#using-delay-bind-script-blocks-with-parameters). It is only possible for parameters that accept _pipeline input_. This is stated in the [documentation of the parameter](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-verb?view=powershell-7.3#-group). – zett42 Dec 04 '22 at 19:59