Borrowing from Windows Explorer in PowerShell part 2: extended properties

When I stated looking at what could be done using explorer objects from PowerShell I “discovered” the extended properties. This vary between operating systems, before Windows 2000 the set was pretty rudimentary, XP and Server 2003 had quite an extensive set of properties and Vista/Server 2008 extends the set still further to 266 items.  You can send a list of the properties to the screen with this command.

 [ps]  >  $objShell = New-Object -ComObject Shell.Application
[ps]  >  $objFolder = $objShell.namespace("C:\")
[ps]  >  0..266 | foreach {"{0,3}:{1}"-f $_,$objFolder.getDetailsOf($Null, $_)}
   0:Name
  1:Size
  2:Type
    ...
264:Frame rate
265:Frame width
266:Total bitrate

It doesn’t matter which folder you choose at line 2. In line 3 I don’t like using strings with –f in examples but it’s the easiest way to do the output {0,3} is ‘Argument 0 formatted to 3 wide’  - that’s the number and {1] is argument 1, and getDetailsOf $null and a number returns the column name.

I store this in a hash-table in the example below

 function Get-ext 

{param ($attributes, $Path=(pwd).path)
 $objShell = New-Object -ComObject Shell.Application
 $objFolder = $objShell.namespace($path)
 0..266 | Foreach-object -begin {$Columns=@{} } -process {$Columns.add($objFolder.getDetailsOf($Null, $_),$_)}
 foreach ($file in $objFolder.items())  {          $attributes | forEach -begin  {$fileObj = New-Object -TypeName System.Object } `

                               -process {Add-Member -inputObject $fileObj -MemberType NoteProperty -Name $_ `                                                                 -Value ($objFolder.GetDetailsOf($file , $Columns[$_]) )}  `
                                -end { $fileObj} }

}

So the function takes a list of attributes as text. It puts all the attribute names and numbers into a hash table, and for each file it builds an object, the properties are built by saying “for each attribute passed, look up its number and get that attribute for the current file”

I found that there is an extendedProperty() method on the file objects, but that this doesn’t seem to work with all the property names, but asking the Folder object to get the properties does.  SO now I can run a command like this to get the photographic information I want.

 Get-ext "name","Title","Tags","f-stop","Exposure Time","ISO Speed" | ft *