{"id":54943,"date":"2008-11-06T11:16:00","date_gmt":"2008-11-06T11:16:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/11\/06\/hey-scripting-guy-how-can-i-format-a-microsoft-word-paragraph\/"},"modified":"2008-11-06T11:16:00","modified_gmt":"2008-11-06T11:16:00","slug":"hey-scripting-guy-how-can-i-format-a-microsoft-word-paragraph","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-format-a-microsoft-word-paragraph\/","title":{"rendered":"Hey, Scripting Guy! How Can I Format a Microsoft Word Paragraph?"},"content":{"rendered":"<p><H2><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\"> <\/H2>\n<P>Hey, Scripting Guy! I have really been enjoying the recent Windows PowerShell articles on the Script Center. I am wondering if it is possible to use Windows PowerShell to work with a Microsoft Office Word document. Specifically, what I would like to be able to do is to change the paragraph formatting and perhaps add a border. I may be asking too much, but I guess I can always hope.<BR><BR>&#8211; DP<\/P><IMG height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\"> \n<P>Hi DP,<\/P>\n<P>I am glad you want to format a paragraph, rather than format say, for instance, your hard disk. If you did format your hard disk, you would not have any more paragraph problems. But then just because you can do something, does not mean you should do something. So maybe you better not format your hard drive\u2014at least not yet. <\/P>\n<P>Rather than opening up the Word document and then selecting the paragraphs and the changing the font size and then highlighting the last sentence and then selecting the border icon, we need to come up with a way to automate this process in Word. In fact, after spending an hour on the treadmill trying to format my stomach, I came up with the <B>FormatWordParagraph.ps1<\/B> script. I am still working on the <B>FormatStomach.ps1<\/B> script (so far, I have been unable to come up with a good API to use, other than the treadMill API, which, while it works pretty good, is rather difficult to use). Here is the <B>FormatWordParagraph.ps1<\/B> script. (By the way, there is a <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/sept07\/hey0924.mspx\">VBScript here<\/A> that works with Word that might be interesting to look at for comparison. In addition, there are quite a few VBScripts for Microsoft Office in the <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/scripts\/office\/default.mspx\">Script Center Script Repository<\/A>. You may want to take a look at the <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/scripts\/default.mspx\">Script Repository&#8217;s home page<\/A> as well.) <\/P>\n<P><B>FormatWordParagraph.ps1<\/B><\/P><PRE class=\"codeSample\">$filePath = &#8220;c:\\fso\\test.doc&#8221;\n$word = New-Object -comobject word.application\n$word.visible = $true\n$doc = $word.documents.open($filePath)\n$paragraphs = $doc.paragraphs\n$paragraphs.indentFirstLineCharWidth(2)\n$lineStyle = &#8220;microsoft.office.interop.word.wdlLineStyle&#8221; -as [type]\n$colorIndex = &#8220;microsoft.office.interop.word.wdColorIndex&#8221; -as [type]\n$lineWidth = &#8220;microsoft.office.interop.word.WdLineWidth&#8221; -as [type]\n$borderType = &#8220;microsoft.office.interop.word.wdBorderType&#8221; -as [type]\nForeach($paragraph in $paragraphs)\n{\n $paragraph.Range.font.size = 10\n}\n $border = $paragraphs.item(&#8220;1&#8221;).borders.item($borderType::wdBorderBottom)\n $border.lineStyle = $lineStyle::wdLineSingle\n $border.ColorIndex = $colorIndex::wdAuto\n $border.lineWidth = $lineWidth::wdLineWidth225p\n $border.visible = $true\n$doc.save()\n$word.quit()<\/PRE>\n<P>Well,&nbsp;DP, this script is about as difficult as falling off a boat with 50 pounds of scuba gear strapped on. After you get your momentum going, it just happens. As they said while I was diving in the Little Caymans two weeks ago, &#8220;pool&#8217;s open&#8221; (not sure why they say that, it must be Caymanian for &#8220;get your happy butt off my boat.&#8221;) The pool&#8217;s open\u2014let&#8217;s dive in. But before we do, here&#8217;s the Word document we are going to work on:<\/P><IMG height=\"368\" alt=\"Image of the newly modified Word document\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/hey1106\/hsg_wordparagraph1.jpg\" width=\"450\" border=\"0\"> \n<P>&nbsp;<\/P>\n<P>The first line of code is very simple. We simply assign a string that represents the path to the file we want to open. Remember in Windows PowerShell we use a dollar sign in front of all variables. This makes it easy to know that we are working with a variable. This is seen here: <\/P><PRE class=\"codeSample\">$filePath = &#8220;c:\\fso\\test.doc&#8221;<\/PRE>\n<P>The next thing we need to do is to create an instance of the <B>word.application<\/B> object. To do this, we use the <B>New-Object<\/B> cmdlet and use the <B>-comobject<\/B> parameter to create the object. We store the returned object in the <B>$word<\/B> variable as seen here: <\/P><PRE class=\"codeSample\">$word = New-Object -comobject word.application<\/PRE>\n<P>When we have a copy of the <B>word.application<\/B> object, we can use it in many different ways. Here is the <A href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb225979.aspx\">documentation on MSDN<\/A> that discusses this object. Stay tuned for more &#8220;Hey, Scripting Guy!&#8221; articles using some of these methods. <\/P>\n<P>Now we have a decision to make, DP. Do you want to see what is going on or not? This is not necessarily a rhetorical question. In our script, we are making it visible because it makes for an interesting demo. However, if you want to modify several hundred Word documents, watching the show would be more boring than an old <A href=\"http:\/\/en.wikipedia.org\/wiki\/Car_54%2C_Where_Are_You%3F\">Car 54, Where Are You?<\/A> rerun. To make the Word document visible, we simply set the visible property to be equal to <B>$true<\/B> as seen here: <\/P><PRE class=\"codeSample\">$word.visible = $true<\/PRE>\n<P>Then we need to open the document: <\/P><PRE class=\"codeSample\">$doc = $word.documents.open($filePath)<\/PRE>\n<P>Next we need to get the collection of paragraphs: <\/P><PRE class=\"codeSample\">$paragraphs = $doc.paragraphs<\/PRE>\n<P>After we have the paragraphs collection, we indent the first line of each paragraph by two spaces. This is easy to do: <\/P><PRE class=\"codeSample\">$paragraphs.indentFirstLineCharWidth(2)<\/PRE>\n<P>Now for something that is very cool with Windows PowerShell. It looks a little bit ugly, but it is very cool nonetheless. We are going to use Word enumeration values for <A href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb213915.aspx\">border line style<\/A>, <A href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb237561.aspx\">border color<\/A>, <A href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb213925.aspx\">border width<\/A>, and <A href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb213697.aspx\">border type<\/A>&nbsp;(but not <A href=\"http:\/\/en.wikipedia.org\/wiki\/Border_Collie\">border collie<\/A>): <\/P><PRE class=\"codeSample\">$lineStyle = &#8220;microsoft.office.interop.word.wdlLineStyle&#8221; -as [type]\n$colorIndex = &#8220;microsoft.office.interop.word.wdColorIndex&#8221; -as [type]\n$lineWidth = &#8220;microsoft.office.interop.word.WdLineWidth&#8221; -as [type]\n$borderType = &#8220;microsoft.office.interop.word.wdBorderType&#8221; -as [type]<\/PRE>\n<P>What is so cool about being able to use enumeration values? Let\u2019s look at one of the enumerations in Table 1. As you can see in Table 1, Word defines a number of values that are used to control the width of a line that is used for the border. In VBScript, you would typically create a constant and assign the number from the value column, and then use it in the script. In VB.NET or in C#, you would use the enumeration directly. In Windows PowerShell, we can also use the enumeration. For each of the enumeration types we create, we place the name of the type, and then we use the <B>-as<\/B> operator to tell it we want to use the variable as a particular type. Even though the code may look a little confusing, all we really did was copy the name of the enumeration we found in MSDN, and then assign it to the variable as a type. <\/P>\n<P><B>Table 1 WdLineWidth Enumeration Values <\/B><\/P>\n<TABLE class=\"dataTable\" id=\"EBG\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD>\n<TR class=\"stdHeader\" vAlign=\"top\">\n<TD class=\"\" id=\"colEDG\">Name<\/TD>\n<TD class=\"\" id=\"colEHG\">Value<\/TD>\n<TD class=\"\" id=\"colELG\">Description<\/TD><\/TR><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\">wdLineWidth025pt<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">2<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">0.25 points<\/P><\/TD><\/TR>\n<TR class=\"evenRecord\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\">wdLineWidth050pt<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">4<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">0.50 points<\/P><\/TD><\/TR>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\">wdLineWidth075pt<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">6<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">0.75 points<\/P><\/TD><\/TR>\n<TR class=\"evenRecord\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\">wdLineWidth100pt<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">8<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">1.00 points (default)<\/P><\/TD><\/TR>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\">wdLineWidth150pt<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">12<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">1.50 points<\/P><\/TD><\/TR>\n<TR class=\"evenRecord\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\">wdLineWidth225pt<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">18<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">2.25 points<\/P><\/TD><\/TR>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\">wdLineWidth300pt<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">24<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">3.00 points<\/P><\/TD><\/TR>\n<TR class=\"evenRecord\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\">wdLineWidth450pt<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">36<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">4.50 points<\/P><\/TD><\/TR>\n<TR class=\"record\" vAlign=\"top\">\n<TD class=\"\">\n<P class=\"lastInCell\">wdLineWidth600pt<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">48<\/P><\/TD>\n<TD class=\"\">\n<P class=\"lastInCell\">6.00 points<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Now we want to change the font of our paragraphs. To do this, we use the <B>Foreach<\/B> statement, because the <B>paragraphs<\/B> property returns a collection of paragraphs. Just like in VBScript, we need to iterate through the collection, so we use <B>Foreach<\/B>. We use the variable <B>$paragraph<\/B> to represent one paragraph out of the collection. The font size is found in the <B>Range.font.size<\/B> property. We set this value equal to 10. The curly brackets indicate we have a code block. That is, the <B>$paragraph.Range.font.size = 10<\/B> code will be repeated once for each paragraph in the collection of paragraphs. This section of code is seen&nbsp;here: <\/P><PRE class=\"codeSample\">Foreach($paragraph in $paragraphs)\n{\n $paragraph.Range.font.size = 10\n}<\/PRE>\n<P>To set the border on the first paragraph, we use the <B>item<\/B> method from the paragraph collection that is held in the <B>$paragraphs<\/B> variable. We choose the first paragraph by supplying 1 to the <B>item<\/B> method. Now we get the borders collection by using the <B>borders<\/B> property, and again use the <B>item<\/B> method to retrieve a specific border. The border we want to draw is the bottom border. To do this we use the <B>wdBorderBottom<\/B> enumeration from the <B>wdBorderType<\/B> enumeration. We have stored this enumeration type in the variable <B>$borderType<\/B>. The secret here is the use of the double colon (<B>::<\/B>) to get our specific enumeration. This line of code is seen here: <\/P><PRE class=\"codeSample\">$border = $paragraphs.item(&#8220;1&#8221;).borders.item($borderType::wdBorderBottom) <\/PRE>\n<P>Next we use the enumerations we created earlier to supply the line style, the color, and the width of the bottom border we will draw. Notice that we use the same syntax, the property of the border, the enumeration, the double colon, and then the actual enumeration name that was taken from MSDN. This section of code is shown&nbsp;here: <\/P><PRE class=\"codeSample\"> $border.lineStyle = $lineStyle::wdLineSingle\n $border.ColorIndex = $colorIndex::wdAuto\n $border.lineWidth = $lineWidth::wdLineWidth225p<\/PRE>\n<P>Now we need to make the border visible. This works exactly the same way it would in VBScript: You set the visible property of the border to <B>true<\/B>. This is seen here: <\/P><PRE class=\"codeSample\">$border.visible = $true<\/PRE>\n<P>Finally, we want to save our changes, and quit Word. To do this we use the <B>save<\/B> method and the <B>quit<\/B> method. The only hard part here is that you save the document and you quit the Word application.<\/P>\n<P><B>Important note<\/B>: If you make the Word application invisible with <B>$word.visible = $false<\/B>, and you forget to quit Word, you can end up with multiple instances of <B>winword.exe<\/B> running on your system. If you are working with hundreds of Word documents\u2026well, let\u2019s just say you probably will not quite make it through hundreds of Word documents before your work station falls off the desk gasping for air and whining about lack of&nbsp;. <\/P><PRE class=\"codeSample\">$doc.save()\n$word.quit()<\/PRE>\n<P>You can see the newly modified Word document here:<\/P><IMG height=\"460\" alt=\"Image of the newly modified Word document\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/hey1106\/hsg_wordparagraph2.jpg\" width=\"600\" border=\"0\"> \n<P>&nbsp;<\/P>\n<P>So, DP, I hope this helps you with your Word paragraph and border problems. Stay tuned for more Word fun next time. Until then, take care.<\/P>\n<P><FONT class=\"Apple-style-span\" face=\"Verdana\" size=\"3\"><SPAN class=\"Apple-style-span\"><B><B>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/B><\/B><\/SPAN><\/FONT><\/P><FONT class=\"Apple-style-span\" face=\"Verdana\" size=\"3\"><B><\/B><\/FONT><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I have really been enjoying the recent Windows PowerShell articles on the Script Center. I am wondering if it is possible to use Windows PowerShell to work with a Microsoft Office Word document. Specifically, what I would like to be able to do is to change the paragraph formatting and perhaps add [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[84,49,3,45,395],"class_list":["post-54943","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-microsoft-word","tag-office","tag-scripting-guy","tag-windows-powershell","tag-word-application"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I have really been enjoying the recent Windows PowerShell articles on the Script Center. I am wondering if it is possible to use Windows PowerShell to work with a Microsoft Office Word document. Specifically, what I would like to be able to do is to change the paragraph formatting and perhaps add [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54943","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=54943"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54943\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=54943"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=54943"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=54943"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}