How to properly close Internet Explorer when launched from PowerShell?
Simply calling the Quit()
method should normally suffice for gracefully terminating Internet Explorer processes, regardless of whether they were created by running iexplore.exe
or by instantiating a COM object in PowerShell.
Demonstration:
PS C:\> $env:PROCESSOR_ARCHITECTUREAMD64PS C:\> (Get-WmiObject -Class Win32_OperatingSystem).CaptionMicrosoft Windows 8.1 EnterprisePS C:\> Get-Process | ? { $_.ProcessName -eq 'iexplore' }PS C:\> $ie = New-Object -COM 'InternetExplorer.Application'PS C:\> Get-Process | ? { $_.ProcessName -eq 'iexplore' }Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName------- ------ ----- ----- ----- ------ -- ----------- 352 20 4244 14164 176 0.05 3460 iexplore 407 32 6428 23316 182 0.23 5356 iexplorePS C:\> $ie.Quit()PS C:\> Get-Process | ? { $_.ProcessName -eq 'iexplore' }PS C:\> _
If you have orphaned Internet Explorer processes to which you don't have a handle you can cycle through them like this:
(New-Object -COM 'Shell.Application').Windows() | Where-Object { $_.Name -like '*Internet Explorer*'} | ForEach-Object { $_.Quit()}
To be totally on the safe side you can release the COM object after calling Quit()
and then wait for the garbage collector to clean up:
(New-Object -COM 'Shell.Application').Windows() | Where-Object { $_.Name -like '*Internet Explorer*'} | ForEach-Object { $_.Quit() [Runtime.Interopservices.Marshal]::ReleaseComObject($_)}[GC]::Collect()[GC]::WaitForPendingFinalizers()
I've had similar problems with COM objects that wouldn't terminate using the quit() method. Interopservices.marshall also doesn't work a lot of times.My workaround : I do a get-process to get a list of all procs before I call the com object and right after : this way I have the PID of my instance. After my script runs it kills the process using stop-process.
Not the best way to do this but at least it works
With a quick look around in the ComObject for IE, it seems that when it is created, it gives you a direct interface to the methods that make interacting with IE easier, for example Navigate()
or ReadyState
.
I did discover a property that seems to be what you are looking for and that would be Parent
Calling $IE.Parent.Quit()
seemed to get rid of the PowerShell created instances.
$IE = New-Object -ComObject InternetExplorer.ApplicationGet-Process | Where-Object {$_.Name -Match "iex"}Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName------- ------ ----- ----- ----- ------ -- ----------- 291 20 5464 14156 200 0.16 1320 iexplore 390 30 5804 20628 163 0.14 5704 iexplore$IE.Parent.Quit()(Get-Process | Where-Object {$_.Name -Match "iex"}).GetType()You cannot call a method on a null-valued expression...