Integrating Microsoft Word with PowerShell – Part 1

by Jeff Hicks - February 23, 2012
Printer Friendly Version

Overview

I’m assuming many of you use Windows PowerShell to create reports for servers, events and all the other items you come across in a Windows network. You probably create text files; perhaps even some nice HTML reports. But you can also use Microsoft Word, assuming you have it installed of course. In the next few articles, I want to guide you through incorporating Microsoft Word into your PowerShell work.

SharePoint 2010 Administration Training

SharePoint 2010 Administration course delivers 15 hours of training that will help you earn one of the most powerful Microsoft certifications in the industry. Gain the knowledge to pass the 70-667 and the skills to setup, deploy, configure, and manage a real SharePoint environment.

SharePoint 2010 Administration Training - Available at TrainSignal

The Word application can be controlled via a COM interface in PowerShell. What is very interesting is that you can do all of this in an interactive session, although I expect you’ll eventually script everything. We’ll start by creating an object for the Word application.

PS C:\> $word=new-object -ComObject "Word.Application"

If you are curious, pipe the object to Get-Member. We’re going to be creating a hierarchy of objects, any of which you can pipe to Get-Member to explore.

Next we need a new document object.

PS C:\> $doc=$word.documents.Add()

At this point, Word is running with a new document, but you won’t see anything on your desktop. Normally this is fine since we want this to happen behind the scenes anyway. But if you’d like to view the document as it is being created set the application’s Visible property to True.

PS C:\> $word.Visible=$True

Before we can start inserting text, we need to get focus. Creating a selection object will also let us do things like setting font size and color which we’ll look at in Part 2.

PS C:\> $selection=$word.Selection

The cursor is now at the top of the document ready for some text. We use the Selection object’s TypeText() method. I’m going to insert the current date and time.

PS C:\> $selection.TypeText((Get-Date))

If we inserted more text it would be inserted immediately after the date. Use the TypeParagraph() method to insert a return.

PS C:\> $selection.TypeParagraph()

Let’s insert some more text. I’m going to get operating system information for the local computer via WMI.

PS C:\> $os=Get-WmiObject -class win32_OperatingSystem

PS C:\> $selection.TypeText("Operating System Information for $($os.CSName)")

Because I want to write all non-System properties, I’m going to quickly build an array to hold property names.

PS C:\> $os.properties | select Name | foreach -begin {$props=@()} -proc {$props+="$($_.name)"}

Now I can get all the properties from $os and insert into the Word document. It is important that the value for TypeText() be treated as a string so I’m going to pipe my nested PowerShell expression to Out-String.

PS C:\> $selection.TypeText(($os | Select -Property $props | Out-String))

I can continue inserting text and paragraphs for as long as I need. When I’m finished, I’ll save and close the document.

PS C:\> $doc.SaveAs([ref]"c:\work\osreport.docx")

PS C:\> $doc.Close()

Be sure to use the [ref] cast for the file path. All that remains is to wrap up the Word application, assuming I don’t want to create a new document.

PS C:\> $word.quit()

Conclusion

And that’s all there is to it!  The final word document is functional, although perhaps not too pretty. One issue, at least with my example here, is that Word uses a variable width font but PowerShell’s formatting assumes a fixed width font. In Part 2 I’ll show you how overcome these limitations. In the meantime, feel free to download the sample script New-WordDoc.ps1.

Related Articles



Sign Up For the Petri IT Knowledgebase Weekly Digest!

*