Why we write as $_. why not simply $_

Hi Gents,

I’m a beginner to Powershell world. I understand $_ represents the objects piped in to the pipeline. But why there is ‘.’ after '$’ For example why we need to write Get-Service | Where-Object {$.status -eq ‘running’} why not ‘Get-Service | Where-Object {$_status -eq ‘running’}’ ?? Expecting a brief explanation. Thanks.

To put it simply, that’s just how you access object properties in PowerShell -

`$_` (and `$PSItem`, which can be used interchangeably) are a way to access the pipeline object.

When accessing properties, you use dot-notation (e.g. `$Object.PropertyName`) to do so.

`$` is just a variable name, the same as `$Object`, so you use `$.PropertyName` to access the properties.

The thing to bear in mind there is that if you access `$_status`, you’re actually accessing the variable named “_status” which (probably) doesn’t exist.

I would look at it like this:

$spooler = Get-Service -Name spooler

Why do you write $spooler.Status to get the status of the spooler service, and not $spoolerstatus?

Well, simple answer is ,

This is how the language is designed

$_ is the current element in the pipeline and to use the members of each of them, we use dot(cherry picking). This is how the whole world of Dot net is nad PowerShell is build on top of .net. And $_Status is considered as a variable by the parser as it starts with $ and continues till a space/line break/= etc… by following criteria for a variable name.

$_status = 'somevalue'
$_CompanyName = 'company1'

Maybe someone has a more academic explanation.
But it’s from what I can tell from the coding languages I’ve tested the common way to state which value you want from an object.
Remember sometimes it’s not just one layer, you could have multiple/nested values in an object.
So you would still need something to delimit which value you want further down.

E.g. $_.ValueX.ValueY


powershell is a object oriented shell , it’s not text oriented like unix shells.

Every cmdlet outputs objects ,use get-member to inspect cmdlets output :

get-service | get-member


<p style=“padding-left: 30px;”></p>


I was taught in this way. Might be easy to remember for you.

Whenever you use any cmdlet, it produces a table inside the memory. For example, Get-Service will create a table which contains a collection of service objects and its properties. Now $_ represent the entire table header. So if you use $, POSH will understand that you are trying to use/call the entire table. But, if you want to call a particular column from that table, you have to use $.column name (Ex. $_.Status). (. dot) used for mentioning a column. Without this POSH will not understand.

Hope it’ll help.



I did a blog post 3 years back with the same info, thanks for reminding it.


Thanks Guys. I’m good now!