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.
Start a ProgramC:\Windows\System32\WindowsPowerShell\v1.0\powershell.exeD:\Powershell\test.ps1Win10Script:
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?
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.
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.
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe-WindowStyle Hidden -NoExit -f "D:\testing\script.ps1"Adding a loop on the code, for this you have many options, for exampleGet-EventSubscriber | Wait-Event which, same as before, will keep the task alive indefinitely.
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe-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
A loop that would keep the task alive for X days / hours / minutes:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe-WindowStyle Hidden -f "D:\testing\script.ps1"[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
Last one, similar to the example before but not using an ObjectEvent at all:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe-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