The Great Dollar Dollar

The Great Dollar Dollar

Rate This
  • Comments 7

No, I’m not talking about our newest rap single. I’m talking about PowerShell’s most hidden gem. The one you can show to most members of even the PowerShell team, and have them gasp – “oh, that’s cool! I gotta remember that!”

And it’s not even for lack of documentation! Here are the first few lines of Get-Help about_automatic_variables:

PS>Get-Help about_automatic_variables

    Describes variables that store state information for Windows PowerShell.
    These variables are created and maintained by Windows PowerShell.

    Here is a list of the automatic variables in Windows PowerShell:

       Contains the last token in the last line received by the session.


That’s it, right at the beginning

The ‘$$’ (“dollar dollar”) automatic variable always holds the last thing on the last line you typed. Now, why would you ever care about tokens received by the session? It saves you typing, that’s why!

Imagine you’re parched and nearly exhausted from typing in some long path name. And to make it worse, just to see if a file exists:

PS>dir C:\windows\system32\drivers\etc\hosts

    Directory: C:\windows\system32\drivers\etc

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         11/7/2010   1:39 PM        848 hosts

Now that you’ve found it, you want to open it in Notepad. While you can normally press the up arrow, go back to the beginning of the line and change ‘dir’ to ‘Notepad’, there’s an easier way:

PS>notepad $$

Voila – notepad opens ‘c:\windows\system32\drivers\etc\hosts’.

If you’re a shell polyglot, the Bash shell (in Unix, Mac, etc.) supports something similar through its ‘!$word designator.


Lee Holmes [MSFT]
Windows PowerShell Development
Microsoft Corporation

Leave a Comment
  • Please add 4 and 3 and type the answer here:
  • Post
  • Cool

    We get first -> ^

    We get last -> $

    Just like RegExp.

  • It's actually $! in bash. $$ is the last line, and $! is a shortcut for $$:!

  • Why would you need $False instead of the string "false"?

  • aca.schaubr, I guess to be internally consistent that it's a variable? Besides, since it is you can do 'fun' stuff like this!

    PS C:\> function false {"it's true!"}

    PS C:\> false

    it's true!

  • Any non-null string evaluates to $true when cast as [bool]

    PS C:\> [bool]"false"


    PS C:\> [bool]$false


    PS C:\>

  • $$ would be a real time saver on typing if it is used instead of the $_ variable (or as an alias). The easiest to type variable should be used for the most frequently typed variable, is not it natural?

    The post mentions only advantages of using $$. There disadvantages, too.

    Use of $$ may actually increase typing. One cannot use commands with $$ from history if they are not the last, right? So that basically most of commands with $$ cannot be reused. One has to recompose commands instead of just reusing them. Same story on copy/paste commands to scripts or to other consoles, all used $$ have to be retyped.

    Use of $$ also increases chances of mistakes. One has to keep in mind: a) what the last argument is; b) whether or not an intermediate “noise” command has been typed and invalidated ephemeral $$ value for potential use in the next command. It looks too fragile in some scenarios.


    Here is a silly but quite possible example. A user types:

    PS> notepad tmp.txt

    PS> ls *

    PS> rm $$

    Imagine a user forgets that he has just typed the second command. Even if it is a rare case it is perfectly possible. Then by typing “rm $$” he means “rm tmp.txt”. It is not what he gets. He gets “rm *”. Who does this mistake? A user does, indeed. But who makes this mistake possible? The shell does.

  • I am not sure, but you can use the "$$Identifier" for required by the programmer entities (e.g., functions' formal parameters, etc.).

    For example:

    function ($Param1)


     $Path="$$ParamI\etc" #Exception! Typos.

    $Path="$ParamI\etc"  # resulted in "\etc" value of the Path


    Pipes and per instance Add-member (etc) -- IMHO -- entail deals with non-existent entities, but programmer's typos (as a rule) are the statical problem. Strict modes (scoped or not)... But how about more fine control?

    p.s. The message has been translated by software translator.

Page 1 of 1 (7 items)