powershellinternet-explorerprocesscomhwnd

Cannot find iexplorer process based on HWND when IE is navigated to a local file?


I am trying to find the process for a Internet Explorer com-object, the code I have provided below does work when the IE com-object is navigated to a URL like google.nl, but when it is navigated to a local html file it does not.

Some information about the function:

  1. it creates a new ieplorer com-object
  2. it changes some properties for the iexporer com-object.
  3. it uses the navigate function from the ieplorer com-object with the specified URL
  4. it return the process object for this com-object based on the HWND.

The issue exist at step 4, it is a simple where logic:

Get-Process -Name iexplore | Where-Object {$_.MainWindowHandle -eq $ie.HWND}

I tried several things even building in a delay but somehow it does not work. If try the logic from outside the function by directly specifying the HWND it does work, example:

PS C:\> Start-IELockedDown localhost
HWND = 659256
HWND Type = int
IE Processes:
@{Name=iexplore; MainWindowHandle=919956}
@{Name=iexplore; MainWindowHandle=397090}
@{Name=iexplore; MainWindowHandle=659256} #matching Entry
@{Name=iexplore; MainWindowHandle=0}
@{Name=iexplore; MainWindowHandle=69090}
@{Name=iexplore; MainWindowHandle=0}
IE with correct HWND
#Nothing?
After this comes the RETURN:
#Also Nothing!

PS C:\> Get-Process -Name iexplore | Where-Object {$_.MainWindowHandle -eq 659256}

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
    582      42     9656      30940       0,50  10260   2 iexplore

Debug Examples:

1 When I run command with a external and working website like this Start-IELockedDown google.nl it actually works:

HWND = 921524
IE Processes:
@{Name=iexplore; MainWindowHandle=921524} #Matching entry
@{Name=iexplore; MainWindowHandle=724706}
@{Name=iexplore; MainWindowHandle=69090}
@{Name=iexplore; MainWindowHandle=0}
IE with correct HWND
@{Name=iexplore; MainWindowHandle=921524} #Logic works
After this comes the RETURN:

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
    480      31     7092      26848       0,22  18912   2 iexplore

2 When I use a filepath instead of external website like this Start-IELockedDown (Get-Item .\blank-page.html | Select-Object -ExpandProperty FullName) the logic seems to break:

HWND = 3015698
IE Processes:
@{Name=iexplore; MainWindowHandle=0}
@{Name=iexplore; MainWindowHandle=3015698} #Matching Entry
@{Name=iexplore; MainWindowHandle=1248958}
@{Name=iexplore; MainWindowHandle=69090}
@{Name=iexplore; MainWindowHandle=0}
IE with correct HWND
#Nothing?
After this comes the RETURN:
#Also nothing!

3 When I run it against localhost which does not respond as I have no local webserver running like this Start-IELockedDown LocalHost it gives me the same issue:

HWND = 986890
IE Processes:
@{Name=iexplore; MainWindowHandle=986890} #Matching Entry
@{Name=iexplore; MainWindowHandle=1051034}
@{Name=iexplore; MainWindowHandle=69090}
@{Name=iexplore; MainWindowHandle=2361678}
@{Name=iexplore; MainWindowHandle=0}
IE with correct HWND
#Nothing?
After this comes the RETURN:
#Also Nothing!

Full Code:

function Start-IELockedDown {
    <#
    .SYNOPSIS
        Open IE without navigation controlls.
    .DESCRIPTION
        Long description
    .EXAMPLE
        PS C:\> Invoke-IELockedDown -URL "http://localhost:8080/"
        Opens a Internet Explorer browser window without navigational controls that navigates to the specified URL.
    .INPUTS
        None
    .OUTPUTS
        InternetExplorer Process Object.
    .NOTES
        General notes
    #>
    [CmdletBinding()]
    param (
        [string] $URL
    )
    
    # Create IE com object
    $ie = New-Object -com InternetExplorer.Application

    # Turns off the unnecessary menus and tools and sets the window as resizable
    $ie.AddressBar = $false
    $ie.MenuBar = $false
    $ie.ToolBar = $false
    $ie.Resizable = $true
    $ie.StatusBar = $false

    # Sets the size of the window and make it visible
    $ie.Top = 20
    $ie.Left = 20
    $ie.Width = 1280
    $ie.Height = 1024
    $ie.Visible = $true

    ## Navigate the browser to the specified URL.
    $ie.Navigate($URL)        
    
    # For Debugging / the StackOverflow Guru's
    Write-host "HWND = $($ie.HWND)"
    Write-Host "IE Processes:"
    Get-Process -Name iexplore | Select-Object Name, MainWindowHandle | Write-host
    Write-Host "IE with correct HWND"
    Get-Process -Name iexplore | Select-Object Name, MainWindowHandle | Where-Object {$_.MainWindowHandle -eq $ie.HWND} | Write-Host    
    Write-Host "After this comes the RETURN:"    

    # Return the Process Object for the IE Com Object
    return Get-Process -Name iexplore | Where-Object {$_.MainWindowHandle -eq $ie.HWND}
}

Solution

  • This issue appears to only exist for non-elevated sessions of PowerShell. If you would like to resolve this you can either run an elevated session of PowerShell (i.e. Run As Administrator) or you can capture the HWND before you navigate to the URL, and reference that.

    function Start-IELockedDown {
        <#
        .SYNOPSIS
            Open IE without navigation controlls.
        .DESCRIPTION
            Long description
        .EXAMPLE
            PS C:\> Invoke-IELockedDown -URL "http://localhost:8080/"
            Opens a Internet Explorer browser window without navigational controlls that navigates to the specified URL.
        .INPUTS
            None
        .OUTPUTS
            InternetExplorer Process Object.
        .NOTES
            General notes
        #>
        [CmdletBinding()]
        param (
            [string] $URL
        )
    
        # Create IE com object
        $ie = New-Object -com InternetExplorer.Application
        $HWND = $ie.HWND
    
        # Turns off the unnecessary menus and tools and sets the window as resizable
        $ie.AddressBar = $false
        $ie.MenuBar = $false
        $ie.ToolBar = $false
        $ie.Resizable = $true
        $ie.StatusBar = $false
    
        # Sets the size of the window and make it visible
        $ie.Top = 20
        $ie.Left = 20
        $ie.Width = 1280
        $ie.Height = 1024
        $ie.Visible = $true
    
        ## Navigate the browser to the specified URL.
        $ie.Navigate($URL)        
    
        # For Debugging / the StackOverflow Guru's
        Write-host "HWND = $($ie.HWND)"
        Write-Host "IE Processes:"
        Get-Process -Name iexplore | Select-Object Name, MainWindowHandle | Write-host
        Write-Host "IE with correct HWND"
        Get-Process -Name iexplore | Select-Object Name, MainWindowHandle | Where-Object {$_.MainWindowHandle -eq $HWND} | Write-Host    
        Write-Host "After this comes the RETURN:"    
    
        # Return the Process Object for the IE Com Object
        return Get-Process -Name iexplore | Where-Object {$_.MainWindowHandle -eq $HWND}
    }