locked
Powershell to close a running program gracefully without use's interact RRS feed

  • Question

  • I have this powershell code to close a program gracefully

    Get-Process MyProgram |   Foreach-Object { $_.CloseMainWindow() | Out-Null }

    the problem is that it will pop-up a Windows asking user to hit 'OK' or to 'Cancel'! what powershell code I can force it selects OK and not prompts for user to interact? thanks.


    Thang Mo

    Wednesday, August 28, 2013 5:47 PM

Answers

  • Hi,

    You can try following code:

    Get-Process Myprogram |   Foreach-Object { $_.CloseMainWindow() | Out-Null } | stop-process –force

    For detailed information about stop-process, please refer to:

    Stop-Process

    http://technet.microsoft.com/en-us/library/hh849781.aspx

    Hope these could be helpful.


    Kate Li

    TechNet Community Support

    • Marked as answer by Cloud_TS Thursday, September 5, 2013 12:32 PM
    Thursday, August 29, 2013 10:40 AM

All replies

  • Hi,

    You can try following code:

    Get-Process Myprogram |   Foreach-Object { $_.CloseMainWindow() | Out-Null } | stop-process –force

    For detailed information about stop-process, please refer to:

    Stop-Process

    http://technet.microsoft.com/en-us/library/hh849781.aspx

    Hope these could be helpful.


    Kate Li

    TechNet Community Support

    • Marked as answer by Cloud_TS Thursday, September 5, 2013 12:32 PM
    Thursday, August 29, 2013 10:40 AM
  • what is that program asks you something before it closes..

    for example in my situation im trying to close outlook:

    Get-Process outlook |   Foreach-Object { $_.CloseMainWindow() }

    but when outlook is set to ask the user if he wants to clear the deleted items before it exists...

    i would like to auto answer "no" for example.

    is it doable?

    Tuesday, December 31, 2013 10:41 AM
  • Here is a workaround:

    $wshell = new-object -com wscript.shell

    $wshell.AppActivate("Microsoft Outlook")

    $wshell.sendkeys("{ENTER})

    You could send the signal to "$_.CloseMainWindow()" then check to see if it closed or is waiting for user interaction. If it is still open then run the wscript code to close it. You may want to change the "{ENTER}" to reflect the actual option you want to use fore example ALT + Y would select yes so you can enter that by changing the last line to:

    $wshell.Sendkeys("%(Y)")

    Or if you want to say NO:

    $wshell.Sendkeys("%(N)")

    Hope this helps.

    Regards,

    Here is a full example:

    $isOutlookOpen = Get-Process outlook*
    if($isOutlookOpen = $null){
        # Outlook is already closed run code here:
        }
    else {
         $isOutlookOpen = Get-Process outlook*

         # while loop makes sure all outlook windows are closed before moving on to other code:
             while($isOutlookOpen -ne $null){
                Get-Process outlook* | ForEach-Object {$_.CloseMainWindow() | Out-Null }
                sleep 5
                If(($isOutlookOpen = Get-Process outlook*) -ne $null){
                Write-Host "Outlook is Open.......Closing Outlook"
                    $wshell = new-object -com wscript.shell
                    $wshell.AppActivate("Microsoft Outlook")
                    $wshell.Sendkeys("%(Y)")
                $isOutlookOpen = Get-Process outlook*
                }
            }
            #Outlook has been closed run code here:
        }


    • Proposed as answer by BriGoon Tuesday, January 28, 2014 8:59 PM
    • Edited by BriGoon Tuesday, January 28, 2014 9:38 PM Added Comment in code.
    Tuesday, January 28, 2014 8:56 PM
  • Hi,

    Your script is very interesting.
    In a specific context, if some panel are opened like account parameter panel, it cannot do the action and the script is looping.
    As i run your script from a batch (.bat) like this start /wait PowerShell -NoLogo -WindowStyle Hidden -NoProfile -ExecutionPolicy Bypass -Command "& '%~dp0CloseOutlook.ps1'", the powershell script continues to execute if i close my batch (infinite loop).
    In this case, if i go to other applications, he tries to make the key combination, which could be dangerous.

    Is there any way to modify Powershell script to do hotkey (ALT+Y) only in the Outlook application to prevent the script from interacting with other applications?
    In order to avoid infinite loops in the background, can we also tell him to do ALT + Y 50 to exit powershell script ?
    This will avoid having a process that runs in a loop.

    Many thanks for all.

    Saturday, March 3, 2018 10:32 AM
  • Hi, Do you have any code to close the Microsoft Edge gracefully?  I have tried the below one but the problem arises when I open the Edge, it opens the last previous session as well. I have checked the settings in Edge and it is set to HomePage only. But still <g class="gr_ gr_528 gr-alert gr_gramm gr_inline_cards gr_run_anim Punctuation replaceWithoutSep" data-gr-id="528" id="528">for instance</g> I have 4 extra Tabs opened in Edge, it reopens them all. 

    I have tried your code on other programs such as Firefox, Chrome and it just works fine. <g class="gr_ gr_762 gr-alert gr_gramm gr_inline_cards gr_run_anim Grammar only-ins replaceWithoutSep" data-gr-id="762" id="762">Only</g> Edge is on the Edge!

    The code is as follows (as found on the net)

    @echo off

    for /f "tokens=1 delims=" %%# in ('qprocess^|find /i /c /n "MicrosoftEdg"') do (
        set count=%%#
    )

    <g class="gr_ gr_118 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling" data-gr-id="118" id="118">taskkill</g> /F /IM MicrosoftEdge.exe /T

    echo Number of Microsoft Edge processes removed: %count%

    pause

    Wednesday, August 22, 2018 5:15 AM
  • I know this is a really late response sorry I missed your question. Posting now in case anyone has the same question. Yes, this is not the most elegant solution as sending the key presses can be a risk. That is why i listed as a "workaround"  and not a real solution. There are a few things you could check like validate the active window is outlook but you could still have the same issue crop up. Your suggestion could work just set an iteration value for the while loop instead of checking the outlook process. It just needs to be more than the number of open windows. Something like this will limit the number of times it runs: 

    $i = 0

    $j = 50 

    While($i -lt $j){

        #Run code here

     $i++ 

    }

    If the loop never ends maybe there is an outlook process still running that is not getting closed. You may need to force the process to close but that could cause data loss. 

    Wednesday, January 2, 2019 10:34 PM
  • This worked well but i cleaned it up a little:

    $Process        = "outlook*"
    $OutlookProc = Get-Process -Name $Process

    if($OutlookProc){
        # while loop makes sure all outlook windows are closed
        while($OutlookProc){
            ForEach ($Proc in Get-Process -Name $Process){$Proc.CloseMainWindow()}
            sleep 5
            If (Get-Process -Name $Process){
                Write-Host "Outlook is Open.......Closing Outlook"
                $wshell = new-object -com wscript.shell
                $wshell.AppActivate("Microsoft Outlook")
                $wshell.Sendkeys("%(Y)")
            }
            $OutlookProc = Get-Process -Name $Process
        }
    }

    Wednesday, November 20, 2019 3:39 PM