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:
In the case above, I broke the original problem into a few problems:
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 } $recordSet.MoveFirst()
while (-not $recordSet.EOF) { $result = New-Object Object foreach ($field in $fields) { $result | Add-Member NoteProperty $field $recordSet.Fields.Item($field).Value } $result $recordSet.MoveNext() }
$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