Many of you seemed to like my little PowerShell ISE add-on to send text from the script pane to a Word document. I should have known someone would ask about a way to make it colorized. You can manually select lines in a script and when you paste them into Word they automatically inherit the colorized tokens. Unfortunately, coming up with a PowerShell equivalent is much more complicated.
If you search around you'll find plenty of tools and scripts for generating HTML and colorized output from the ISE. I tried incorporating some of them into my script but they were much more complicated than I wanted to deal with. All I really needed was a simple Ctrl+C command. So I cheated. I decided to use the SendKeys() method from VBScript.
if ($Colorized) {
#copy the selection to the clipboard and paste
#This is a shortcut hack that may not always work the first time
$wshell = New-Object -ComObject Wscript.shell
#must be lower-case c otherwise you will end up sending
#ctrl+shift+c
$wshell.SendKeys("^c")
#timing is everything with SendKeys. This could be a lower value
start-sleep -Milliseconds 500
$global:selection.Paste()
}
I added a new switch parameter to the function called Colorized. This meant I also needed an additional menu shortcut.
$psise.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("Send to Word Colorized",{Send-ToWord -Colorized},"") | Out-Null
You'll notice that there is no keyboard shortcut. At least for me, I got inconsistent results using a keyboard shortcut, and often nothing. But if I selected the menu item, it always seemed to work.
Here is the complete updated function.
#requires -version 3.0
#this is an ISE only function
Function Send-ToWord {
[cmdletbinding()]
Param(
[ValidatePattern("\S+")]
[string[]]$Text = $psise.CurrentFile.Editor.SelectedText,
[switch]$Colorized
)
If (($global:word.Application -eq $Null) -OR -NOT (Get-Process WinWord)) {
#remove any variables that might be left over just to be safe
Remove-Variable -Name doc,selection -Force -ErrorAction SilentlyContinue
#create a Word instance if the object doesn't already exist
$global:word = New-Object -ComObject word.application
#create a new document
$global:doc = $global:word.Documents.add()
#create a selection
$global:selection = $global:word.Selection
#set font and paragraph for fixed width content
$global:selection.Font.Name = "Consolas"
$global:selection.font.Size = 10
$global:selection.paragraphFormat.SpaceBefore = 0
$global:selection.paragraphFormat.SpaceAfter = 0
#show the Word document
$global:word.Visible = $True
}
if ($Colorized) {
#copy the selection to the clipboard and paste
#This is a shortcut hack that may not always work the first time
$wshell = New-Object -ComObject Wscript.shell
#must be lower-case c otherwise you will end up sending
#ctrl+shift+c
$wshell.SendKeys("^c")
#timing is everything with SendKeys. This could be a lower value
start-sleep -Milliseconds 500
$global:selection.Paste()
}
else {
#insert the text
$global:selection.TypeText($text)
}
#insert a new paragraph (ENTER)
$global:selection.TypeParagraph()
} #end Function
#add to menu
$psise.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("Send to Word",{Send-ToWord},"Ctrl+Alt+W") | Out-Null
#keyboard shortcut doesn't always work
$psise.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("Send to Word Colorized",{Send-ToWord -Colorized},"") | Out-Null
I can't guarantee the color copy and paste will work 100% of the time. Otherwise, you can always use traditional keyboard shortcuts: Ctrl+C,Alt+Tab (to Word), Ctrl+V.
Enjoy.