Avoid Scripting: Use PowerShell Command History


Summary: Microsoft Scripting Guy, Ed Wilson, talks about avoiding Windows PowerShell scripting by using command history.

Hey, Scripting Guy! Question Hey, Scripting Guy! I used to have a program that I could use to keep track of commands I typed at the command prompt. It permitted me to use macros to replay those commands or to select which commands I wanted to run. It was simple, elegant, and not complicated. It is a shame that “modern” programs are not that easy to use. I really don’t relish the thought of having to learning scripting to be able to run a few commands. I wish I could go back to my old command prompt. But I guess I cannot. No action required. I am just letting off steam today. Thanks for listening.

—LM

Hey, Scripting Guy! Answer Hello LM,

Microsoft Scripting Guy, Ed Wilson, is here. The Scripting Wife and I were out and about the other day, before the snow storm hit, and we ran across a little tea shop that had a very nice Lapsang Souchong tea. It is one of the few teas that I drink with milk. I find I need the milk to help cut the rather strong, unique flavor. If you haven’t had this tea, you may want to try it sometime—but don’t rush out and buy a pound of it just yet. It is a bit of an acquired taste, and you might not like it.

It is a good tea to try off a nice tea menu to see if you like it. I find it goes really well with Scottish butter cookies—but again, that may be me. I find the combination to be a bit “old school”;  but then, it may be that I fell in love with the combination a long time ago when we were in Australia for the first time.

Speaking of old school...

Yeah, I think I may remember using an old-fashioned command prompt a long time ago. It was simple—but I also remember some of the commands were pretty convoluted, and they all seemed to act differently. The good thing, LM, is that you can use the Windows PowerShell console in a similar fashion to how you used the command line. You do not have to learn scripting if you do not want to. All you need to do is to use the command history.

Windows PowerShell command history

There are a number of Windows PowerShell cmdlets that permit working with the command history. I can find them by using the Get-Command cmdlet, and then looking for a name that matches History and a command type that equals Cmdlet. Here is the command and the results:

PS C:\> Get-Command -Name *history* -CommandType cmdlet

CommandType     Name                                        ModuleName

-----------               ----                                               ----------

Cmdlet          Add-History                                        Microsoft.Powe...

Cmdlet          Clear-History                                     Microsoft.Powe...

Cmdlet          Get-History                                        Microsoft.Powe...

Cmdlet          Invoke-History                                    Microsoft.Powe...

To see the commands in my history, I use the Get-History cmdlet:

PS C:\> Get-History

  Id CommandLine

  --   -----------

   7 clhy

   8 cls

   9 h

  10 cls

  11 Get-Command -Noun history

  12 cls

  13 Get-Command -Noun history -CommandType cmdlet

  14 Get-Command -Noun history -CommandType Cmdlet

  15 Get-Command -Noun history

  16 Get-Command Get-Command -Syntax

  17 cls

  18 Get-Command -Name *history* -CommandType cmdlet

If I find myself using the Get-History cmdlet often, I can use an alias. Here is the Get-Alias command:

PS C:\> Get-Alias -Definition Get-History

CommandType     Name                                     ModuleName

-----------               ----                                            ----------

Alias           ghy -> Get-History

Alias           h -> Get-History

Alias           history -> Get-History

If I want to run a command from the history, I use the Invoke-History cmdlet. I generally use Get-History and Invoke-History together. I need to see what is in my history before I can execute a prior command. The easiest way to run something from the history is to specify the command ID. This technique is shown here:

PS C:\> Get-History

  Id CommandLine

  --     -----------

  21 clhy

  22 cls

  23 Get-History

  24 cls

  25 Get-Service bits

  26 Get-Process explorer

  27 cls

 

PS C:\> Invoke-History -Id 25

Get-Service bits

Status   Name               DisplayName

------        ----                   -----------

Running  bits               Background Intelligent Transfer Ser...

As shown here, I can specify an array of ID numbers for the Get-History cmdlet:

PS C:\> Get-History -Id 25, 26

  Id CommandLine

  --    -----------

  25 Get-Service bits

  26 Get-Process explorer

But when I attempt to use an array of IDs with the Invoke-History cmdlet, I get the following error message:

Image of error message

Hmmm…

Well, I can pipe the results from Get-History to Invoke-History:

PS C:\> Get-History 25 | Invoke-History

Get-Service bits

Status   Name               DisplayName

------       ----                   -----------

Running  bits               Background Intelligent Transfer Ser...

Because I can get multiple items from the history, can I also pipeline them? As shown in the following image, I still get an error message:

Image of error message

Bummer.

When I see an error message that says a cmdlet will not accept multiple items through the pipeline, I can usually substitute the command for one that includes Foreach-Object. This is because Foreach-Object interrupts the pipeline and deals with each item, one at a time. It ruins “streaming” the output, but it permits me to pipe the results from one command to another. I can also automate the output without having to resort to scripting. Here is the revised command:

Get-History -Id 25, 26 | foreach { Invoke-History -id $_.ID}

As shown in the following image, the command works:

Image of command output

LM, that is all there is to using the Windows PowerShell command history. Script Without Scripting Week will continue tomorrow when I will talk about more cool stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Comments (3)

  1. Chen V says:

    Cool stuff. Thanks Ed

  2. Lady Bracknell says:

    I like lapsang Souchong as well. Like Ed I find the tea too strong so blend it 50/50 with an ordinary leaf tea

  3. MikeM says:

    I must say the "Hey, Scripting Guy! Blog" goes AWESOMELY well with my Starbucks coffee every morning. I use Get-History often but this great tip for combing it with Invoke-History just sweetened the coffee!!! Thanks much ED! MM

Skip to main content