Trying to kill a process by NAME and CPU Time - powershell

What I'm trying is to close a windows of explorer.exe without killing the whole process, because that will restart the whole taskbar. So far I can only identify it by CPU Time which separated from the windows explorer.exe because it start after.
Is there a PowerShell script or command out there that could help me achieve this?

Take a closer look at the Shell.Application COM Object.
The method 'Windows()' returns an object foreach open explorer-window.
You can call the the method 'Quit()' of these Objects to close the windows, here is a example:
$explorerPathYouWantToKill = "C:\"
$shellApp = New-Object -COM 'Shell.Application'
($shellApp.Windows() | Where-Object {$_.LocationURL -eq "file:///$($explorerPathYouWantToKill.Replace('\','/'))"}) | Foreach {
$_.Quit()
}

Related

unpin folders in windows (os) quick access using cmd command calling powershell from after effects callsystem

anyone could help this out?
Its about powershell use.
Im using inside after effects scripting language: extendscript.
Pinning works, but cant solve unpinning; Tried this and many other ways, before posting.
// Pin folder to quick access (working)
system.callSystem("cmd.exe /c powershell.exe -c \"$qa = New-Object -ComObject shell.application; $qa.NameSpace('C:\\TEST').Self.InvokeVerb(\'pintohome\')\"");
// Unpin folder from quick access (not working):
system.callSystem("cmd.exe /c powershell.exe -c \"($qa.Namespace(\"shell:::{679F85CB-0220-4080-B29B-5540CC05AAB6}\").Items() | Where-Object { $_.Path -EQ 'C:\\TEST' }).InvokeVerb('unpinfromhome')\"");
Tried to follow this post instructions.
Your unpin call doesnt define $qa - each execution of system.callSystem() is starting a new PowerShell instance which is independent. On your attempt to unpin $qa will be undefined / Namespace() wont exist and it will fail.
Try copying the code $qa = New-Object -ComObject shell.application; from the beginning of the pin command and paste it at the beginning of the unpin command like this:
system.callSystem("cmd.exe /c powershell.exe -c \"$qa = New-Object -ComObject shell.application; ($qa.Namespace(\"shell:::{679F85CB-0220-4080-B29B-5540CC05AAB6}\").Items() | Where-Object { $_.Path -EQ 'C:\\TEST' }).InvokeVerb('unpinfromhome')\"");

How to cleanup $IE object, close current processes [duplicate]

