PowerShell for Windows Admins

Jan 12 2017   10:48AM GMT

Using $_

Richard Siddaway Richard Siddaway Profile: Richard Siddaway


The $_ symbol seems to be causing confusion from some recent forum questions I’ve seen.

$_ represents the current object on the pipeline – if you want to know why $_ was chosen you’ll have to read PowerShell in Action!

You can use $_ in a number of situations – in commands that perform an action on every object (or selected objects) on the pipeline. Here’s some of the commoner usages:

In the early versions of PowerShell you used it in the filter script of Where-Object

Get-Process | Where-Object -FilterScript {$_.CPU -gt 50}

This is more usually written as

Get-Process | Where {$_.CPU -gt 50}

As of PowerShell v3 if you are filtering on ONE property you can simplify the syntax

Get-Process | Where CPU -gt 50

which is a truncated version of

Get-Process | Where -Property CPU -gt -Value 50

When you write it like this its obvious what is happening. Get in the habit of thinking of the syntax in this manner even if you write in the shortened form

If you need to filter on TWO or more properties you have to use the old style syntax

Get-Process | Where {$_.CPU -gt 50 -AND $_.Handles -gt 1000}

In all of these cases you’re comparing a property of the current pipeline object against a value. If the comparison is true the object is passed onto the next step of the pipeline. If its false the object is discarded.

You can use $psitem in place of $_ if you prefer

Get-Process | Where {$psitem.CPU -gt 50}

In the Foreach-Object cmdlet you can use $_ to refer to the current object

Get-CimInstance -ClassName Win32_NetworkAdapter -Filter "NetEnabled = $true" |
ForEach-Object {
$ip = Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter "Index = $($_.DeviceId)"
$props = @{
Name = $_.NetConnectionId
Product = $_.ProductName
DHCP = $ip.DHCPEnabled
IP   = $ip.IPAddress
New-Object -TypeName PSObject -Property $props

$psitem also works in this situation

The third common usage of $_ is in select-object in calculated fields (you can do the same in Format-Table)

Get-CimInstance -ClassName Win32_LOgicalDisk -Filter "DriveType=3" |
select DeviceId, VolumeName,
@{N='Size(GB)'; E={[math]::Round($_.Size / 1GB, 2)}},
@{N='Used(GB)'; E={[math]::Round(($_.Size - $_.FreeSpace) / 1GB, 2)}},
@{N='Free(%)'; E={[math]::Round(($_.FreeSpace / $_.Size) * 100, 2 )}}

In this example we’re changing the size to GB from bytes and calculating the used space and the % free space. Again you could use $psitem instead of $_


This fails

$nics = Get-CimInstance -ClassName Win32_NetworkAdapter -Filter "NetEnabled = $true"
$data = foreach ($nic in $nics) {
$ip = Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter "Index = $($_.DeviceId)"
$props = @{
Name = $_.NetConnectionId
Product = $_.ProductName
DHCP = $ip.DHCPEnabled
IP   = $ip.IPAddress
New-Object -TypeName PSObject -Property $props
$data |Format-List

To recap $_ (or $psitem) is used to represent the current object on the pipeline. You can us it in commands that are performing an action on every object on the pipeline.

 Comment on this Post

There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when other members comment.

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

Share this item with your network: