Skip to content Skip to sidebar Skip to footer

Using Powershell To Run Javascript In Internet Explorer On Windows Server

I have this piece of a PowerShell script: $IE = New-Object -com InternetExplorer.Application $IE.Navigate($URL) While ($IE.ReadyState -Ne 4) {Start-Sleep -Milliseconds 100} $IE.Doc

Solution 1:

This may have something to do with Internet Explorer 'protected mode'. If IE indeed is in protected mode, the $IE object gets lost after the .Navigate() command and any action after that will result in the error You cannot call a method on a null-valued expression.

To handle this, here's a function that tries to reconnect the $IE object.

functionConnect-InternetExplorer{
    # creates a new 'InternetExplorer.Application' object and navigates to the given url.# If IE is in 'protected mode', the function tries to reconnect using the window handle
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Mandatory = $true, Position = 0)]
        $Url,

        [switch]$Visible
    )
    # test if Internet Explorer is in 'Protected Mode'# see https://www.lifewire.com/how-to-disable-protected-mode-in-internet-explorer-2624507$ieProtectedMode = ((Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3' -Name '2500').2500 -ne 3)

    $ie = New-Object -ComObject 'InternetExplorer.Application' -ErrorAction SilentlyContinue
    $ie.Visible = [bool]$Visible$ie.Silent = $true$hwnd = $ie.Hwnd
    $ie.Navigate($Url)

    if ($ieProtectedMode) {
        $oldErrorActionPreference = $ErrorActionPreference$ErrorActionPreference = 'Stop'$objShell = New-Object -ComObject 'Shell.Application'
        Start-Sleep -Milliseconds 100try {
            $ie = $objShell.Windows() | Where-Object {$_.HWND -eq $Hwnd}
            $ie.Visible = [bool]$Visible
        }
        catch {
            # sometimes the Shell.Application does not find the window quickly enough,
            Start-Sleep -Milliseconds 500try {
                $ie = $objShell.Windows() | Where-Object {$_.HWND -eq $Hwnd}
                $ie.Visible = [bool]$Visible
            }
            catch {
                Write-Warning "Could not connect to the InternetExplorer ComObject."
            }
        }
        finally {
            $ErrorActionPreference = $oldErrorActionPreference# clean up the Com object
            [System.Runtime.Interopservices.Marshal]::ReleaseComObject($objShell) | Out-Null
            [System.GC]::Collect()
            [System.GC]::WaitForPendingFinalizers()
        }
    }

    if (!$ie) { return$null }
    while ($ie.Busy -eq $true) { Start-Sleep -Milliseconds 50 }
    return$ie
}

# this replaces the first three lines of your original code$IE = Connect-InternetExplorer -Url $URLif ($IE) {
    $IE.Document.ParentWindow.ExecScript("var JSIEVariable = new XMLSerializer().serializeToString(document);", "javascript")
    $Obj = $IE.Document.ParentWindow.GetType().InvokeMember("JSIEVariable", 4096, $Null, $IE.Document.parentWindow, $Null)
    $HTML = $Obj.ToString()
    $IE.Quit()

    # clean up the $IE Com object
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($IE) | Out-Null
    [System.GC]::Collect()
    [System.GC]::WaitForPendingFinalizers()
}
else {
    Write-Warning "Could not connect Internet Explorer"
}

Hope that helps

Solution 2:

A coworker helped me figure this out. It doesn't have anything to do with IE security, at least not as far as anything that hasn't already been covered. The problem is 'Microsoft.mshtml.dll' is missing from the GAC. It won't be present on a clean install of Windows Server but installing something like Office or Visual Studio will add it. However, i would bet that most people running a Windows Server wouldn't want to do that just for the sake of getting this working. What I did was copy the following folder/file structure from my Windows 10 PC to my server, closed out all instances of PowerShell and ISE and when I opened PowerShell again and ran the script everything worked.

C:\Windows\assembly\GAC\Microsoft.mshtml C:\Windows\assembly\GAC\Microsoft.mshtml\7.0.3300.0__b03f5f7f11d50a3a C:\Windows\assembly\GAC\Microsoft.mshtml\7.0.3300.0__b03f5f7f11d50a3a\Microsoft.mshtml.dll C:\Windows\assembly\GAC\Microsoft.mshtml\7.0.3300.0__b03f5f7f11d50a3a__AssemblyInfo__.ini

Post a Comment for "Using Powershell To Run Javascript In Internet Explorer On Windows Server"