Never Lose Your Work at the Console
If you’re like me, every once in a while you have a dash of brilliance, write the perfect one-liner, but forget to record your work. You know you solved this problem already, but none of your documentation bears witness. You’re a trapeze artist without a safety net when you work at the console. Now, between transcripts, saving previous output, and HistoryPX, you won’t have to worry.
Transcripts
Transcripts are exactly what you think they are. They are a character for character representations of what happened at the console. To start saving a transcript you run the Start-Transcript cmdlet with a filepath. Transcripts will store all of your commands as well as whatever is written to the pipeline using Out-Default. Stopping a transcript is as easy as running Stop-Transcript.
If you ever log a bug report with any open-source modules on GitHub attaching your transcript log is a great idea. The developer gets more than a vague error report and you’re more likely to get your bug squashed.
If your as lazy as I am, you likely don’t want to have to remember to run a transcript cmdlet at the beginning of every PowerShell session. That sounds too much like work. Instead, add the following code to your PowerShell profile.
$Date = (Get-Date -format "yyyy-MM-dd-hh-mm-ss")
Start-Transcript -Path ~\Documents\WindowsPowerShell\Transcripts-$Date.txt
No more remembering and you have a log of all of your work. Your transcripts will be stored in the Transcripts folder in WindowsPowerShell.
Out-Variable
For something less formal than a transcript you can use the OutVariable parameter for the Out-Default cmdlet. Out-Default runs whenever there is something left over in the pipeline. That is what writes to the console.
We can leverage a little-known feature called Default Parameter Values to save the output. Here, you specify what cmdlet, what parameter, and what value to pass to the parameter. Now whenever the cmdlet is run, the value is passed to the specified parameter.
PS:> $PSDefaultParameterValues['out-default:outvariable'] = 'PreviousOutput'
PS:> Get-Process -Name PowerShell
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
375 24 48072 90832 0.39 8116 8 powershell
594 34 87088 132444 3.33 9196 8 powershell
380 24 46064 88872 0.48 9336 8 powershell
669 34 66748 110692 2.89 10784 8 powershell
PS:> $PreviousOutput
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
375 24 48072 90832 0.39 8116 8 powershell
594 34 87088 132444 3.33 9196 8 powershell
380 24 46064 88872 0.48 9336 8 powershell
669 34 66748 110692 2.94 10784 8 powershell
After running the above code you can now retrieve any previous pipeline output that was sent to the console screen. This is also something you can put in your profile so you don’t have to remember.
HistoryPX
Kirk Munro has written a beautiful module for handling your PowerShell history. There is even talks with bringing HistoryPX into PowerShell so it is installed by default.
For now though, you install it using the following. Note: SnippetPx is also a module written by Kirk.
Install-Module -AllowClobber HistoryPx,SnippetPx
Then, all you have to do import the HistoryPx module and you’re off to the races. Notice how once you import the module you automatically get the previous output saved in the $__ variable. You also get the ability to grab the output from previous commands using Get-History AND you get measure-command statistics. All for simply importing HistoryPx.
Git:> Import-Module historypx
Git:> get-process -name powershell
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
375 24 48040 90816 0.39 8116 8 powershell
594 34 87080 132440 3.33 9196 8 powershell
380 24 46032 88856 0.48 9336 8 powershell
889 36 73336 118452 3.97 10784 8 powershell
PS:> $__
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
375 24 48040 90816 0.39 8116 8 powershell
594 34 87080 132440 3.33 9196 8 powershell
380 24 46032 88856 0.48 9336 8 powershell
889 36 73336 118452 3.97 10784 8 powershell
PS:> Get-History
Id CommandLine Duration Success #Err #Out #Src Output
-- ----------- -------- ------- ---- ---- ---- ------
18 Clear-History 00:00:00.002 True
19 Import-Module historypx 00:00:00.010 True
20 get-process -name powershell 00:00:00.021 True 4 1 {System.Diagnostics.Process (powershell),...
21 $__ 00:00:00.019 True 4 1 {System.Diagnostics.Process (powershell),...
PS:> (Get-History -Id 20).Output
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
375 24 48040 90816 0.39 8116 8 powershell
594 34 87080 132440 3.33 9196 8 powershell
380 24 46032 88856 0.48 9336 8 powershell
889 36 73336 118452 4.27 10784 8 powershell
With DefaultParameters, transcripts, and HistoryPx you no longer have an excuse to lose your work.