{"id":18221,"date":"2010-05-29T00:01:00","date_gmt":"2010-05-29T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/05\/29\/hey-scripting-guy-weekend-scripter-querying-the-windows-search-index\/"},"modified":"2010-05-29T00:01:00","modified_gmt":"2010-05-29T00:01:00","slug":"hey-scripting-guy-weekend-scripter-querying-the-windows-search-index","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-weekend-scripter-querying-the-windows-search-index\/","title":{"rendered":"Hey, Scripting Guy! Weekend Scripter: Querying the Windows Search Index"},"content":{"rendered":"<p><img decoding=\"async\" height=\"16\" width=\"125\" src=\"http:\/\/s7.addthis.com\/static\/btn\/v2\/lg-share-en.gif\" alt=\"Bookmark and Share\">\n&nbsp;<\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: small\">Microsoft Scripting Guy Ed Wilson here. I finally had time to play around with querying Windows Search from within Windows PowerShell. I tried, back during the beta of Windows Vista, to do that, but I was unable to get it to work. It has been on my mind and on the back burner for quite some time. Today, being a nice relaxed day&mdash;due in part to the fact that I have been unable to receive any e-mail for the last 36 hours&mdash;I finally had time to play around with it. <\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: small\">A quick word of warning: This script and the concept of querying the Windows Search index can quickly become addictive. After you begin experimenting with the query syntax, you can easily begin to think of other applications and additional items to look for, and as a result you can eat up vast amounts of time. My first effort produced the SearchEveryThingFromWindowsSearch.ps1 script that is seen here. <\/p>\n<p><\/span><\/p>\n<p class=\"CodeBlockScreenedHead\"><strong><span style=\"font-size: small\">SearchEveryThingFromWindowsSearch.ps1<\/p>\n<p><\/span><\/strong><\/p>\n<p class=\"CodeBlockScreened\"><span style=\"font-size: 11pt\"><span style=\"background-color: #f2f2f2\"><span style=\"font-family: Lucida Sans Typewriter\">$objConnection = New-Object -ComObject adodb.connection<br \/>$objrecordset = New-Object -ComObject adodb.recordset<br \/>$objconnection.open(&#8220;Provider=Search.CollatorDSO;Extended Properties=&#8217;Application=Windows&#8217;;&#8221;)<br \/>$objrecordset.open(&#8220;SELECT System.ItemName, System.ItemTypeText, System.Size FROM SystemIndex&#8221;, $objConnection)<br \/>$objrecordset.MoveFirst()<br \/>do <br \/>{<br \/><span>&nbsp;<\/span>$objrecordset.Fields.Item(&#8220;System.ItemName&#8221;)<br \/><span>&nbsp;<\/span>$objrecordset.Fields.Item(&#8220;System.ITemTypeText&#8221;)<br \/><span>&nbsp;<\/span>$objrecordset.Fields.Item(&#8220;System.SIze&#8221;)<br \/><span>&nbsp;<\/span>$objrecordset.MoveNext()<br \/>} Until ($objrecordset.EOF)<\/p>\n<p>$objrecordset.Close()<br \/>$objConnection.Close()<br \/>$objrecordset = $null<br \/>$objConnection = $null<br \/><span style=\"font-size: small\">[gc]::collect()<\/p>\n<p><\/span><\/span><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: small\"><br \/>Just like any other script that uses the COM version of ADO, you begin by creating the <b>connection<\/b> object, the <b>recordset<\/b> object, and opening the connection. The key thing is to know which provider to use. The provider used here is the <b>Search.CollatorDSO<\/b> provider, but I must also specify <b>extended<\/b> properties as well. Therefore, the <b>provider<\/b> string that is used to open the connection is shown here:<\/p>\n<p><\/span><\/p>\n<p class=\"CodeBlockScreened\"><span style=\"font-size: 11pt\"><span style=\"background-color: #f2f2f2\"><span style=\"font-family: Lucida Sans Typewriter\">&#8220;Provider=Search.CollatorDSO;Extended Properties=&#8217;Application=Windows&#8217;;&#8221;<\/p>\n<p><\/span><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: small\"><br \/>The first three lines of the script are shown here:<\/p>\n<p><\/span><\/p>\n<p class=\"CodeBlockScreened\"><span style=\"font-size: 11pt\"><span style=\"background-color: #f2f2f2\"><span style=\"font-family: Lucida Sans Typewriter\">$objConnection = New-Object -ComObject adodb.connection<br \/>$objrecordset = New-Object -ComObject adodb.recordset<br \/>$objconnection.open(&#8220;Provider=Search.CollatorDSO;Extended Properties=&#8217;Application=Windows&#8217;;&#8221;)<\/p>\n<p><\/span><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: small\"><br \/>After the connection is open, it is time to open the <b>recordset<\/b>. Here I also type in my select statement that will be used to retrieve information from the index. Note that I do not have a <b>where<\/b> clause; this query will therefore return the <b>ItemName<\/b>, the <b>ItemTypeText<\/b> and the <b>Size<\/b> from the <b>SystemIndex<\/b>. The <b>SystemIndex<\/b> is the only table that I can query with this provider. In addition to the SQL statement, the <b>open<\/b> method also needs a <b>connection<\/b> object. This command is shown here:<\/p>\n<p><\/span><\/p>\n<p class=\"CodeBlock\"><span style=\"font-size: 11pt\"><span style=\"font-family: Lucida Sans Typewriter\"><span style=\"background-color: #f2f2f2\">$objrecordset.open(&#8220;SELECT System.ItemName, System.ItemTypeText, System.Size FROM SystemIndex&#8221;, $objConnection)<\/p>\n<p><\/span><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: small\"><br \/>The next thing I do is move to the beginning of the <b>recordset<\/b>, and print out each of the property items I had selected. After displaying the three property items for the current record, the script moves to the next item in the <b>recordset<\/b>. It will continue in this fashion until it reaches the <b>EOF<\/b> (end of the file) property of the <b>recordset<\/b>. A Do&hellip;Until loop is used to walk through the <b>recordset<\/b>. This section of the script is shown here:<\/p>\n<p><\/span><\/p>\n<p class=\"CodeBlock\"><span style=\"font-size: 11pt\"><span style=\"font-family: Lucida Sans Typewriter\"><span style=\"background-color: #f2f2f2\">$objrecordset.MoveFirst()<br \/>do <br \/>{<br \/><span>&nbsp;<\/span>$objrecordset.Fields.Item(&#8220;System.ItemName&#8221;)<br \/><span>&nbsp;<\/span>$objrecordset.Fields.Item(&#8220;System.ITemTypeText&#8221;)<br \/><span>&nbsp;<\/span>$objrecordset.Fields.Item(&#8220;System.SIze&#8221;)<br \/><span>&nbsp;<\/span>$objrecordset.MoveNext()<br \/>} Until ($objrecordset.EOF)<\/p>\n<p><\/span><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: small\"><br \/>A little bit of cleanup code is all that I needed to add to the script. I therefore close the <b>recordset<\/b> and the connection, set the objects to <b>$null<\/b>, and call garbage collection. When working with COM-based objects, it is always a good idea to call garbage collection at the end of your script. The cleanup code is shown here:<\/p>\n<p><\/span><\/p>\n<p class=\"CodeBlock\"><span style=\"font-size: 11pt\"><span style=\"font-family: Lucida Sans Typewriter\"><span style=\"background-color: #f2f2f2\">$objrecordset.Close()<br \/>$objConnection.Close()<br \/>$objrecordset = $null<br \/>$objConnection = $null<br \/>[gc]::collect()<\/p>\n<p><\/span><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: 11pt\"><br \/><span style=\"font-size: small\">When the script runs, the output shown in the following image scrolls by in the output pane. To stop the script from running, click the red square in the Windows PowerShell ISE. If you run it in the Windows PowerShell console, press CTRL+C to halt execution. If you do not do this, the script will run for quite some time. <\/p>\n<p><\/span><\/span><\/p>\n<p class=\"Fig-Graphic\"><span style=\"font-size: small\"><img decoding=\"async\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/may\/hey0529\/wes-05-29-10-01.jpg\" alt=\"Image of output from script\" style=\"max-width: 600px;border: 0px\"><\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: 11pt\"><span style=\"font-size: small\">&nbsp;<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: 11pt\"><span style=\"font-size: small\">If you want to know exactly what we will be looking at tomorrow, follow us on <\/span><a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingguystwitter\"><span style=\"font-size: small\">Twitter<\/span><\/a><span style=\"font-size: small\"> or <\/span><a href=\"http:\/\/bit.ly\/scriptingguysfacebook\"><span style=\"font-size: small\">Facebook<\/span><\/a><span style=\"font-size: small\">. If you have any questions, send e-mail to us at <\/span><a target=\"_blank\" href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\"><span style=\"font-size: small\">scripter@microsoft.com<\/span><\/a><span style=\"font-size: small\"> or post your questions on the <\/span><a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingforum\"><span style=\"font-family: arial,helvetica,sans-serif\"><span style=\"font-size: small\">Official Scripting Guys Forum<\/span><\/span><\/a><span style=\"font-size: small\">. See you tomorrow. Until then, peace.<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: 'Segoe UI','sans-serif';font-size: 11pt\">&nbsp;<\/p>\n<p><\/span>\n<b><span style=\"font-family: 'Segoe UI','sans-serif';font-size: 11pt\">Ed Wilson and Craig Liebendorfer, Scripting Guys<\/p>\n<p><\/span><\/b><\/p>\n<p><b><span style=\"font-family: 'Segoe UI','sans-serif';font-size: 11pt\"><\/span><\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Microsoft Scripting Guy Ed Wilson here. I finally had time to play around with querying Windows Search from within Windows PowerShell. I tried, back during the beta of Windows Vista, to do that, but I was unable to get it to work. It has been on my mind and on the back burner for [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[31,3,147,61,45],"class_list":["post-18221","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-operating-system","tag-scripting-guy","tag-search","tag-weekend-scripter","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; Microsoft Scripting Guy Ed Wilson here. I finally had time to play around with querying Windows Search from within Windows PowerShell. I tried, back during the beta of Windows Vista, to do that, but I was unable to get it to work. It has been on my mind and on the back burner for [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/18221","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=18221"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/18221\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=18221"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=18221"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=18221"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}