A Quick History Lesson
Today, I did a significant amount of work in a PowerShell session and, even though most of what I did was copy/pasted from a file (open in VS Code), I wanted to grab only the essential commands from the session.
Instead of scrolling or arrowing up (which is actually using PowerShell history, by default), you can list all of the commands that you have executed in your session, up to a predefined maximum.
All of the output is from PowerShell 7.0.0-preview.6.
Preview 6 dropped last week on 11/21/2019, as announced by Steve Lee. If you are a fan of PowerShell and you don’t know Steve, you have some homework to do.
Historical Facts
As with most commands, you can find more about it through PowerShell’s powerful help system.
Conceptual Help
Most PowerShell concepts have an “about_*” help file that could be considered a primer for the topic.
|
|
|
|
Cmdlet Help
Next, let’s examine the cmdlets.
|
|
You should skim through the help for the rest of the cmdlets to familiarize yourself with what they do. I will provide
examples for Get-History
and Invoke-History
further down the page.
Preference Variable
As we learned from the conceptual help, the $MaximumHistoryCount
preference variable default value is 4096, since
Windows PowerShell 3.0. This is how many commands that PowerShell will save for the session.
You can change this in your $profile
to a maximum of 32767. You can verify this is the maximum via the following
command and seeing the MaxRange attribute.
|
|
History Class
PowerShell can access command history through the Microsoft.PowerShell.Commands
namespace with the [HistoryInfo]
class.
The class has the following properties.
Property | Type | Description |
---|---|---|
Id | [long] |
Id of the history entry |
CommandLine | [string] |
String of the command |
ExecutionStatus | [System.Management.Automation.Runspaces.PipelineState] |
Execution status of associated pipeline |
StartExecutionTime | [datetime] |
Start time of associated pipeline |
EndExecutionTime | [datetime] |
End time of associated pipeline |
Duration | [timespan] |
Calculated timespan from start and end time |
The Duration
property was first available in PowerShell Core 6.1.
It is displayed by default in Get-History
output since PowerShell 7.0.0-preview.2.
It was added by PowerShell community member Keith Hill. Anyone can contribute to make PowerShell even greater!
Get-History
When you run Get-History
or its alias h
, you should see something similar to following output. That is to say, your
specific data will be different, but the same properties should be present. For versions below 7 preview 2, you will
only see the Id
and CommandLine
properties.
|
|
But wait, there’s more!
Piping the command to Format-List
, you’ll see all of the properties.
|
|
Send Specific Historical Commands to the Clipboard
Now that we know how to get the commands from history, here is how you can get exactly what you want into your clipboard.
|
|
This grabbed the history of the lines I typed/pasted in, in the order I wanted them, expanded the CommandLine property, and sent it to the clipboard.
Pretty simple.
| clip
a lot instead of using the mouse to select and copy.
Doing this has save me a considerable amount of time and without error.
You could, of course, use Set-Clipboard
instead.
Get a Range of HistoryInfo Entries
I just learned while writing this post that you can get a range of history entries.
|
|
The Id
that you supply is the last entry. The Count
is the number of preceding history entries, including the
Id
.
Invoke-History
The Cmdlet Invoke-History
runs commands from the session history.
Re-execute Specific Historical Commands
What if I wanted to re-execute those lines in the same order?
|
|
Send History into the Pipeline
If you remember from the help for Invoke-History
, you’ll see that Id
can accept pipeline input via ByPropertyName
.
This means that you could do the following.
|
|
This will execute the command associated with history entry with Id
of 75.
Unfortunately, you cannot send an array of [HistoryInfo]
objects into Invoke-History
as it only accepts a single
instance.
A Better History
If you want better control and multi-session spanning history, you should use PSReadLine
. And if you are using
PowerShell 6 or higher, or are running Windows 10 October 2018 Update (build 1809) or higher, you already have
PSReadLine
installed and are most likely using it.
Here are the properties that have something do to with history.
- AddToHistoryHandler
- HistoryNoDuplicates
- HistorySavePath
- HistorySaveStyle
- HistorySearchCaseSensitive
- HistorySearchCursorMovesToEnd
- HistoryStringComparison
- MaximumHistoryCount
Getting this list was a little tricky, but here’s how you can do it. This method will help you digging into other objects as well.
|
|
To learn more about PSReadLine
, check out the README file for the project’s GitHub repo.
Here are a few blog posts about PSReadLine
, albeit dated. They should, however, still provide relevant information.
- Towards a better console - PSReadLine for PowerShell command line editing
- PSReadLine - A free PowerShell console extension
- Change PowerShell’s Tab Complete
Summary
We used PowerShell’s Help system to view conceptual help and the help for the *-History
cmdlets. We saw examples of
using the two primary cmdlets, Get-History
and Invoke-History
, including how to save or re-execute specific
commands.
I hope you’ve found this interesting or informative. If you have any comments or questions, please post them below.
Thanks for reading!