Learn about Windows PowerShell
Hey, Scripting Guy! I have a rather strange question. Do you know how to add a reference to a document in Microsoft Word? I am not talking about by using the GUI tools, but by using a Windows PowerShell or a VBScript to add a reference at the bottom of a page in a document. I am not trying to play "stump the chump." I really do have a good reason for asking this. I have a document at work that contains a paragraph I copied out of a book, and I would like to give credit to the book from whence the information was gathered. I do not want to do a formal footnote thing like I did in college, but I do think that some kind of reference would be appropriate to show that I did not plagiarize anything. I figure that as a writer you would appreciate my honesty. What do you say?
Microsoft Scripting Guy Ed Wilson here. I have spent much of the morning today on Twitter, answering questions, tweeting, and retweeting. It is a cool rainy morning, and I am munching on a bowl of raw walnuts and a small piece of 85% Cacao chocolate, and I’m enjoying a pot of freshly brewed English Breakfast tea with lemon grass and a stick of ceylon cinnamon. I am listening to Weather Report this morning on my Zune, as I monitor both Twitter and incoming e-mail sent to email@example.com. It is a wonderful day and a great morning to be up early and hanging out with virtual friends (as opposed to imaginary friends who hung out with me when I was a child).
Write a script to add end notes to a Word document? Dude (or dudette), why didn't I think of that? Obviously I can do it, but I never thought of such a thing. Man, oh man, how much different my life would have been when I was in graduate school (along with my good friend, Fred Flintstone). If I could have scripted my references instead of wrestling with a manual typewriter and Kate Turabian, I might have been able to spend more time in town, instead of in the library. Life would have been more fun, or at the very least, my studies would have been more efficient.
Because of the cool jazz from Weather Report, the caffeine from the English Breakfast tea, and the rush from the 85% Cacao, I am susceptible to suggestion. I loved your suggestion for adding end notes to a Word Document so much that I wrote the AddEndNote.ps1 script for you. The complete AddEndNote.ps1 script is shown here.
$Text = "Windows PowerShell Best Practices, Microsoft Press, Forthcoming, Ed Wilson"$document = "C:\fso\WhyUsePs2.docx"$word = New-Object -ComObject word.application$word.Visible = $false$doc = $word.Documents.Open($document)$range = $doc.Paragraphs.item(4).range$endNotes = $doc.endNotes$endNotes.Add($range,"reference",$text) | Out-Null$doc.Save()$doc.close()$word.quit()
Before jumping into the AddEndNote.ps1 script, look at the following image, which includes an excerpt from the Microsoft Press book, Windows PowerShell 2.0 Best Practices, by yours truly:
Because the material is excerpted from a book, I need to add attribution to the selection—the AddEndNote.ps1 script is used to do that. The first step is to initialize:
$Text = "Windows PowerShell Best Practices, Microsoft Press, Forthcoming, Ed Wilson"
$document = "C:\fso\WhyUsePs2.docx"
Next you need to create the word.application object, which is the main object used in working with Microsoft Word automation. In nearly every case of Microsoft Word automation, you will need to first create the application object. In the AddEndNote.ps1 script, the application object is stored in the $word variable. This is shown here:
$word = New-Object -ComObject word.application
After you have the word.application object stored in a variable, you need to decide if you wish to make the Microsoft Word visible or invisible. When I am in the process of writing my script, I will generally make the Microsoft Word document visible. After I have the script working properly, I will make it invisible. To control the visibility of the Microsoft Word document, you need to set the appropriate value for the visible property. To make the Microsoft Word document visible, you set the visible property to $true. To make the Microsoft Word document invisible, you set the visible property to $false. This is shown here:
$word.Visible = $false
After the word.application object has been created, the Documents property is queried to return a documents collection object. The documents collection object provides the open method, which you use to open a Microsoft Word document. The open method returns a document object that is stored in the $doc variable. This is shown here:
$doc = $word.Documents.Open($document)
After the document object has been created, the paragraphs property is used to return a paragraphs collection object. To return a specific paragraph object from the paragraphs collection object, you use the item method from the paragraphs collection object. Paragraph numbering begins at one and includes headings in the count. The paragraph object supplies a range property. When you query the range property, it returns a range object. The range object is stored in the $range variable as seen here:
$range = $doc.Paragraphs.item(4).range
The endnotes property of the document object is used to return an endnotes collection object. The endnotes collection object is stored in the $endNotes variable as shown here:
$endNotes = $doc.endNotes
After you have an endnotes collection object, you can use the add method to add an endnote to the document. The add method accepts three parameters: The first is the range object that represents the location for placement of the endnote; the second is the text for the custom reference mark; and the last parameter is the text of the endnote. When the add method is called, it returns an endnote object. Because I am not using the returned endnote object in the script, I pipe it to the Out-Null cmdlet. This is shown here:
$endNotes.Add($range,"reference",$text) | Out-Null
After the endnote has been added to the Microsoft Word document, it is time to clean up the scripting environment. To do this, the save method is called from the document object to save the changes to the Microsoft Word document. After the changes have been saved, the close method from the document object is called to close the document. And after the document has been closed, it is time to call the quit method from the application object.
If you do not call the quit method from the application object, you will leave an instance of Microsoft Word running in memory. If you are running several scripts and you do not call the quit method, it would be possible to consume all of your available memory on your computer, and it would cause performance problems at the very least. In the worst case scenario, it might be possible to crash your computer. As a best practice when scripting any Microsoft Office product, ensure you properly clean up after the script.
The cleanup code for the AddEndNote.ps1 script is shown here:
When the AddEndNote.ps1 script is run, it adds a reference mark to the end of the last paragraph and adds an endnote at the bottom of the page. This is shown here:
TL, that was such a cool suggestion, and it was fun too!
If you want to know exactly what we will be looking at tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at firstname.lastname@example.org or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson and Craig Liebendorfer, Scripting Guys