There was a set of recently asked questions about doing something with Internet Explorer via PowerShell. All of them contain codes to launch IE from PowerShell as an object, via $ie=new-object -comobject InternetExplorer.Application. The problem is, the proper way of closing IE that consists of calling $ie.quit() does not work - first, if that IE would have happened to have more than a single open tab, IE doesn't quit as a whole and only the tab that corresponds to the COM object is closed, and second, should it have only one tab, the window gets closed but the processes remain.
PS > get-process iexplore
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
352 31 7724 24968 142 0,58 3236 iexplore
228 24 22800 15384 156 0,19 3432 iexplore
I have tried to research the methods on how to close a process started via New-Object -ComObject, and have found this: How to get rid of a COMObject. The example of that COMObject is Excel.Application, which indeed behaves as intended - calling quit() makes window close, and executing [System.Runtime.Interopservices.Marshal]::ReleaseComObject($ex) if $ex is a created COMObject stops the Excel process. But this is not the case with Internet Explorer.
I have also found this question: How to get existing COM Object of a running IE which provides code to connect to IE via list of open windows, and works to an extent of IE launched from elsewhere, but if the COM object is created via PowerShell, this script is not able to completely stop IE's processes, if modified as such:
$shellapp = New-Object -ComObject "Shell.Application"
$ShellWindows = $shellapp.Windows()
for ($i = 0; $i -lt $ShellWindows.Count; $i++)
{
if ($ShellWindows.Item($i).FullName -like "*iexplore.exe")
{
$ie = $ShellWindows.Item($i)
$ie.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($ie)
}
}
In case of IE launched outside of PowerShell, the processes are stopped, but in case of IE launched within PowerShell, two processes remain, and this code reports to have found no IE windows to reach COM objects, therefore IE processes are (yet) unable to be stopped.
So, how to reach the apparently orphaned windowless IE processes and gracefully stop them? I am aware of Get-Process iexplore | Stop-Process, but this will stop any and all IEs, not just those launched by the script, and if the script is run as administrator or SYSTEM on a, say, remote desktop server, everyone's IEs will be stopped.
Environment:
OS Windows 7 x64, PowerShell 4 (installed above PS version 2), IE11 version 11.0.9600.17691 (automatically updated). IE set to "Open home page" upon starting, so at least one tab is always open.
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_ARCHITECTURE
AMD64
PS C:\> (Get-WmiObject -Class Win32_OperatingSystem).Caption
Microsoft Windows 8.1 Enterprise
PS 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 iexplore
PS 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.Application
Get-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...
I tried an experiment with Powershell launching Excel via COM:
$x = New-Object -com Excel.Application
$x.Visible = $True
Start-Sleep 5 # make it stay visible for a little while
$x.Quit()
$x = 0 # Remove .NET's reference to com object
[GC]::collect() # run garbage collection
As soon as [GC]::collect() finished the process disappeared from taskmgr. This makes sense to me, because (in my understanding) a COM client is responsible for releasing references to the COM server. In this case .NET (via a Runtime Callable Wrapper) is the COM client.
The situation may be more complicated with IE, since there may be other tabs associated with a given IE process (and there's the frame merging that #Noseratio mentions), but at least this will get rid of the reference created by the PS script .
There's HKCU\Software\Microsoft\Internet Explorer\Main\FrameMerging registry key that prevents merging IE "frame" processes, explained here. I haven't tried it myself, but I think it might solve your problem if you set it before you instantiate the InternetExplorer.Application COM object.
If that doesn't help, try launching a new IE instance with the following command line, prior to creating the COM object (I haven't tried that, either):
iexplore.exe -noframemerging -private -embedding
There is a possible race condition before this IE instance becomes available as a COM server, so you may want to put some delay before you create an object.
This may be useful to you:
Get-Process | Where-Object {$_.Name -Match "iexplore"} | Stop-Process
This command closes all the Internet Explorer windows that are currently open/running:
Get-Process iexplore | Stop-Process

System hangs in between running a powershell script.

I am trying to automate to extract data from a webpage after clicking on a button. But when I try to execute, the system freezes and it requires hard reboot. Please refer the code below.
$ie = New-Object -ComObject Internetexplorer.application
$ie.visible = $true
$ie.navigate("http://beta.speedtest.net")
while($ie.readystate -ne 4) {
sleep -Milliseconds 100
}
$link = $ie.document.getElementsByTagName("span") |Where-Object {$_.innertext -like "Begin test"}
$link.click()
Reference: Powershell website automating button click on loginenter code here
There is nothing in there which would cause a system freeze.
As you are starting an Internet Explorer instance, I guess IE is crashing your system and it is unreleated to your script or powershell.
You can verify by running the script on another machine.
Then I would try reinstalling IE on the crashing machine.

How to tell if an optical drive has ejected

I am trying to eject an optical disc on a Windows PC connected to a robotic disc changer. I have the following powershell script which works most of the time:
$path=$args[0]
$sh = New-Object -Comobject "Shell.Application"
$sh.Namespace(17).Items() |
Where-Object { $_.Type -eq "Removable Disc" } |
foreach {
if($_.Path -eq $path) { $_.InvokeVerb("Eject") }
}
However, sometimes it doesn't work, presumably because Windows thinks the drive is still in use.
Is there any way I can get a response code from this to tell if it has successfully ejected the disc? Or otherwise tell if the disc is still mounted?
Alternatively, does anyone know a nice C++ way of doing it, which would be even better as I could avoid the need to call a separate script...

Powershell: how to check if any instance of internet explorer is already running

I want to check if any instance of internet explorer, ie any window of it, is already opened or not so that i can decide that a new object has to be created or i have to attach to existing process of that IE window. This is the code below:
$ie = (New-Object -COM "Shell.Application").Windows()| ? { $_.Name -eq "Windows Internet Explorer" }
I want to attach to windows() only when a window of IE is already opened and if no IE window is opened then the line should be like this:
$ie = (New-Object -COM "Shell.Application")
try:
if (
Get-Process iexplore -ea silentlycontinue |
Where-Object {$_.MainWindowTitle -ne ""}
)
if (Get-Process iexplore) { "Yes" } else { "No" }
I have no idea whether this works in a terminal services environment with many user (does a non-elevated Get-Process only look in your own session (and the system session) for processes?)