Problems querying the Windows search index - windows

I want to write a powershell script which searches the Windows index for files containing names which are provided as a parameter to the script. I searched the internet and came up with the following solution:
function Search-FileInIndex ($firstname, $lastname) {
$sql = "SELECT System.ItemName, System.DateCreated, System.ItemPathDisplay, System.Search.Rank FROM SYSTEMINDEX WHERE CONTAINS('`"$($firstname)`" NEAR `"$($lastname)`"') and SCOPE= 'c:\' and System.Search.Rank > 0 ORDER BY System.ItemPathDisplay"
$provider = "provider=search.collatordso;extended properties=’Application=Windows’;"
$connector = new-object system.data.oledb.oledbdataadapter -argument $sql, $provider
$dataset = new-object system.data.dataset
if ($connector.fill($dataset)) {
$dataset.tables[0] | format-table -autosize *
}
$dataset.Dispose()
$connector.Dispose()
}
Search-FileInIndex john doe
However, I have two problems.
Problem 1
The provided solution works and finds files, but sometimes I get really strange error messages like these ones resulting in an exception instead of a file listing:
Ausnahme beim Aufrufen von "Fill" mit 1 Argument(en): "Fehler E_FAIL(0x80004005) in IErrorInfo.GetDescription."
In C:\Search-FileInIndex.ps1:11 Zeichen:9
+ if ($connector.fill($dataset)) {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : OleDbException
or
Ausnahme beim Aufrufen von "Fill" mit 1 Argument(en): "Die Pipe wurde beendet."
In C:\Search-FileInIndex.ps1:11 Zeichen:9
+ if ($connector.fill($dataset)) {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : OleDbException
I read on the internet that especially the first error results from keywords being used but I don't see any reserved keywords in my query and as I already said, it works sometimes. Is this a race condition or memory issue? I'm running this on Windows 10 Enterprise 1703 with 16 GB of RAM.
EDIT:
I got some new insights.
If I run the script for the first time, it usually works. If I run it again, the crashes are likely to occur, but I didn't find a waiting time between these two runs yet.
If it crashes there is an entry in the application log in the Event Viewer that IndexSearcher.exe was faulty.
The problem seems to be the field System.Search.Rank. If I remove it, it runs flawlessy. However, I need the rank because otherwise I cannot filter the wrong results (due to the NEAR-search). Do you know a replacement for the NEAR-search?
Problem 2
Actually, I would like to have hit-highlighting showing me a snippet of the found matches in the file. However, the MSDN states that the API originally used for that is deprecated. I read on stackoverflow that I would have to use an explorer shell interface, but I have no clue how to do this. Can you provide a working example?
Thanks and best regards,
Hans

I can reproduce the error and the troublemaker seems surprisingly the "NEAR" statement in SQL. This solution is working for me:
function Search-FileInIndex($firstname, $lastname) {
$con = New-Object -ComObject ADODB.Connection
$rs = New-Object -ComObject ADODB.Recordset
$sql = "SELECT System.ItemName, System.DateCreated, System.ItemPathDisplay, System.Search.Rank FROM SYSTEMINDEX WHERE CONTAINS(System.Search.Contents, '$($firstname)') and CONTAINS(System.Search.Contents, '$($lastname)') and SCOPE= 'c:\' and System.Search.Rank > 0 ORDER BY System.ItemPathDisplay"
$con.Open("Provider=Search.CollatorDSO;Extended Properties='Application=Windows';")
$rs.Open($sql, $con)
While(-Not $rs.EOF){
$rs.Fields.Item("System.ItemPathDisplay").Value
$rs.MoveNext()
}
$rs.Close()
$con.Close()
}
Search-FileInIndex john doe

Related

Powershell Force Maximize / Reopen if close

Working on a Kiosk Windows tablet, was working before I started to optimize. I had used a Windows Debloating tool to remove all the unnecessary items on the tablets. But I believe it removed something I was calling on in the script. Just looking to see if anyone has any idea what I would need to reinstall. Or if I should start over on the Image
Here is the Powershell script
Add-Type -AssemblyName UIAutomationClient
$MyProcess = Get-Process | where { $_.MainWindowTitle -like "Kiosk*" }
while (1 -eq 1) {
if ($null -ne $MyProcess) {
# if Minimized make it Normal
$ae = [System.Windows.Automation.AutomationElement]::FromHandle($MyProcess.MainWindowHandle)
$wp = $ae.GetCurrentPattern([System.Windows.Automation.WindowPatternIdentifiers]::Pattern)
if ($wp.Current.WindowVisualState -eq 'Minimized') {
$wp.SetWindowVisualState('Normal')
}
# execute needed function
}
else {
start-process "C:\Users\Public\Desktop\Welcome.lnk" -WindowStyle Normal
# execute needed function
}
start-sleep -Milliseconds 500
}
And here is the error attempted a copy and paste
Cannot convert argument "hwnd", with value: "System.Object[]", for "FromHandle' to type "System.IntPtr": "Cannot convert the "System.Object[]" value of type "System.Object[]"' to type "System. IntPtr At C:\Scripts\KioskMinimizedcheckscript.ps1:9 char:5 + Sae = [system.windows. Automation.AutomationElement]:: FromHandle($
+
+CategoryInfo
: NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgument Conversion InvalidcastArgument
You cannot call a method on a null-valued expression. At C:\scripts\KioskMinimizedcheckscript.ps1:10 char:5
Swp = Sae.GetCurrentPattern([system.windows. Automation.windowPatt ...
+ CategoryInfo
Invalidoperation; (:) [], RuntimeException
+ FullyQualifiedErrorId: InvokeMethodonNull
Image of Actual Error
Tried running script on default install of windows and works fine. Just need to know what to add back into the stripped down version.

How to enter text into an input field through Power Shell?

Here is a PowerShell script to trigger Internet Explorer, open LinkedIn login page and enter some text in the username text field.
$ie = New-Object -Com "InternetExplorer.Application"
$ie.Navigate("www.linkedIn.com")
$ie.Visible = $true
$doc = $ie.document
$usernameElement = $doc.getElementByTagName("input") | Where-Object {$_.id = "session_key-login""}
$usernameElement.Click()
Get-Process iexplore | Foreach-Object {$_.CloseMainWindow()}
Unfortunately, I keep getting the following error:
You cannot call a method on a null-valued expression.
At C:\Users\Pinku\Desktop\Untitled1.ps1:7 char:23
+ $usernameElement.Click <<<< ()
+ CategoryInfo : InvalidOperation: (Click:String) [], RuntimeExcepti
on
+ FullyQualifiedErrorId : InvokeMethodOnNull
I have tried but have not been able to alleviate myself from this issue.Please suggest!
Instead of using $doc.getElementsByTagName("input") and then trying to filter through the results, try retrieving the ID directly using getElementById:
$usernameElement = $doc.getElementById("session_key-login")
$usernameElement.Click()
---Edit---
Response to still getting the null-valued expression after using the above:
The error message is that it can't find any elements called "session_key-login", and so it returns $null, and hence, when you try to invoke the Click() method, it throws the error. Some things to try:
-Check to see if the id exists. Run the following code after creating your $ie object, and see if there is an ID that matches "session_key-login":
$ie = New-Object -Com "InternetExplorer.Application"
$ie.Navigate("www.linkedIn.com")
$ie.Visible = $true
$doc = $ie.document
$doc.getElementsByTagName("Input") | Select Id, Name
-Try running your PowerShell session as Administrator. I know I wasn't able to launch IE properly until I ran PowerShell as Administrator. For ex. even though the iexplore process was created, the physical Internet Explorer window didn't open for me.

Powershell - Internet Explorer - Get document for a newly opened tab

I am trying to figure out how to login to web-pages in Internet Explorer 9 using PowerShell version 2 on Windows 7 x64. When I run these lines one by one in PowerShell, I get exactly what I want - The page opens and I am able to login.
$internet_explorer = new-object -com "InternetExplorer.Application"
$internet_explorer.visible = $true
$internet_explorer.navigate2("https://abcd.efgh.com/ijkl/Login.jsp")
$this_document = $internet_explorer.document
$username_field = $this_document.getElementByID("usernameField")
$password_field = $this_document.getElementByID("passwordField")
$login_button = $this_document.getElementByID("SubmitButton")
$username_field.value = "username"
$password_field.value = "password"
$login_button.click()
But when I try to open another tab and try to login to the new webpage by executing the below lines one-by-one,
$internet_explorer.navigate2("https://mnop.qrst.com/uvwx/Login.jsp", 0x0800)
$this_document = $internet_explorer.document
$username_field = $this_document.getElementByID("usernameField")
$password_field = $this_document.getElementByID("passwordField")
$login_button = $this_document.getElementByID("SubmitButton")
$username_field.value = "username"
$password_field.value = "password"
$login_button.click()
I get the following errors :
Property 'value' cannot be found on this object; make sure it exists and is settable.
At line:1 char:17
+ $username_field. <<<< value = "username"
+ CategoryInfo : InvalidOperation: (value:String) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
Property 'value' cannot be found on this object; make sure it exists and is settable.
At line:1 char:17
+ $password_field. <<<< value = "password"
+ CategoryInfo : InvalidOperation: (value:String) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
You cannot call a method on a null-valued expression.
At line:1 char:20
+ $login_button.click <<<< ()
+ CategoryInfo : InvalidOperation: (click:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
So when I open a new tab, how can I get Document of that newly opened tab? Please help me solve this
EDIT : Alternative methods will do. Please feel free to suggest any other way to login to multiple web pages automatically (like what was attempted above) if they exist
From the documentation for the Navigate method, it would appear that the new tab is not available for automation:
When navOpenInNewWindow or navOpenInNewTab is specified, the caller does not receive a pointer to the IWebBrowser2 interface for the new window, so there is no immediate way to manipulate it.

PowerShell, doesn't contain method 'items'

When executing this code, I received the error below:
$filesExist = Test-Path($file)
if ($filesExist) {
$shell_app=new-object -com shell.application
$zip_file = Get-Item "$mindCrackFolder\files.zip"
$destination = Get-Item $mindCrackFolder
$destination.Copyhere($zip_file.items(), 0x14)
#Remove-Item "$zip_file"
#Remove-Item "install.ps1"
}
Error:
Method invocation failed because [System.IO.FileInfo] doesn't contain a method named 'items'.
At C:\Users\User1\Desktop\ps install\install.ps1:33 char:5
+ $destination.Copyhere($zip_file.items(), 0x14)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
But I already convertered $destination into a IO object to be manipulated? Can I get any help, this my first time experimenting with PS.
This has nothing do with $destination. $zip_file.items() is evaluated first and the error message is telling you that the .NET System.IO.FileInfo object returned by Get-Item has no Items() method. Get-Item only returns an object that provides information about a file - size, last write time, readonly or not, etc. You can't use Get-Item to access the contents of a ZIP file.
If you need to extract the contents of the ZIP file, consider using the PowerShell Community Exensions' Expand-Archive cmdlet.
The errors is talking about the object you use the items() method on = $zip_file. Powershell doesn't have built-in zip support, you gotta create it(using shell.application com-object, google it) or add a .net library. $zip_file is just a simple FileInfo object just as the ones you get from dir(Get-ChildItem). It does not contain an items() method.
Solution: as previously said, google powershell zip files to read about how you can use zip files in powershell. My suggestion is DotNetZip
I don't know what and where you learned these, but you seem to have copied some code wrongly and made changes ad-hoc. Try the below script which does what you want:
$shell_app=new-object -com shell.application
$filename = "test.zip"
$zip_file = $shell_app.namespace((Get-Location).Path + "\$filename")
$destination = $shell_app.namespace((Get-Location).Path)
$destination.Copyhere($zip_file.items(), 0x14)
The items and copyHere method are not available on FileInfo objects, which is what you get from Get-Item. Use them as shown above.

How do I get an error reason from InstallProductKey (SoftwareLicensingService) in PowerShell?

I'm using some PowerShell functions to configure Windows product keys and activation. I get an instance of the SoftwareLicensingService and call InstallProductKey, like this. The trap block with super formatting is extra to help debugging.
trap [Exception]
{
"=================================================="
"Trapped: $($Error[0])"
"=================================================="
"Exception: $($_.Exception)"
"--------------------------------------------------"
""
break
}
$service = Get-WmiObject -Query "SELECT * FROM SoftwareLicensingService"
$service.InstallProductKey("12345-12345-12345-12345-12345")
$service.RefreshLicenseStatus() | Out-Null
The error condition is an invalid product key. I know this because I entered it manually into the Activate Windows dialog from the System panel. But, the script only ever shows me the WMIMethodException or the COMException.
==================================================
Trapped: Exception calling "InstallProductKey" : ""
==================================================
Exception: System.Runtime.InteropServices.COMException (0xC004F025)
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at System.Management.ManagementObject.InvokeMethod(String methodName, ManagementBaseObject inParameters, InvokeMethodOptions options)
at System.Management.Automation.ManagementObjectAdapter.InvokeManagementMethod(ManagementObject obj, String methodName, ManagementBaseObject inParams)
--------------------------------------------------
Exception calling "InstallProductKey" : ""
At line:14 char:31
+ $service.InstallProductKey <<<< ("12345-12345-12345-12345-12345")
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : WMIMethodException
I don't get a return code from the method (despite the documentation stating I do, can't find a list of error codes anyway). Do you know how to get the activation (or product key install) error reason?
As far as I can see there's no message there. Adding these to your trap:
$_ | fl * -Force
$_.Exception | fl * -Force
Returns everything that is there in the exception and there is nothing useful. So I googled a bit and found a piece of C# code here: http://www.dozty.com/?tag=change-windows-7-product-key-c-sharp They were cathcing ManagementException and in C# it seemed to work a bit better. I have rewritten that code into PowerShell and was trying to catch ManagementException, but without luck:
trap [Exception]
{
[System.Management.ManagementException] $_
break
}
$classInstance = new-object System.Management.ManagementObject("root\CIMV2","SoftwareLicensingService.Version=`"6.1.7600.16385`"", $null);
$inParams = $classInstance.GetMethodParameters("InstallProductKey")
$inParams["ProductKey"] = "12345-12345-12345-12345-12345"
$classInstance.InvokeMethod("InstallProductKey", $inParams, $null)
It throws: Cannot convert the "System.Runtime.InteropServices.COMException (0xC004F050)"

Resources