Integrating Microsoft Word with PowerShell: Generate a Document

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 part two of this series, I’ll show you steps you can take to format the style of your Word document using PowerShell.

Create an Object for the Word App

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 two.

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

Insert Text in the Document with PowerShell

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:\> $ | select Name | foreach -begin {$props=@()} -proc {$props+="$($"}

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()

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.