Microcode: Windows PowerShell, Windows Desktop Search & Problem Solving

In the pursuit of my passion of media (specifically, trying to prune my DVR collection in a more flexible way than Windows Media Center), I started getting curious about how I could get the same kind of data that Windows Explorer has about some RecordedTV.  Since I could find it using the Search dialog in Windows, I thought that Windows Desktop Search should have some way to get at it as well.  After a number of searches, I ran across this little snippet from Greg Stemp's "Hey, Scripting Guy!" column.  It walks through how to extract out the DateTaken information from a JPEG.  This article provides valuable code snippets from VBScript that I used to create a Windows PowerShell function (Search-WindowsDesktop).  The article also contained a small link to a reference of almost every special query field that Windows Desktop Search provides.

That reference is the backbone of a number of scripts that I will post about here, but, in the interests of keeping it simple, I will post the final scripts in a later post.  It's also an example of how I go about solving problems.  When faced with a problem, my passion for programming partitions the problem.  I break each problem into a smaller set of individual problems with independent solutions.  This has a number of side-effects:

  • Increases the possibility that I might have a or know about a solution to a problem similar to the smaller problem
  • Forces the mind to think of independent solutions to parts, which helps you build a number of reusable components instead of one throw away script
  • Allows me to search for the answers to the unsolved problems more flexibly
  • Opens the possibility to finding better answers for the independent problems later on, which can improve the flow and performance of the entire system
  • Exposes me to potential other problems I could solve at reduced cost

In the case above, I broke the original problem into a few problems:

  • Where can I find RecordedTV Metadata?
    • Where can I find the most metadata? Answer: (Windows Desktop Search)
    • How do I get at it from scripts?
    • How can I display the data? (Answer: Tediously, or I can use Windows PowerShell, which will display the properties on the object for free)

Since the example that I have searches for Photo Metadata, which might be fun to script, Instead of making a function that just gets my recorded TV, I'm going to make a function that can query Windows Desktop Search for any field that I want and can come back with data.  Then I will write a script to get out my DVR metadata, but I can always build more interesting stuff from this core component later.  By building many things that depend on this core script, and ensuring that they all continue to work, I can make a flexible solution that can be extended upon and improved later.

Here's my function to pull data out of Windows Desktop Search:

function Search-WindowsDesktop($fields, $filter)
    $connection = New-Object -comObject "ADODB.Connection"
    $recordSet = New-Object -comObject "ADODB.RecordSet"

    $null = $connection.Open("Provider=Search.CollatorDSO;Extended Properties='Application=Windows';") > $null

    $ofs = ","
    $query = "SELECT $fields"
    $query += " FROM SYSTEMINDEX $filter"
    $null = $recordSet.Open($query, $connection)

    if ($recordSet.EOF) { return }

    while (-not $recordSet.EOF) {       
        $result = New-Object Object
        foreach ($field in $fields) {
            $result | Add-Member NoteProperty $field $recordSet.Fields.Item($field).Value

    $null = $recordSet.Close()
    $null = $connection.Close()

    $connection = $null
    $recordSet = $null

Here's a a few quick samples of using it that I'll expand upon later:

Search-WindowsDesktop "System.Title", "System.RecordedTV.EpisodeName" "WHERE System.RecordedTV.ChannelNumber IS NOT NULL"

Search-WindowsDesktop "System.Contact.FullName" "WHERE System.Contact.FullName IS NOT NULL"

Search-WindowsDesktop "System.Photo.CameraModel", "System.Photo.ProgramModeText", "System.Photo.OrientationText" "WHERE System.Photo.DateTaken IS NOT NULL"

Hope this helps,

James Brundage