In my PowerShell classes, we explore multiple variables to help us work with different cmdlets and constructs. I often get questions on when to use special variables. Take a look below for an explanation of when to use some of them.
$_
This is the generic variable used in PowerShell prior to V3. I still use it because it is shorter and helps prevent horizontal scrolling. We use it to represent the object that is currently in the PowerShell Pipeline. When you pass information in the pipeline, only one object will be in the pipeline. This variable represents that object. We do not provide a named variable in the pipeline. $_ will have access to all of the members of that object.
# This will show you that $_ is the object in the pipeline.
# $_ is a STRING object.
Get-ChildItem |
Select-Object -First 1 -ExpandProperty Name |
ForEach-Object {
$_
}
You have access to the objects properties.
# Accessing the objects properties.
Get-ChildItem |
Select-Object -First 1 -ExpandProperty Name |
ForEach-Object {
$_.Length
}
You also have access to the objects methods.
# Accessing the objects methods.
Get-ChildItem |
Select-Object -First 1 -ExpandProperty Name |
ForEach-Object {
$_.ToUpper()
}
$PSITEM
$PSItem was introduced in PowerShell V3. The idea of introducing $PSItem is to help make your code more readable. Both $_ and $PSItem stand for “The current object in the PowerShell Pipeline.” Those of you who have sat in my class may recall that I say those exact words when I type either one of these. There is no difference between the two except the $PSItem is only supported in PowerShell V3 and later.
Generic variable used with ForEach looping.
When we are not using the PowerShell Pipeline, but need to loop through an unknown number of objects, we use the ForEach construct. Take a look at this code.
# Looping with ForEach
$Events = Get-EventLog -LogName System -Newest 5
ForEach ($Event in $Events)
{
$Event.instanceId
}
First we gather the objects that we want to work with. In this case, we are collecting event objects. In the declaration of the ForEach loop, we declare a temporary variable called $Event. A lot of documentation uses the singular form of the variable holding all of the objects for the generic variable. You can see that $Events is holding the collection of objects and $Event is the generic variable used to reference the objects in $Events. I find this to be to confusing. You can name the generic variable anything that you want. I am going to change it to $E for clarity.
# Looping with ForEach
# Shortened generic variable for clarity.
$Events = Get-EventLog -LogName System -Newest 5
ForEach ($E in $Events)
{
$E.instanceId
}
$This
This is a bit more complicated to explain. I’m actually adding the CLASS keyword to my advanced PowerShell classes. PowerShell 5 supports the creation of classes just like many other object orientated languages. The $This variable refers to the object itself. We use it when creating methods or modifying the properties of the object being accessed.
# Using $This in a method.
Class MyMath
{
$X = 5
$Y = 10
$Total = 0
[Void]Add()
{
$This.Total = $This.X + $This.Y
}
}
$Math = [MyMath]::new()
$Math
$Math.Add()
$Math
These variables can be a bit confusing. It is part of learning PowerShell’s syntax. I’ve been asked, “Why do you have to type this stuff?” Well, that is coding. We need to clearly define what we want the computer to do. One of my college professors, Dave Syler, told us the computer will do exactly what you tell it to do. If you do not provide clear instructions, it will go off on its own and do something else. The syntax is designed to provide clear instructions.
I hope this helps many of you out. Once you have used the syntax for a while, it becomes second nature to you.
Comments