Sometimes you're executing a series of commands when using the PowerShell console and have to go back and forth repeating commands you've used before. Sometimes, just using the up/down arrow keys is enough (or their close cousins: F7, F8 and F9).

However, sometimes it isn't enough. One of the issues with up/down and friends is that this really isn't implemented by PowerShell (or whatever PowerShell host you're using), but by the Windows Console Subsystem in CRSS.EXE. And sometimes it can also be a drag.

Fortunately, PowerShell has some pretty useful things that I had not played with much before, but they turn out to be pretty useful.


Get-History

PowerShell keeps track of the last N commands you've executed in the "History", where N == 64 by default. You can modify how many commands the history will contain by setting the $MaximumHistoryCount variable in your profile scripts.


Technically speaking, exactly what gets stored here depends on the Host application, but the default ConsoleHost pretty much does what you'd normally expect.

You can check your history using the Get-History command, which by default is aliased as 'ghy', 'h' and 'history'. Go on and give it a try!

One interesting thing is that each entry in the history is given an Id, which you can use later on to refer to that specific entry in the command history.


Repeating a Command

You can repeat (i.e. execute again) an arbitrary entry in the command history by using the Invoke-History command and passing it the Id of the entry to execute again:

Invoke-History 45

If you don't provide an Id, then the last entry in the history will be executed again (or you can also pass in a string with the first few characters of the command and the history is searched backwards for the first match).

This is pretty handy also, because Invoke-History is by default aliased as 'r' and 'ihy'. So you can simply repeat the last command using "r".

One thing to watch out for is that Invoke-History will first write to the console the command it is going to execute, so keep that in mind when looking at the output.

Notice that when you use Invoke-History, the Invoke-History command itself will not go into the command history. However, the command executed as a result of the use of Invoke-History will indeed get appended to the history!

The Last Command

Another interesting thing is that, PowerShell will store the last command executed into the $^ variable. So an easy way to check what the last command executed was is to simply type $^ at the prompt:

tomasr@arcano {~\scripts} $^
cls

Let me reiterate something: The $^ variable stores the last command directly executed, not the last command in the history. That means that if you call Invoke-History, then $^ will contain your Invoke-History command, not the actual command executed as a result.

It does provide for some funky stuff. For example, you can repeat the last executed command (yes, even redo an Invoke-History command) using:

tomasr@arcano {~\scripts} &$^

  Id CommandLine
  -- -----------
  89 $ExecutionContext.SessionState
  90 $ExecutionContext.SessionState.Host
  91 $ExecutionContext.Host

A discrepancy

There's another interesting difference between $^ and the history. For example, let's say you execute a compound command like "ls; echo done".

If you immediately check the history, you'll see that the last entry in the list is indeed the entire thing ("ls; echo done"). This means that history really keeps track of entire pipelines executed.

However, if you immediately check the value of $^, you'll notice that it only contains the first part of the pipeline ("ls"); not the entire thing. In fact, $^ only stores the first command in the pipeline executed; so if you execute, say, "ls | sort", still only "ls" is stored; which is certainly a lot less useful (but still interesting).


Add-History

There's also an Add-History command you can use to push stuff into the history without actually executing it first. In theory, this would seem to be aimed primarily at making it possible to persist the history across sessions. All you need to do is save the contents of your history to a file and then read it back and feed it to Add-History.

This is unfortunately less than useful, because it is not done automatically for you. You can partially automate it, but since it requires you to explicitly use a command to close your session, well, little chance of our fingers and brains getting used to it (and even if you do, what happens if you accidentally close the window instead of typing the right command?). Looks like V2 might help here; would be nice.

Have fun!

Technorati tags:


Tomas Restrepo

Software developer located in Colombia.