Whenever I teach or speak about PowerShell, a recurring mantra is that there is no difference between running a PowerShell script and executing commands interactively in the shell, except that it saves you typing. You can create a PowerShell script by simply copying and pasting commands from the shell into a .PS1 text file. This means you can develop and test your script as you write it. But copying and pasting can be a pain. One alternative I have is a script to take your PowerShell history and turn it into a script file.
Whenever you run a PowerShell command, it is stored in an internal history buffer. We use the Get-History cmdlet to retrieve history.
[cc lang="PowerShell"]
PS S:\> get-history
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
Id CommandLine
-- -----------
1 get-date
2 $stats=dir *.ps1 | measure-object -Property Length -sum
3 $stats.count
[/cc]
You can also retrieve specific history items by their id number.
[cc lang="PowerShell"]
PS S:\> get-history 3
Id CommandLine
-- -----------
3 $stats.count
[/cc]
But this is an object which means it has properties.
[cc lang="PowerShell"]
PS S:\> get-history 3 | get-member
TypeName: Microsoft.PowerShell.Commands.HistoryInfo
Name MemberType Definition
---- ---------- ----------
Clone Method Microsoft.PowerShell.Commands.HistoryInfo Clone()
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
CommandLine Property System.String CommandLine {get;}
EndExecutionTime Property System.DateTime EndExecutionTime {get;}
ExecutionStatus Property System.Management.Automation.Runspaces.PipelineState ...
Id Property System.Int64 Id {get;}
StartExecutionTime Property System.DateTime StartExecutionTime {get;}
[/cc]
The CommandLine property is what we are after. In my script, I get either all command history or selected items and "export" the commandline parameter to a text file. I made this more of a convert script by including a custom header at the beginning of the file. Take a look at the script.
[cc lang="PowerShell"]
Param(
[Parameter(Position=0,Mandatory=$True,HelpMessage="Enter the filename and path for the script file",
ValueFromPipeline=$False)]
[ValidateNotNullorEmpty()]
[string]$Path,
[Parameter(Mandatory=$False,ValueFromPipeline=$True)]
[int64[]]$ID,
[switch]$NoClobber
)
Begin {
Set-StrictMode -Version 2.0
Write-Verbose "Starting $($myInvocation.mycommand)"
#delete the script if it already exists
if ((Test-Path -Path $Path) -AND ($NoClobber))
{
$msg="$path already exists and NoClobber was specified."
Write-Warning $msg
#bail out
Exit
}
Elseif (Test-Path -Path $path)
{
Write-Verbose "Removing existing version of $path"
Remove-Item $Path
}
#get the file name and convert the last part to upper case
$FileName=(Split-Path -Path $path -Leaf).ToUpper()
#add a brief header
$header=@"
#Requires -Version 2.0
# $Filename
# Generated from PowerShell History $(Get-Date)
# Author: $env:username
# $("-"*80)
"@
$header | Out-File -FilePath $Path -Encoding ASCII
$history=@()
} #close Begin
Process {
if ($id)
{
foreach ($i in $id)
{
Write-Verbose "Retrieving history item $([string]$i) $((Get-history -id $i).CommandLine)"
$history+= Get-History -id $i
}
}
else
{
Write-Verbose "Retrieve All History"
$history=Get-History -count $maximumhistorycount
}
} #close Process
End {
Write-Verbose "Writing $($history.count) history commands to $path"
Add-Content -Path $path -Value ($history | select -expandproperty commandline ) -Encoding ASCII
#write the file object to the pipeline
Write-Verbose "Writing script file object to the pipeline"
Get-Item -Path $path
Write-Verbose "Finished"
} #close End
[/cc]
Unlike my other posts, this is written as a script. Let's assume I have this command line history.
[cc lang="PowerShell"]
PS S:\> get-history
Id CommandLine
-- -----------
1 get-date
2 get-process
3 get-service
4 get-wmiobject win32_operatingsystem | select *
[/cc]
Now to convert it to a script.
[cc lang="PowerShell"]
PS S:\> .\Convert-HistoryToScript.ps1 MyScript.ps1
Directory: C:\scripts
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 1/10/2011 11:36 AM 298 MyScript.ps1
[/cc]
The script writes the file object to the pipeline. Here's the end result.
[cc lang="PowerShell"]
#Requires -Version 2.0
# MYSCRIPT.PS1
# Generated from PowerShell History 01/10/2011 11:36:51
# Author: Jeff
# --------------------------------------------------------------------------------
get-date
get-process
get-service
get-wmiobject win32_operatingsystem | select *
get-history
[/cc]
Of course, rarely do you get everything correct so you will most likely want to edit the file to clean it up. Or you can pipe in a collection of history ID numbers. Look at the script's help for a few examples. I hope you'll let me know if you find this useful.
Download Convert-HistoryToScript.
1 thought on “Convert History to Script”
Comments are closed.