Some variable names in the Windows PowerShell language are off limits, and using them can produce very unexpected -- and unwanted -- results. Everyone runs into this problem at one point or another and every script newbie will want to pull his hair out wondering what’s wrong with his script. The culprit is almost always PowerShell’s automatic variables.
The PowerShell language itself needs a few variables to function correctly. PowerShell uses these variables to store various bits of information and allows you to read the variables -- not write to them. PowerShell stores different types of information in these variables.
One of the most popular automatic variables is the pipeline variable $_, which is also called $PSItem. This variable is used to represent objects flowing across the PowerShell pipeline.
If you've used PowerShell to read a CSV file or used the Get-AdUser cmdlet to find Active Directory users, but didn’t want to retrieve all of the items in the CSV or all Active Directory users, then you've probably used another popular automatic variable: where alias (also called Where-Object). For example, if you query a CSV file with the headers of FirstName and LastName that contain hundreds of names, one way to only get the names that have a last name of Jones is to use Where-Object (see Figure 1).
In this example, I used the pipeline variable to represent each name that comes from the Import-Csv cmdlet. I’m referencing the LastName property of the pipeline variable and telling Where-Object to only show me names that have a last name of Jones. I couldn’t use the $_ variable myself by assigning a value to it because PowerShell is already using it.
In the PowerShell script shown in Figure 2, you’d expect $_ to be equal to somethingelse but it’s not. That is because PowerShell allows admins to write to any automatic variable. You’ll notice no error occurred. This often trips up new PowerShell users.
Finally, two other automatic variables are $true and $false. PowerShell reserves these variables to signify a Boolean True and a Boolean False value. And these values are used consistently across all types of PowerShell scripts to check for various conditions. For example, you could use the $false variable to check if something is equal to something else, as shown in Figure 3, where I check to see if the integer 1 is equal to the integer 2 (Figure 3).
In this case, 1 is not equal to 2. And I confirm this by comparing the result of 1 -eq 2 against the automatic variable $false. As expected, the result of that condition is our other automatic variable $true.
When you try to assign a variable to the variable $false (Figure 4), you will receive a helpful error that indicates the variable is read-only or a constant. In either case, this means the variable was defined somewhere else and nothing is allowed to change its value.
These examples are fairly simple, so it's difficult to make a mistake. However, once you begin to build larger scripts, the issue of using an automatic variable can become more difficult to track down. Remember: you don’t have to get an actual error to have a problem. The next time you encounter an issue with a script, in which everything looks correct, check the automatic variables to ensure the ones you’re using aren’t somehow conflicting with PowerShell’s variables.
Simple commands for comparing PowerShell variables