PS: How To Run As A Scheduled Task

3 minute read

Description:

Many times you will want PS to run as a scheduled task on computers. I have changed this post so many times over the last couple months so here is my final version (works in my env):


To Resolve:

  1. You have two options, run the .ps1 file directly, or, my preferred way with three files per script:

1a. For each .ps1 file, I also have a .log and a .bat that goes with it.

1b. The .bat is simply the batch file use to call the powershell script. I include “pause” on the end if I am running interactively, or remove it if the script will be a scheduled task.

Contents:

@ECHO OFF
PowerShell.exe -NoProfile -Command “& {Start-Process PowerShell.exe -ArgumentList ‘-NoProfile -ExecutionPolicy Bypass -File “”%~dpn0.ps1″”‘ -Verb RunAs}

NOTE: It is absolutely important that if you use this method, the .bat and the .ps1 need to HAVE THE SAME NAME

1c. The .log file is generated by scripts automatically because I prefer to see logging in a file instead of on the console.

# Let’s get started – Open the Windows Task Scheduler using whichever method you prefer.

  1. Setup the scheduled task:

2a. Create a basic task. Click the “Change User or Group” and select SYSTEM. Mark it as “Run whether user is logged in or not” and check the “run with highest privileges”. You can leave the “configure for” as the default (Vista/Server08)

2b. Trigger: Set it to run “On A Schedule” – Daily start at 12:05 AM, repeat every 5/10 minutes for a duration of 1 day/indefinitely. Obviously, replace with whatever you want.

2c. Action: Start a Program – C:\Scripts\scriptname.bat , start in: C:\Scripts. That’s it!

NOTE: For Powershell you could set it up like:

Start a program – Powershell.exe , Add Arguments: .\scriptname.ps1 -NoProfile -ExecutionPolicy Bypass -Verb RunAs , Start in: C:\Scripts\

# I almost always have problems with this though, hence why I prefer the batch file method.

  1. Once completed, you can check your “scriptname.log” to make sure it is actually running.

See my post on PS: Logging for details on logging.

The Powershell Way:

Example:

$taskName = "Chocolatey Daily Upgrade"
$taskAction = New-ScheduledTaskAction –Execute C:\programdata\chocolatey\choco.exe -Argument "upgrade all -y"
$taskTrigger = New-ScheduledTaskTrigger -At 2am -Daily
$taskUser = "System"
Register-ScheduledTask –TaskName $taskName -Action $taskAction –Trigger $taskTrigger -User $taskUser
Clear-Host

I was going to break this into a new post, but I don’t want people having to search all over the site so here is more notes:

To Lock Screen Every 5 Minutes Of Inactivity:

$TaskName = "LockScreen"
$service = New-Object -ComObject("Schedule.Service")
$service.Connect()
$rootFolder = $service.GetFolder("")
$taskdef = $service.NewTask(0)
$sets = $taskdef.Settings
$sets.AllowDemandStart = $true
$sets.Compatibility = 2
$sets.Enabled = $true
$sets.RunOnlyIfIdle = $true
$sets.IdleSettings.IdleDuration = "PT05M"
$sets.IdleSettings.WaitTimeout = "PT60M"
$sets.IdleSettings.StopOnIdleEnd = $true
$trg = $taskdef.Triggers.Create(6)
$act = $taskdef.Actions.Create(0)
$act.Path = "C:\Windows\system32\rundll32.exe"
$act.Arguments = "user32.dll,LockWorkStation"
$username = "$env:userdomain" + "\" + "$env:username"
$user = "$username"
$rootFolder.RegisterTaskDefinition($TaskName, $taskdef, 6, $user, $null, 3)

PS Scheduled Task To Launch A Batch Script:

$tName = "RunMyScript"
$tCommand = "C:\scripts\startup.bat"
$tAction = New-ScheduledTaskAction -Execute "$tCommand"
$uName = "$env:userdomain" + "\" + "$env:username"
$tTrigger = New-ScheduledTaskTrigger -AtLogOn -User $username
Register-ScheduledTask -Action $tAction -Trigger $tTrigger -TaskName "$tName" -User $uName

PS Scheduled Task To Launch A Powershell Script:

$tName = "RunMyScript"
$tCommand = "C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe"
$tArgs = "-NoProfile -ExecutionPolicy Bypass -File C:\scripts\temp.ps1"
$tAction = New-ScheduledTaskAction -Execute "$tCommand" -Argument $tArgs
$uName = "$env:userdomain" + "\" + "$env:username"
$tTrigger = New-ScheduledTaskTrigger -Daily -At "8:05am"
Register-ScheduledTask -Action $tAction -Trigger $tTrigger -TaskName "$tName" -User $uName

PS Scheduled Task As System:

$tName = "RunMyScript"
$tCommand = "C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe"
$tArgs = "-NoProfile -ExecutionPolicy Bypass -File C:\_gwill\google\temp\temp.ps1"
$tAction = New-ScheduledTaskAction -Execute "$tCommand" -Argument $tArgs
$uName = "NT Authority" + "\" + "System"
$tTrigger = New-ScheduledTaskTrigger -Daily -At "8:05am"
Register-ScheduledTask -Action $tAction -Trigger $tTrigger -TaskName "$tName" -User $uName

Using Jobs To Run Specific Commands:

# NOTE: I like to use commands that output something to a file for these tasks as I'm pretty sure you won't see
# a powershell window pop up. Haven't tried though!
# See more about jobs at https://blogs.technet.microsoft.com/heyscriptingguy/2014/05/12/introduction-to-powershell-scheduled-jobs/
$taskName = "RunScriptblock"
$scriptBlock = {
"hello world" | Out-File C:\scripts\test.txt -Append
"hello world2" | Out-File C:\scripts\test.txt -Append
"hello world3" | Out-File C:\scripts\test.txt -Append
}
$taskTrigger = New-JobTrigger -Daily -At "12:05 AM"
$taskUser = "domain.com\user"
Register-ScheduledJob –Name $taskName -Credential $taskUser -ScriptBlock $scriptBlock -Trigger $taskTrigger
# can be viewed at Task Scheduler Library\Microsoft\Windows\Powershell\ScheduledJobs