{"id":51693,"date":"2009-12-29T00:01:00","date_gmt":"2009-12-29T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2009\/12\/29\/hey-scripting-guy-how-can-i-list-all-the-properties-of-a-microsoft-word-document\/"},"modified":"2009-12-29T00:01:00","modified_gmt":"2009-12-29T00:01:00","slug":"hey-scripting-guy-how-can-i-list-all-the-properties-of-a-microsoft-word-document","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-list-all-the-properties-of-a-microsoft-word-document\/","title":{"rendered":"Hey, Scripting Guy! How Can I List All the Properties of a Microsoft Word Document?"},"content":{"rendered":"<p class=\"MsoNormal\"><a class=\"addthis_button\" href=\"http:\/\/www.addthis.com\/bookmark.php?v=250&amp;pub=scriptingguys\"><img decoding=\"async\" alt=\"Bookmark and Share\" src=\"http:\/\/s7.addthis.com\/static\/btn\/v2\/lg-share-en.gif\" width=\"125\" height=\"16\"><\/a>&nbsp;<\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<p><font size=\"2\"><img decoding=\"async\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"><\/font><\/p>\n<p class=\"MsoNormal\">Hey, Scripting Guy! I am trying to find a Windows PowerShell script that will list all the properties of a Microsoft Word document. I am not talking about the size and the date of the document; those are file properties. I am talking about stuff like the author, the subject, and those properties most people never know even exist for a document. Is this even possible?<\/p>\n<p class=\"MsoNormal\">&#8212; JM<\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\"><img decoding=\"async\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\">Hello JM, <\/p>\n<p class=\"MsoNormal\">Microsoft Scripting Guy Ed Wilson here. I wrote a similar article that illustrates accessing the meta data from a Microsoft Excel spreadsheet on October 9, 2008 (I was in Australia when I wrote <a href=\"http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2008\/10\/09\/how-can-i-read-microsoft-excel-metadata.aspx\"><font face=\"Segoe\">How Can I Read Microsoft Excel Metadata?<\/font><\/a>). I was looking through some of the pictures I took while I was in Sydney, such as the following one I took at the <a href=\"http:\/\/en.wikipedia.org\/wiki\/ANZAC_War_Memorial\"><font face=\"Segoe\">ANZAC War Memorial<\/font><\/a>. The ANZAC War Memorial is a beautiful art deco structure, and looking at it causes me to reminisce just a bit. I absolutely love taking pictures in Sydney because of the striking architecture found there. <\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of the ANZAC War Memorial\" alt=\"Image of the ANZAC War Memorial\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/december\/hey1229\/hsg-12-29-09-01.jpg\" width=\"600\" height=\"450\"><\/p>\n<p class=\"MsoNormal\"><br>JM, Get-WordProperties.ps1 opens a Microsoft Word document, and inspects the built-in document properties. If a property contains a value, the value is displayed; otherwise, a note is displayed in the Windows PowerShell console that states the property does not contain a value. The complete Get-WordProperties.ps1 script is seen here.<\/p>\n<p class=\"CodeBlockScreenedHead\"><strong>Get-WordProperties.ps1<\/strong><\/p>\n<p class=\"CodeBlockScreened\"><font face=\"Lucida Sans Typewriter\">$application = New-Object -ComObject word.application<br>$application.Visible = $false<br>$document = $application.documents.open(&#8220;C:dataScriptingGuys2009HSG_12_28_09Test.docx&#8221;)<br>$binding = &#8220;System.Reflection.BindingFlags&#8221; -as [type]<br>$properties = $document.BuiltInDocumentProperties<br>foreach($property in $properties)<br>{<br><span>&nbsp;<\/span>$pn = [System.__ComObject].invokemember(&#8220;name&#8221;,$binding::GetProperty,$null,$property,$null)<br><span>&nbsp; <\/span>trap [system.exception]<br><span>&nbsp;&nbsp; <\/span>{<br><span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>write-host -foreground blue &#8220;Value not found for $pn&#8221;<br><span>&nbsp;&nbsp;&nbsp; <\/span>continue<br><span>&nbsp;&nbsp; <\/span>}<br><span>&nbsp; <\/span>&#8220;$pn`: &#8221; +<br><span>&nbsp;&nbsp; <\/span>[System.__ComObject].invokemember(&#8220;value&#8221;,$binding::GetProperty,$null,$property,$null)<\/p>\n<p>}<br>$application.quit()<\/font><\/p>\n<p class=\"MsoNormal\">JM, if you read the Microsoft Excel metadata Hey, Scripting Guy! post I referred to earlier, you will recall that it took me two days to write the script to retrieve the metadata. The problem is that the process to retrieve the information is not documented. Whereas, the Microsoft Word automation model is documented, the use of the interfaces from Windows PowerShell was never intended and therefore we have to use some pretty tricky procedures to obtain the information. Luckily, the Microsoft Word automation model and the Microsoft Excel automation model are similar enough that I was able to leverage the two days of research, trial, and experimentation that led to the previous Hey, Scripting Guy! post. Because the two approaches are similar, I am not going to repeat all the background information from the <a href=\"http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2008\/10\/09\/how-can-i-read-microsoft-excel-metadata.aspx\"><font face=\"Segoe\">previous post<\/font><\/a>.<\/p>\n<p class=\"MsoNormal\">The basic Microsoft Word document properties are shown in the following image and are accessed by clicking the Office button in Office 2007, clicking <b>Prepare<\/b>, and then clicking <b>Properties:<\/b> <\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of Microsoft Word document properties\" alt=\"Image of Microsoft Word document properties\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/december\/hey1229\/hsg-12-29-09-02.jpg\" width=\"600\" height=\"420\"><\/p>\n<p class=\"MsoNormal\"><br>You can see the advanced document properties by opening the Document Properties drop-down list. The Document Properties dialog box is shown in the following image. As you can see, the Summary tab is completely filled out:<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Imageof Summary tab completely filled out\" alt=\"Imageof Summary tab completely filled out\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/december\/hey1229\/hsg-12-29-09-03.jpg\" width=\"385\" height=\"463\"><\/p>\n<p class=\"Fig-Graphic\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\">The Get-WordProperties.ps1 script begins by creating the <b>application<\/b> object. The <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb244569.aspx\">application object<\/a> is the main object that is used when automating Microsoft Word. To create the application object, use the <b>New-Object<\/b> cmdlet and the <b>&ndash;comObject<\/b> parameter with the <b>word.application<\/b> program ID. Store the returned <b>application<\/b> object in the <b>$application<\/b> variable, as shown here:<\/p>\n<p class=\"CodeBlockScreened\"><font face=\"Lucida Sans Typewriter\">$application = New-Object -ComObject word.application<\/font><\/p>\n<p class=\"MsoNormal\">There is no need for the Microsoft Word document to appear and capture the window focus. The Get-WordProperties.ps1 script runs faster if the Microsoft Word document is not visible. To control this behavior, set the <b>visible<\/b> property from the <b>application<\/b> object to <b>$false<\/b>. One thing that is vital when making the application invisible is that you must call the <b>quit<\/b> method at the end of the script to keep from having multiple instances of word.exe running. The line of code that makes the application invisible is shown here:<\/p>\n<p class=\"CodeBlockScreened\"><font face=\"Lucida Sans Typewriter\">$application.Visible = $false<\/font><\/p>\n<p class=\"MsoNormal\">The <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb211897.aspx\"><font face=\"Segoe\">document object<\/font><\/a> is obtained by using the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb216319.aspx\"><font face=\"Segoe\">open method<\/font><\/a> from the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb211902.aspx\"><font face=\"Segoe\">documents collection object<\/font><\/a> that is returned by the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb212729.aspx\"><font face=\"Segoe\">documents property<\/font><\/a> of the application object. Store the returned <b>document<\/b> object in the <b>$document<\/b> variable, as seen here:<\/p>\n<p class=\"CodeBlockScreened\"><font face=\"Lucida Sans Typewriter\">$document = $application.documents.open(&#8220;C:dataScriptingGuys2009HSG_12_28_09Test.docx&#8221;)<\/font><\/p>\n<p class=\"MsoNormal\">The <b>invokemember<\/b> method that is required to retrieve the <b>document<\/b> properties requires a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.reflection.bindingflags.aspx\"><font face=\"Segoe\">bindingflags enumeration<\/font><\/a> value. To provide access to the <b>bindingflags<\/b> enumeration values, use <b>&ndash;as [type]<\/b> and store the <b>bindingflags<\/b> enumeration in the <b>$binding<\/b> variable, as seen here:<\/p>\n<p class=\"CodeBlockScreened\"><font face=\"Lucida Sans Typewriter\">$binding = &#8220;System.Reflection.BindingFlags&#8221; -as [type]<\/font><\/p>\n<p class=\"MsoNormal\">You obtain the <b>BuiltInDocumentProperties<\/b> collection object by querying the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb214820.aspx\"><font face=\"Segoe\">BuiltInDocumentProperties property<\/font><\/a> from the <b>document<\/b> object. Store the <b>BuiltInDocumentProperties<\/b> collection object in the <b>$properties<\/b> variable, as seen here:<\/p>\n<p class=\"CodeBlockScreened\"><font face=\"Lucida Sans Typewriter\">$properties = $document.BuiltInDocumentProperties<\/font><\/p>\n<p class=\"MsoNormal\">Because the <b>BuiltInDocumentProperties<\/b> collection object is a collection, use the <b>foreach<\/b> statement to iterate through the collection, as seen here:<\/p>\n<p class=\"CodeBlockScreened\"><font face=\"Lucida Sans Typewriter\">foreach($property in $properties)<\/font><\/p>\n<p class=\"CodeBlockScreened\"><font face=\"Lucida Sans Typewriter\">{<\/font><\/p>\n<p class=\"MsoNormal\">Inside the <b>foreach<\/b> loop, use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.type.invokemember.aspx\"><font face=\"Segoe\">invokemember method<\/font><\/a> to retrieve the name of each <b>document<\/b> property from the collection of <b>BuiltInDocumentProperties<\/b>. This is shown here:<\/p>\n<p class=\"CodeBlockScreened\"><font><font face=\"Lucida Sans Typewriter\"><span>&nbsp;<\/span>$pn = [System.__ComObject].invokemember(&#8220;name&#8221;,$binding::GetProperty,$null,$property,$null)<\/font><\/font><\/p>\n<p class=\"MsoNormal\">It is entirely possible that a particular document property will be empty. If this is the case, an error will be generated. To keep the script from crashing, the <b>trap<\/b> statement is used to handle any <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.exception.aspx\"><font face=\"Segoe\">system exception<\/font><\/a> that might be generated. If an instance of the <b>system.exception<\/b> class is generated, the exception is trapped and the name of the empty document property is displayed in blue on the Windows PowerShell console. This is seen here:<\/p>\n<p class=\"CodeBlockScreened\"><font><font face=\"Lucida Sans Typewriter\"><span>&nbsp; <\/span>trap [system.exception]<\/font><\/font><\/p>\n<p class=\"CodeBlockScreened\"><font><font face=\"Lucida Sans Typewriter\"><span>&nbsp; <\/span><span>&nbsp;<\/span>{<\/font><\/font><\/p>\n<p class=\"CodeBlockScreened\"><font><font face=\"Lucida Sans Typewriter\"><span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>write-host -foreground blue &#8220;Value not found for $pn&#8221;<\/font><\/font><\/p>\n<p class=\"MsoNormal\">After the exception has been trapped, the <b>continue<\/b> statement is used to cause the script to return to the top of the <b>foreach<\/b> loop. The <b>continue<\/b> statement is seen here:<\/p>\n<p class=\"CodeBlockScreened\"><font><font face=\"Lucida Sans Typewriter\"><span>&nbsp;&nbsp;&nbsp; <\/span>continue<\/font><\/font><\/p>\n<p class=\"CodeBlockScreened\"><font><font face=\"Lucida Sans Typewriter\"><span>&nbsp;&nbsp; <\/span>}<\/font><\/font><\/p>\n<p class=\"MsoNormal\">If there were no errors accessing the <b>document<\/b> property, the <b>invokemember<\/b> method is used to retrieve the value of the <b>document<\/b> property. There is no need to use the <b>trap<\/b> statement to handle errors because the nonexistent document properties were previously handled. This is seen here:<\/p>\n<p class=\"CodeBlockScreened\"><font><font face=\"Lucida Sans Typewriter\"><span>&nbsp; <\/span>&#8220;$pn`: &#8221; +<\/font><\/font><\/p>\n<p class=\"CodeBlockScreened\"><font><font face=\"Lucida Sans Typewriter\"><span>&nbsp;&nbsp; <\/span>[System.__ComObject].invokemember(&#8220;value&#8221;,$binding::GetProperty,$null,$property,$null)<\/font><\/font><\/p>\n<p class=\"CodeBlockScreened\"><font face=\"Lucida Sans Typewriter\">}<\/font><\/p>\n<p class=\"MsoNormal\">After all the document properties and values have been displayed, close the Microsoft Word document by using the <b>quit<\/b> method, as shown here:<\/p>\n<p class=\"CodeBlockScreened\"><font face=\"Lucida Sans Typewriter\">$application.quit()<\/font><\/p>\n<p class=\"MsoNormal\">When the Get-WordProperties.ps1 script runs, the output shown in the following image is seen in the Windows PowerShell ISE:<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of script output in Windows PowerShell ISE\" alt=\"Image of script output in Windows PowerShell ISE\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/december\/hey1229\/hsg-12-29-09-04.jpg\" width=\"600\" height=\"421\"><\/p>\n<p class=\"Fig-Graphic\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\">JM, that is all there is to using Windows PowerShell to get the document properties from a Microsoft Word document. Microsoft Word Week will continue tomorrow. <\/p>\n<p class=\"MsoNormal\">If you want to know exactly what we will be looking at tomorrow, follow us on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> or <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send e-mail to us at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\"><font face=\"Segoe\">scripter@microsoft.com<\/font><\/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.<br><\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<p><b><span>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/span><\/b><\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; &nbsp; Hey, Scripting Guy! I am trying to find a Windows PowerShell script that will list all the properties of a Microsoft Word document. I am not talking about the size and the date of the document; those are file properties. I am talking about stuff like the author, the subject, and those properties [&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],"class_list":["post-51693","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-microsoft-word","tag-office","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; &nbsp; Hey, Scripting Guy! I am trying to find a Windows PowerShell script that will list all the properties of a Microsoft Word document. I am not talking about the size and the date of the document; those are file properties. I am talking about stuff like the author, the subject, and those properties [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/51693","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=51693"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/51693\/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=51693"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=51693"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=51693"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}