{"id":3974,"date":"2013-03-24T00:01:00","date_gmt":"2013-03-24T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/03\/24\/weekend-scripter-convert-word-documents-to-pdf-files-with-powershell\/"},"modified":"2013-03-24T00:01:00","modified_gmt":"2013-03-24T00:01:00","slug":"weekend-scripter-convert-word-documents-to-pdf-files-with-powershell","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/weekend-scripter-convert-word-documents-to-pdf-files-with-powershell\/","title":{"rendered":"Weekend Scripter: Convert Word Documents to PDF Files with PowerShell"},"content":{"rendered":"<p><strong>Summary<\/strong>: Windows PowerShell MVP, Sean Kearney, talks about using Windows PowerShell to convert Word documents to PDF files en-masse.<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Today&rsquo;s blog is brought to you by Windows PowerShell MVP and honorary Scripting Guy, Sean Kearney.<\/p>\n<p style=\"padding-left: 30px\"><a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/tags\/sean+kearney\/\" target=\"_blank\">Previous blog posts by Sean Kearney<\/a><\/p>\n<p>Take it away Sean&hellip;<\/p>\n<p>My boss looks up at me today, and sighs, &ldquo;I love the built-in <strong>SaveAs PDF<\/strong> in Word 2013. But I want to do multiple documents at the same time. Oh, if ONLY there was some way to do this in bulk.&rdquo;<\/p>\n<p>The wires and lights starting blinking in my head. I&rsquo;m about to leap out of my chair because I hear &ldquo;Bulk.&rdquo; Many to do, repeatable, and&hellip;<\/p>\n<p>POWERSHELL!<\/p>\n<p>So accessing a file in Microsoft Word programmatically is quite easy. We&rsquo;ve been doing it for years.<\/p>\n<p style=\"padding-left: 30px\">$Word=NEW-OBJECT &ndash;COMOBJECT WORD.APPLICATION<\/p>\n<p style=\"padding-left: 30px\">$Doc=$Word.Documents.Open(&ldquo;C:\\Foofile.docx&rdquo;)<\/p>\n<p>And along the same lines, we could save this same file in the following manner.<\/p>\n<p style=\"padding-left: 30px\">$Doc.saveas([ref] &ldquo;C:\\Foofile.docx&rdquo;)<\/p>\n<p>If we would like to save it in an alternate format, like in .pdf format, things get a wee bit fancier. We have to speak a bit of .NET.<\/p>\n<p style=\"padding-left: 30px\">$Doc.saveas([ref] &ldquo;C:\\Foofile.pdf&rdquo;, [ref] 17)<\/p>\n<p>If your brain didn&rsquo;t pop out just now, you&rsquo;re OK. Let&rsquo;s get a little fancier. What if I want Microsoft Word to save that PDF file with the same name as the parent without knowing the name?<\/p>\n<p>Now we&rsquo;re stepping into the land of fun. We can access the file name of that single document in the following way. Three of the available properties in the Word object are the <strong>Name<\/strong> of the document, the <strong>Path<\/strong> to the document, and the <strong>FullName<\/strong> path. I poked out using the following cmdlet to&hellip;well, to be honest&hellip;to guess.<\/p>\n<p style=\"padding-left: 30px\">$Doc | get-member &ndash;membertype property *Name*<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2275.wes-3-24-13-1.jpg\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2275.wes-3-24-13-1.jpg\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>Note the two little nuggets. In poking about and using a similar search for <strong>Path<\/strong>, &nbsp;I found&nbsp;the property holding its path.<\/p>\n<p style=\"padding-left: 30px\">$Doc | get-member &ndash;membertype property *Path*<\/p>\n<p>So I could do something like this: Open some file, get the file name information, swap out .docx with .pdf, and then save it.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3681.wes-3-24-13-2.jpg\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3681.wes-3-24-13-2.jpg\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>With these three bits of information, I don&rsquo;t have to actually know &nbsp;the file name. Word will tell me based on the document. But let&rsquo;s simplify this down a bit. Let&rsquo;s just take a known file name and resave it as a PDF file with the same file name. All we need to do is run a <strong>Replace()<\/strong> method on the provided file name, and swap .docx with .pdf.<\/p>\n<p>Yes&hellip;.we&rsquo;re presuming it&rsquo;s a .pdf, J.<\/p>\n<p style=\"padding-left: 30px\">$File=&rdquo;C:\\Foofolder\\foofile.docx&rdquo;<\/p>\n<p style=\"padding-left: 30px\">$Word=NEW-OBJECT &ndash;COMOBJECT WORD.APPLICATION<\/p>\n<p style=\"padding-left: 30px\">$Doc=$Word.Documents.Open($File)<\/p>\n<p style=\"padding-left: 30px\">$Doc.saveas([ref] (($File).replace(&ldquo;docx&rdquo;,&rdquo;pdf&rdquo;)), [ref] 17)<\/p>\n<p style=\"padding-left: 30px\">$Doc.close()<\/p>\n<p>So that&rsquo;s all fine and dandy. But what if we have a folder of DOCX files that we want to convert at once?<\/p>\n<p>Let&rsquo;s pretend we ran the following lines in Windows PowerShell:<\/p>\n<p style=\"padding-left: 30px\">$File=&rdquo;C:\\Foofolder\\foofile.docx&rdquo;<\/p>\n<p style=\"padding-left: 30px\">$Files=GET-CHLDITEM &lsquo;C:\\FooFolder\\*.DOCX&rsquo;<\/p>\n<p>Now we could cheat and access the full file name and path by accessing the <strong>FullName<\/strong> from the drive system. But let&rsquo;s have some fun with Word and ask it these questions.<\/p>\n<p style=\"padding-left: 30px\">Foreach ($File in $Files) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; # open a Word document, filename from the directory<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $Doc=$Word.Documents.Open($File.fullname)<\/p>\n<p>Now let&rsquo;s ask Word what is the name of the file. And while we&rsquo;re at it, let&rsquo;s swap the .docx file extension with .pdf.<strong><\/strong><\/p>\n<p style=\"padding-left: 30px\">&nbsp; $Name=($Doc.Fullname).replace(&ldquo;docx&rdquo;,&rdquo;pdf&rdquo;)<\/p>\n<p>Then we&rsquo;ll access that file within Microsoft Word and use the built-in <strong>SaveAs PDF<\/strong> option in Word 2010 or Word 2013 to produce a PDF file in the same folder as the original Word document. When done, we close the file.<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $Doc.saveas([ref] $Name, [ref] 17)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $Doc.close()<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p>So when done our script will look like this:<\/p>\n<p style=\"padding-left: 30px\"># Acquire a list of DOCX files in a folder<\/p>\n<p style=\"padding-left: 30px\">$Files=GET-CHLDITEM &lsquo;C:\\FooFolder\\*.DOCX&rsquo;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Foreach ($File in $Files) {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; # open a Word document, filename from the directory<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $Doc=$Word.Documents.Open($File.fullname)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; # Swap out DOCX with PDF in the Filename<\/p>\n<p style=\"padding-left: 30px\">$Name=($Doc.Fullname).replace(&ldquo;docx&rdquo;,&rdquo;pdf&rdquo;)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; # Save this File as a PDF in Word 2010\/2013<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $Doc.saveas([ref] $Name, [ref] 17)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $Doc.close()<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p>So why the big secrecy about using the document names in Word itself? In the future, I&rsquo;ll show you how to programmatically trigger a mail merge, and you&rsquo;ll see where it&rsquo;s needed there.<\/p>\n<p>Cheers and remember to keep on scriptin&rsquo;.<\/p>\n<p>~Sean,<br \/> The Energized Tech<\/p>\n<p>Thanks, Sean, for taking the time to share your scripting expertise with us today. Join me tomorrow when I have a guest blog post from Ingo Karstein about using Windows PowerShell with SharePoint. It is cool and you do not want to miss it.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Ed Wilson, Microsoft Scripting Guy<\/strong>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Windows PowerShell MVP, Sean Kearney, talks about using Windows PowerShell to convert Word documents to PDF files en-masse. Microsoft Scripting Guy, Ed Wilson, is here. Today&rsquo;s blog is brought to you by Windows PowerShell MVP and honorary Scripting Guy, Sean Kearney. Previous blog posts by Sean Kearney Take it away Sean&hellip; My boss looks [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[56,84,49,3,154,61,45],"class_list":["post-3974","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-guest-blogger","tag-microsoft-word","tag-office","tag-scripting-guy","tag-sean-kearney","tag-weekend-scripter","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Windows PowerShell MVP, Sean Kearney, talks about using Windows PowerShell to convert Word documents to PDF files en-masse. Microsoft Scripting Guy, Ed Wilson, is here. Today&rsquo;s blog is brought to you by Windows PowerShell MVP and honorary Scripting Guy, Sean Kearney. Previous blog posts by Sean Kearney Take it away Sean&hellip; My boss looks [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3974","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\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=3974"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3974\/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=3974"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=3974"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=3974"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}