Convert Transcript to Script

During my PowerShell scripting best practices at Techmentor last week I mentioned a function I had to convert a PowerShell transcript to a script file. Since there’s very little difference between an interactive session and a script, parsing the transcript can yield 80% or more of a script very quickly. I wrote such a function several years ago. What I was really thinking about was my convert history to script function. But, since I mentioned it and a few people have asked, I’ve dusted off the transcript to script function and polished it up for PowerShell 2.0.

This function is merely intended as a rapid prototyping tool, taking PowerShell expressions from your transcript and generating a PowerShell script file.

[cc lang="PowerShell"]
Function Convert-TranscriptToScript {

<#
.Synopsis
Convert a PowerShell transcript to a script.
.Description
This function will parse out all commands from a PowerShell transcript and create a PowerShell script file
that you can then continue to edit and flesh out. Existing script files will be overwritten unless you use
-NoClobber.

IMPORTANT: This function assumes your PowerShell prompt starts with PS and ends with >.
.Parameter Transcript
The file name and path of your transcript file.
.Parameter ScriptFile
The filename and path for your new script. Existing files will be overwritten.
.Parameter NoClobber
Do not overwrite an existing script file. A warning will be displayed and the transcript
will not be processed.
.Example
PS C:\> Convert-TranscripttoScript “c:\work\trans.txt” “c:\scripts\NewScript.ps1″
Finished parsing c:\work\trans.txt. See c:\scripts\NewScript.ps1 for your script.

.Notes
NAME: Convert-TranscriptToScript
AUTHOR: Jeffery Hicks
VERSION: 1.0
LASTEDIT: 03/19/2011

Learn more with a copy of Windows PowerShell 2.0: TFM (SAPIEN Press 2010)

.Link

http://jdhitsolutions.com/blog/2011/03/convert-transcript-to-script/

.Link
Start-Transcript
about_Regular_Expressions

.Inputs
None

.Outputs
None
#>

Param (
[Parameter(Position=0,Mandatory=$True,HelpMessage="You need to specify a transcript file name and path.")]
[ValidateNotNullOrEmpty()]
[ValidateScript({Test-Path $_})]
[string]$Transcript,
[Parameter(Position=1,Mandatory=$True,HelpMessage="You need to specify a filename for the new script.")]
[ValidateNotNullorEmpty()]
[string]$ScriptFile,
[Switch]$NoClobber
)

#If -NoClobber make sure file doesn’t already exist
if ($NoClobber -AND (Test-Path -Path $ScriptFile))
{
Write-Warning “NoClobber specified and $ScriptFile already exists. Try again with a new name.”
}
else
{
#Create new file and overwrite any existing file
#This is a script header
“# Script Created $(Get-Date)” | Out-File -filepath $ScriptFile
“# Source file: $Transcript” |Out-File -filepath $ScriptFile -append
“# Author: $env:userdomain\$env:username” | Out-File -filepath $ScriptFile -append
#insert a blank line
write `n | Out-File -filepath $ScriptFile -append

#get all the lines that start with PS which should be part of a prompt.
#and filter out the stop-transcript line
#if you have a custom prompt that doesn’t start with PS this probably won’t work for you. Or
#you will need to modify the regular expression

[regex]$r=”^(? PS(.+?)>)”
$filteredLog=Get-Content $Transcript | Select-String -pattern $r | where {$_ -notmatch “stop-transcript”}

$filteredLog | Foreach {
#each object in $filteredLog is a MatchInfo object which needs to be converted to a string
#Then split the string into an array using the regular expression
$lines=$r.Split($_)
#$_.ToString().split(“>”)
#trim off spaces on the last element and write to the script file
$lines[-1].Trim() | Out-File -filepath $ScriptFile -append
}
#add a closing comment
write “`n#End of script” | Out-File -filepath $ScriptFile -append

Write-Host “Finished parsing $Transcript. See $ScriptFile for your script.” -ForegroundColor Green
} #else
} #end function
[/cc]

The function makes an assumption that you aren’t using a custom prompt as it uses a regular expression to match the default prompt in each line of text of the transcript.

[cc lang="PowerShell"]
#get all the lines that start with PS which should be part of a prompt.
#and filter out the stop-transcript line
#if you have a custom prompt that doesn’t start with PS this probably won’t work for you. Or
#you will need to modify the regular expression

[regex]$r=”^(? PS(.+?)>)”
$filteredLog=Get-Content $Transcript | Select-String -pattern $r | where {$_ -notmatch “stop-transcript”}
[/cc]

My regular expression pattern is defined with a named group, path, but I don’t really use it. Insted the function goes through each line of the filtered log and splits it on the matching pattern.

[cc lang="PowerShell"]
$filteredLog | Foreach {
#each object in $filteredLog is a MatchInfo object which needs to be converted to a string
#Then split the string into an array using the regular expression
$lines=$r.Split($_)
#trim off spaces on the last element and write to the script file
$lines[-1].Trim() | Out-File -filepath $ScriptFile -append
}
[/cc]
In my version I’ve created an alias, cts. Here’s an example of taking a transcript and creating a script file.

[cc lang="PowerShell"]
PS S:\> cts C:\Users\Jeff\Documents\PowerShell_transcript.20110321073839.txt -ScriptFile e:\temp\TestScript.ps1
Finished parsing C:\Users\Jeff\Documents\PowerShell_transcript.20110321073839.txt. See e:\temp\TestScript.ps1 for your script.
[/cc]

My function isn’t especially fancy, although it does have a -NoClobber parameter so that it doesn’t overwrite any existing files. Personally, I prefer my Convert-HistoryToScript function since I don’t always remember to start a transcript. But, Convert-TranscriptToScript if you get a transcript from somewhere like a class or colleague and would like to turn it into a script. In any event I hope you’ll let me know how this works for you.

Download Convert-TranscriptToScript.