1

I am trying to use Task Scheduler to run a PS1 script, however it does not seem to work. When I run the task PowerShell opens briefly, but the script does not run. When I execute the script manually it runs as expected.

  • Task Scheduler settings:
    • Action: Start a Program
    • Program: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
    • Arguments: D:\Powershell\test.ps1
    • Configure for: Win10

Script:

Add-Type -AssemblyName System.Windows.Forms
$Timer = [System.Timers.Timer]::new(3000)
Register-ObjectEvent -InputObject $Timer -EventName Elapsed -Action{
    [System.Windows.Forms.SendKeys]::SendWait("%{TAB}")
}

$Timer.Start()

Is there anything I am missing here?

2
  • 3
    Arguments: D:\Powershell\test.ps1 should be -f "D:\Powershell\test.ps1" tho, if this is running as NT AUTHORITY\SYSTEM I don't think it will work Commented Aug 12, 2021 at 21:09
  • If the task runs under the SYSTEM account (add that detail to the question), test whether it actually works under the system account. Also add -ExecutionPolicy bypass. Commented Aug 13, 2021 at 7:41

1 Answer 1

1

As in my comment, to execute a script (*.ps1) you just need to call the -File Argument or -f for short however, doing only this, will not result in what you want (a task that is Alt-Tabbing indefinitely?) because the task would end as soon as the ObjectEvent was registered.

As a workaround, you need to find a way to keep the scheduled task alive, ergo, keep the powershell.exe process running in the background alive.

I'll list a few option so you can decide which one you like more or fits your need.

  1. The easiest one, in my opinion, is just to add the -NoExit argument to your task, this will keep the task alive indefinitely, until, manually ending it / reboot / shutdown / killing the powershell.exe process / etc.

    • Program: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
    • Arguments: -WindowStyle Hidden -NoExit -f "D:\testing\script.ps1"
  2. Adding a loop on the code, for this you have many options, for example
    Get-EventSubscriber | Wait-Event which, same as before, will keep the task alive indefinitely.

    • Program: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
    • Arguments: -WindowStyle Hidden -f "D:\testing\script.ps1"
    Add-Type -AssemblyName System.Windows.Forms
    
    $Timer = [System.Timers.Timer]::new(3000)
    Register-ObjectEvent -InputObject $Timer -EventName Elapsed -Action {
        [System.Windows.Forms.SendKeys]::SendWait('%{TAB}')
    }
    
    $Timer.Start()
    
    Get-EventSubscriber | Wait-Event
    
  3. A loop that would keep the task alive for X days / hours / minutes:

    • Program: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
    • Arguments: -WindowStyle Hidden -f "D:\testing\script.ps1"
    • Code (you can use a [datetime] object instead of [System.Diagnostics.Stopwatch] here, your call):
    Add-Type -AssemblyName System.Windows.Forms
    
    $Timer = [System.Timers.Timer]::new(3000)
    Register-ObjectEvent -InputObject $Timer -EventName Elapsed -Action {
        [System.Windows.Forms.SendKeys]::SendWait('%{TAB}')
    }
    
    $Timer.Start()
    
    $elapsed = [System.Diagnostics.Stopwatch]::StartNew()
    
    do {
        Start-Sleep -Milliseconds 5
    }
    until($elapsed.Elapsed.Minutes -ge 60)
    
    $elapsed.Stop()
    exit 0
    
  4. Last one, similar to the example before but not using an ObjectEvent at all:

    • Program: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
    • Arguments: -WindowStyle Hidden -f "D:\testing\script.ps1"
    Add-Type -AssemblyName System.Windows.Forms
    
    $elapsed = [System.Diagnostics.Stopwatch]::StartNew()
    
    do {
        [System.Windows.Forms.SendKeys]::SendWait('%{TAB}')
        Start-Sleep -Milliseconds 3000
    }
    until($elapsed.Elapsed.Seconds -ge 30)
    
    $elapsed.Stop()
    exit 0
    
Sign up to request clarification or add additional context in comments.

2 Comments

I was able to make this work using your suggestions, thank you for this! The task of alt+tabbing indefinitely was just an easy way for me to identify if the loop was actually running continuously. I really wanted to work through the process of scheduling a task that occurs when the computer goes idle - and in some situation use a loop to continue to do something until interruption.
@hcsuaf if the answer was helpful to you considerer accepting it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.