PowerShell has a set of automatically managed variables that give you information about the code currently running. Their purpose and usefulness vary: some are used very often and others only rarely. In any case, it doesn’t hurt to know a few of them and to have it ringing in the back of your head that there are others that might be useful in the future.

Both the official documentation and the “get-help about_automatic_variables” command contain the full list, but I’d like to go through a few here that I find interesting or that have a catch.

Some variables are well known to anyone who knows a bit of PowerShell. Variables like $_, $true, $false, $Args, $NULL are in common use even before you know what automatic variables are.

Related to error handling, the $? and $Error variables could be useful, although you have to handle them with care. In the first case, $? returns TRUE if the last operation succeeded, or FALSE otherwise. The $Error variable is, in principle, an array containing the most recent errors. The problem I see with this array is that it only contains PowerShell errors. That is, taking this code as an example:

ping error_forzado
$?
$Error

In a case like this, the $? variable will be False but $Error won’t contain the error from the ping command. The reason is that it isn’t a PowerShell error. When we run ping we’re invoking an executable, not a PowerShell function or cmdlet. That’s why you have to be careful, and it’s usually better to capture errors through other mechanisms.

Also related to error capturing is the $LastExitCode variable, which stores the exit code of the last Windows program run. In the previous example, $LastExitCode would have a value of 1.

Another very interesting variable is $MyInvocation. This variable gives you information about the command currently running, including the script name, the function, the path, the parameters, etc. For example, the BoundParameters and UnboundArguments properties give you access to the list of arguments passed to the function. UnboundArguments is something like $Args, although the type of $Args is Object[] and UnboundArguments is of type List.

Another interesting variable, related to the previous one, is $PSBoundParameters. In this case the explanation is simple: using this variable is the same as using $MyInvocation.BoundParameters. At least that’s how it is on my machine, where $PSBoundParameters.Equals($MyInvocation.BoundParameters) returns True. And I fall back on the classic “works on my machine” because I’ve found people out there saying otherwise depending on the PowerShell version being run.

And finally, two that come in really handy: $PSCommmandPath and $PSScriptRoot. These two variables give you, respectively, the full path and the directory of the script the code is running from. They can be very useful for referencing paths relative to a specific script, whatever the value of Get-Location is. Mind you, it’s important to keep in mind that they are strings; if we want to manipulate them, it’s usually best to create DirectoryInfo or FileInfo variables from their values.