2
votes

I have a folder with sub folders and I want to run a powershell script that finds all the office documents (word and excel 2003,2007 and 2010 for the moment) and print the "last saved by" property that we can find on the properties, details tab of the files.

Can anybody help?

--- solution ---

$word = New-Object -Com Word.Application
$word.Visible = $false #to prevent the document you open to show
$doc = $word.Documents.Open($path)

$binding = "System.Reflection.BindingFlags" -as [type]
Foreach($property in $doc.BuiltInDocumentProperties) {
   try {
      $pn = [System.__ComObject].invokemember("name",$binding::GetProperty,$null,$property,$null)
      if ($pn -eq "Last author") {
         $lastSaved = [System.__ComObject].invokemember("value",$binding::GetProperty,$null,$property,$null)
         write-host "Last saved by: "$lastSaved      
      }        }
   catch { }
}

$doc.Close()
$word.Quit()

Did some adjustments to the correct answer and now it's working.

1
While you wait some answer from someone else you can start to take a look at getdetailsof method. msdn.microsoft.com/en-us/library/bb787870%28v=vs.85%29.aspx and even here technet.microsoft.com/en-us/library/ee176615.aspxNicola Cossu

1 Answers

5
votes

It's not as easy as one would have hoped. You can easily open a Word document from Powershell with

$word = New-Object -COM Word.Application
$word.Visible = $false #to prevent the document you open to show
$doc = $word.Document.Open("path-to-document")

But Document properties are stored in the property BuiltInDocumentProperties, which in themselves are dynamic COM-objects (and therefore not directly available)

The method I've used is to traverse each of these properties and then retrieved the value:

$binding = "System.Reflection.BindingFlags" -as [type]
Foreach($property in $doc.BuiltInDocumentProperties) {
   try {
      $pn = [System.__ComObject].invokemember("name",$binding::GetProperty,$null,$property,$null)
      if ($pn -eq "Last save time") {
         $lastSaved = [System.__ComObject].invokemember("value",$binding::GetProperty,$null,$property,$null)
      }
   }
   catch { }
}

You can get the names of all available properties by simply printing the $pn variable.