PowerShell

PowerShell: How to automatically restart applications when they were closed

If you want an application always started and available then this article is for you. Sometimes an application is mistakenly closed by the user. This article shows a step-by-step scenario how to configure a scheduled task watching the status of your application.

Prerequisites

Well, we are going to use a PowerShell three-iner. For the execution of PowerShell script files we have to take a glance at the PowerShell Executionpolicy. Make sure the policy setting is configured to remotesigned (recommended) or unrestricted.

Get-ExecutionPolicy

1.PNG

If you see Restricted, run

Set-ExecutionPolicy remotesigned -Force

2.PNG

PowerShell script for checking the status of the application (started / not started)

Open PowerShell ISE. (Type ise in PowerShell). Copy the code into your ISE session.

If (!(Get-Process -Name notepad.exe -ErrorAction SilentlyContinue))
{Invoke-Item C:\Windows\notepad.exe
}

Let’s stay here for a short explanation. The If Statement checks if notepad.exe is running. The ! at the beginning of the command is a NOT statement. Only if notepad is not running, Invoke-Item will start notepad again.

Save the script. I name it notepad.ps1.

Unbenannt.PNG

Now we can move on and put the script in a scheduled task. Unfortunately, I have to tell you this is not a good idea. Why? PowerShell will pop up every time the script runs. That’s annoying. The good news: I have a workaround for that. We call the PowerShell script from a VB script!

Creating the VB script

Open notepad. Type the following:

command = "powershell.exe -nologo -command C:\Temp\notepad.ps1"
set shell = CreateObject("WScript.Shell")
shell.Run command,0

Unbenannt.PNGNow we have two files: A PowerShell Script and a VB Script.

Unbenannt.PNG

Configuring a Scheduled Task to run every 60 seconds

Open PowerShell ISE. First, think about which user you want to create the task for. In the following code example the task will be configured for the local user account patrick. Pay also attention to the path of your VB script (Line 1):

$Action=New-ScheduledTaskAction -Execute "C:\Temp\notepad.vbs"
$Trigger=New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 1)
$Set=New-ScheduledTaskSettingsSet
$Principal=New-ScheduledTaskPrincipal -UserId "patrick" -LogonType Interactive
$Task=New-ScheduledTask -Action $Action -Trigger $Trigger -Settings $Set -Principal $Principal
Register-ScheduledTask -TaskName "Start Notepad" -InputObject $Task

When Patrick logs on and if notepad is not started, then the task will start it. That happens every 60 seconds. Configurations less than 1 minute are not supported.

No pain no gain

End of subject.

Writing that Scheduled Task script was a nightmare. I had a typo and a logical error and couldn’t find them for over an hour. No pain no gain. 😉

Don’t worry. All of the above is working. Have fun with it!

Further thoughts

If you like Scheduled Tasks and PowerShell, then have a look at my articles

How to schedule software installation with PowerShell

Configuring the automatic start of PowerShell at every logon

10 replies »

  1. So mine is not working. My Synology.vbs when I run it works not problem. But this doesnt run every minute. i’ve logged off and back on, and doesn’t run period. What am i missing?

    $Action=New-ScheduledTaskAction -Execute “C:\Temp\Synology.vbs”
    $Trigger=New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 1)
    $Set=New-ScheduledTaskSettingsSet
    $Principal=New-ScheduledTaskPrincipal -UserId “brandon” -LogonType Interactive
    $Task=New-ScheduledTask -Action $Action -Trigger $Trigger -Settings $Set -Principal $Principal
    Register-ScheduledTask -TaskName “Start Synolog” -InputObject $Task

    Like

  2. I also have the same issue as Fernando Viana.
    I found getting rid of the .exe from the process name worked
    Original
    If (!(Get-Process -Name notepad.exe -ErrorAction SilentlyContinue))
    {Invoke-Item C:\Windows\notepad.exe
    }

    Working
    If (!(Get-Process -Name notepad -ErrorAction SilentlyContinue))
    {Invoke-Item C:\Windows\notepad.exe
    }

    Liked by 2 people

  3. Hello! I tried to do exactly like you, however the notepad opens every 1 minute, that way. It’s as if the script you created did not check if the process is already open and commands to open a new instance anyway. First I tried with my application, after the same way that you put in your example (notepad), both did not work. What could be going wrong? Thanks a lot!

    Like

      • I don’t know what I may have done wrong, but I put everything exactly as you put it in the article, including the path of the files (Temp folder), changing only the user according to mine here. Even so, Notepad opened every 1 minute, even though an instance has already been opened. I don’t know if it is a particularity of my system, but I did the test using PowerShell x64 and x86 with administrator privileges and remotesigned (I have both x64 and x86 installed on my Windows 10 Pro x64 don’t know why). I don’t know if there’s any other way to prevent Windows from opening more than one instance of the applications, because with my application it happened the same way as Notepad in the test.

        Thanks for you reply!

        Regards,
        Fernando.

        Liked by 1 person

      • Use this one

        I also have the same issue as Fernando Viana.
        I found getting rid of the .exe from the process name worked
        Original
        If (!(Get-Process -Name notepad.exe -ErrorAction SilentlyContinue))
        {Invoke-Item C:\Windows\notepad.exe
        }

        Working
        If (!(Get-Process -Name notepad -ErrorAction SilentlyContinue))
        {Invoke-Item C:\Windows\notepad.exe
        }

        Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.