From this other post it looks like it is possible to get the return value of IHTMLWindow2::execScript
from Internet Explorer API, however the linked example is in C++ and I don't really understand it. I'm trying to do the same thing in PowerShell, so here's my code that shows the problem:
$ie = New-Object -COM InternetExplorer.Application
$ie.visible = $true
$ie.navigate("http://google.com")
while ( $ie.busy ) { start-sleep -m 100 }
$document = $ie.document
$window = $document.parentWindow
Function eval($jsCommand) {
# Of course it doesn't return anything here. How can I get the return value?
return $window.execScript($jsCommand, 'javascript')
}
eval 'parseInt("12")' # returns nothing
What I'm really trying to do is to make jQuery selector/objects available in my PowerShell script, so that I can do things like:
eval '$("input#selector")' | where name -eq 'username'
and more.
Update: Look at this Gist for PowerShell function to run JavaScript/JQuery and return results back to PS, with timeout. It was extended from the answer below.
The preferred method is probably what @Matt suggested to use the eval method instead of execScript which has been deprecated in IE11. However, I still couldn't find how to access that eval
from IE API. I created this other question to follow up with that.
I could, however, figure a way to execute JavaScript/jQuery on a web page and return the results back to PowerShell with this trick that we store the JavaScript return value in the DOM using setAttribute
and then retrieving it in PowerShell using getAttribute
.
# some web page with jQuery in it
$url = "http://jquery.com/"
# Use this function to run JavaScript on a web page. Your $jsCommand can
# return a value which will be returned by this function unless $global
# switch is specified in which case $jsCommand will be executed in global
# scope and cannot return a value. If you received error 80020101 it means
# you need to fix your JavaScript code.
Function ExecJavaScript($ie, $jsCommand, [switch]$global)
{
if (!$global) {
$jsCommand = "document.body.setAttribute('PSResult', (function(){$jsCommand})());"
}
$document = $ie.document
$window = $document.parentWindow
$window.execScript($jsCommand, 'javascript') | Out-Null
if (!$global) {
return $document.body.getAttribute('PSResult')
}
}
Function CheckJQueryExists
{
$result = ExecJavaScript $ie 'return window.hasOwnProperty("$");'
return ($result -eq $true)
}
$ie = New-Object -COM InternetExplorer.Application -Property @{
Navigate = $url
Visible = $false
}
do { Start-Sleep -m 100 } while ( $ie.ReadyState -ne 4 )
$jQueryExists = CheckJQueryExists $ie
echo "jQuery exists? $jQueryExists"
# make a jQuery call
ExecJavaScript $ie @'
// this is JS code, remember to use semicolons
var content = $('#home-content');
return content.text();
'@
# Quit and dispose IE COM
$ie.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($ie) | out-null
Remove-Variable ie