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?
- Where do I usually find scripts? (Answer: Technet)
- Is there a solution here for RecordedTV? (Answer: not that I can find)
- What other metadata could I look for?
- Photos (Answer: Seek and Ye Shall Find - Scripting Windows Desktop Search 3.0)
- 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 }
$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