PowerShell Automatic Variables
> I hope you've been working on last month's scripting challenge. I'll have a solution next week.
When using PowerShell, either in an interactive console session or in a script, you might want to take advantage of built-in or automatic variables. These variables are created and maintained by PowerShell, and they provide useful information about the current session, the state of the script or command execution, or the environment. You don't need to define them; they are automatically available for use. However, this also means that you should avoid using the variable names for your own variables.
PID
Some of the variables are defined as read-only or constant so you'll get an error if you try to use the variable name for your own variable. For example, if you try to assign a value to $PID
, you'll get an error because $PID
is a read-only variable that contains the process ID of the current PowerShell session.
PS S:\> $pid
35996
PS S:\> $pid = 4
WriteError: Cannot overwrite variable PID because it is read-only or constant.
I can use this variable to filter out the current pwsh
process.
Get-Process pwsh -IncludeUserName | where id -ne $pid | Select ID,CommandLine,Username,StartTime,@{Name="Runtime";Expression = {New-TimeSpan -Start $_.startTime -end (Get-Date)}}

$pecial
Don't forget that you only include the $
sign when you are referencing the variable. In the previous example the variable name is PID
. We use $PID
to reference the variable value.. If you want to use the variable in a string, you can use the $(...)
syntax to reference the variable.
However, there is a variable with a name of $
.
PS C:\> $$
0
PS C:\> Get-Variable -Name $
Name Value
---- -----
$ 0
The variable holds the last token of the last processed command. PowerShell uses the AST (Abstract Syntax Tree) to parse the command. This breaks a command down into its components using tokens. The $
variable shows you the last token. If you are familiar with regular expressions, the $
is used to indicate a pattern at the end of a string. The principal is the same.
PS C:\> Get-Service bits
Status Name DisplayName
------ ---- -----------
Stopped bits Background Intelligent Transfer Service
PS C:\> $$
bits
PS C:\> 1..5 | Foreach-Object { ($_*$_) * 3.14}
3.14
12.56
28.26
50.24
78.5
PS C:\> $$
}
Don't confuse token with character. In this example the tokens are bits
and }
. I don't have a good practical example for this variable, and I rarely write code that relies on the AST.
$^
The counterpart to $
is the ^
variable. This variable holds the first token of the last processed command.
PS C:\> Get-Service bits
Status Name DisplayName
------ ---- -----------
Stopped bits Background Intelligent Transfer Servi…
PS C:\> $^
Get-Service
Again, I don't have a good practical example for this variable. If you have a use case for $^
or $$
, I'd love to hear about it.
$?
The ?
variable is a boolean value that indicates whether the last command was successful. If the last command was successful, $?
is True
. If the last command failed, $?
is False
. The command has to properly complete for this variable to be set. If you mangle the syntax, the command won't run so the variable remains unchanged.
PS C:\> Get-Service winrm
Status Name DisplayName
------ ---- -----------
Running winrm Windows Remote Management (WS-Management)
PS C:\> $?
True
PS C:\> Get-Service abcdef
Get-Service: Cannot find any service with service name 'abcdef'.
PS C:\> $?
False
> *Don't confuse this variable with the ?
alias for Where-Object
.
This should also apply to native commands, i.e. non-PowerShell commands.
PS C:\Scripts\PSTeachingTools> $?
True
PS C:\Scripts\PSTeachingTools> cd c:\temp
PS C:\temp> git status
fatal: not a git repository (or any of the parent directories): .git
PS C:\temp> $?
False