Difference Between $_ and $PSItem in Windows PowerShell

Difference Between $_ and $PSItem in Windows PowerShell
In this video, I’m going to answer a very common question that I get when I’m teaching Windows PowerShell, and that’s, “What’s the difference between what’s called $_ and $PSItem?” Let me explain to you a little bit about what these two variables do.
When we’re working with the PowerShell pipeline, and we want to reference whatever object is currently moving through the pipeline, we need a way of doing this. There’s two automatic variables that we can utilize, $_ or $PSItem. Let me show you.
I’m going to run this command. All it’s going to do is grab three objects, representing each one of the drives on this particular machine. What I’m going to do is I want to reference just the device ID property. You can see over here, the device ID property is simply going to be my drive letters when we’ve finished.
What I’m going to do is, first, do it with $_. You can see I’m taking my original command. I’m piping it before each object, and I’m referencing the current object in the PowerShell pipeline ‑‑ and that is how we say it ‑‑ then we’re going to reference its device ID property.
Let me run this one first. You can see all we get are the drive letters. Now I’m going to run this again, but this time I’m going to replace $_ with $PSItem. That’s the only difference in this code. We get the exact same thing. Let’s discover why. I’m going to go ahead and open up the help file about automatic variables.
In this help file, if I scroll down a little bit, here’s the reference to $_. Right there, it’s telling you it’s the same as $PSItem. It contains the current object in the PowerShell pipeline. Let’s take a look at $PSItem. Let’s jump down here. Look, $PSItem, the same as $_, so there’s some confusion in the PowerShell world. When should I actually use one or the other?
I’m going to be honest with you. They are exactly the same. [laughs] In PowerShell 2, when we use $_, it started to cause some confusion, so when PowerShell 3 was released the creators of PowerShell decided, “Let’s go ahead and rename it, or provide an alternate name for it, PSItem.” For some individuals, it’s a little more clear as to what it represents.
For me, personally, I still use $_ to save room on the screen, particularly when I have to teach and project it on a big screen for everybody to see, I need to be conscious of how much horizontal real estate I have. Either one is supported and will work.
The next question I usually get is, “Well, which one’s faster?” What I’m going to do is I’m going to run a little speed test here for you. We are running inside of a virtual machine, and it’s actually in a shared environment. It’s up in Azure, so the results will vary here. I’m going to run this test several times.
Essentially, what it’s going to do is it’s going to do a measurement of the same procedure using $_ and $PSItem. It’s going to run each one of these tests 100 times and give me the average of the number of ticks.
If you’re not familiar with a date‑time object, a tick is an extremely minute small amount of time. It’s the most accurate measurement we can come up with. Let’s go ahead and run this.
The items in green is the faster of the two. You can see we’re pretty much on an even spread. The reason is that these are exactly the same thing. There is no performance difference between the two of them. No matter how many times I run this, almost always do we get an even spread between them.
Which one should you use? That’s up to you and whatever team you’re working with. If your team prefers $PSItem, go ahead and use that. $_, it’s still there for backward compatibility and you can still use it.
For instructor-led PowerShell training classes, see our course schedule:
PowerShell $_ and $PSItem in Windows PowerShell used in this video.
Download the $_ and $PSItem in Windows PowerShell Script.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | <# ╔══════════════════════════════════════════════════════════════════════════════╗ ║ ║ ║ Explaining $_ and $PSItem ║ ╟──────────────────────────────────────────────────────────────────────────────╢ ║ Interface Technical Training ║ ║ Jason A Yoder ║ ║ ║ ╚══════════════════════════════════════════════════════════════════════════════╝ #> #region Display Title Clear-Host $String = @' █ █ ███ ███ █ █ █ █ █ █ ███ ███ █████ █ █ █ █ █ █ █ █ █ ███ █ █ ███ ███ █ █ █ █ ████ ███ █ █ █ █ █ █ █ █ ███ ███ █ █ █ █ █████ █ █ █ █ █ ███ █ █ █ █ █ █ █ ████ █ █ █ ███ █ █ █ ███ █ █ █ █ █ █ █ █ █ █ █████ █ ███ █ █ █ ███ █████ ██ ███ █ █ █ '@ Write-Host $String -BackgroundColor DarkYellow -ForegroundColor Yellow #endregion # Used to represent the current object in the PowerShell Pipeline. Get-CimInstance -ClassName Win32_LogicalDisk Get-CimInstance -ClassName Win32_LogicalDisk | ForEach-Object {$_.DeviceID} Get-CimInstance -ClassName Win32_LogicalDisk | ForEach-Object {$PSItem.DeviceID} # Verify that $_ and $PSItem represent the same thing. Get-Help about_Automatic_Variables -ShowWindow #region Speed test Clear-Host Write-Host Write-Host 'Verify there is not any measureable' -ForegroundColor Yellow Write-Host 'performance difference $_ and $PSItem.' -ForegroundColor Yellow Write-Host 'Results are in the average number of ticks.' -ForegroundColor Cyan Write-Host '-------------------------------------------' -ForegroundColor Yellow Write-Host Write-Host '$_ : $PSItem' For ($X = 0 ; $X -lt 10 ; $X++) { $Test1 = 1..100| ForEach -Begin{$Sum = 0} ` -Process { $Sum += Measure-Command -Expression { Get-Process | ForEach {$_.name} | Out-Null } } ` -End {$Sum | Measure-Object -Property Ticks -Average | Select-Object -ExpandProperty Average} $Test2 = 1..100| ForEach -Begin{$Sum = 0} ` -Process { $Sum += Measure-Command -Expression { Get-Process | ForEach {$PSItem.name} | Out-Null } } ` -End {$Sum | Measure-Object -Property Ticks -Average | Select-Object -ExpandProperty Average} If ($Test1 -lt $Test2) {$Color1 = "DarkGreen" ; $Color2 = "DarkBlue"} Else {$Color1 = "DarkBlue" ; $Color2 = "DarkGreen"} Write-Host "$Test1" -BackgroundColor $Color1 -NoNewline Write-Host ' : ' -ForegroundColor White -NoNewline Write-Host "$Test2" -BackgroundColor $Color2 } # END: For ($X = 0 ; $X -lt 10 ; $X++) #endregion |
You May Also Like
A Simple Introduction to Cisco CML2
0 3804 0Mark Jacob, Cisco Instructor, presents an introduction to Cisco Modeling Labs 2.0 or CML2.0, an upgrade to Cisco’s VIRL Personal Edition. Mark demonstrates Terminal Emulator access to console, as well as console access from within the CML2.0 product. Hello, I’m Mark Jacob, a Cisco Instructor and Network Instructor at Interface Technical Training. I’ve been using … Continue reading A Simple Introduction to Cisco CML2
How to Build in a PSMethod to your PowerShell Code
0 71 0In this video, PowerShell instructor Jason Yoder shows how to add Methods (PSMethod) to your code using free software that’s added into the PSObject. For instructor-led PowerShell courses, see our course schedule. Microsoft Windows PowerShell Training Download the Building Methods PowerShell script</a> used in this video. <# ╔══════════════════════════════════════════════════════════════════════════════╗ ║ ║ ║ Building Methods ║ ╟──────────────────────────────────────────────────────────────────────────────╢ … Continue reading How to Build in a PSMethod to your PowerShell Code
OSPF Adjacency Troubleshooting Solution – Getting Close to the OSPF adj
0 249 1In this video, Cisco CCNA & CCNP instructor Mark Jacob shows how to troubleshoot OSPF Adjacency issues by showing the distance between routers with the show ip ospf neighbor command.
See what people are saying...