I have a main python script that generates a GUI, and through that GUI I want the user to be able to create, amend, and delete schedules managed by the windows task scheduler.
-
Is using either WMI or schtasks.exe an option ? – FredP Oct 02 '14 at 12:43
-
Ahem... quick google results : http://blog.ziade.org/2007/11/01/scheduling-tasks-in-windows-with-pywin32/ http://sourceforge.net/projects/pytaskscheduler/ Have a nice day :-) – FredP Oct 02 '14 at 13:01
-
This looks like it was written for Python 2.3, so not exactly what I was looking for. Will see if I can scavenge from it though. – I_do_python Oct 02 '14 at 13:48
-
1With `subprocess` you could do: http://stackoverflow.com/a/2725908/660921 – Martin Tournoij Oct 02 '14 at 14:02
-
1@FredP, your solution is incompatible with 3.x. – I_do_python Oct 02 '14 at 14:05
4 Answers
This code creates a task which will run in 5 minutes (uses pywin32):
import datetime
import win32com.client
scheduler = win32com.client.Dispatch('Schedule.Service')
scheduler.Connect()
root_folder = scheduler.GetFolder('\\')
task_def = scheduler.NewTask(0)
# Create trigger
start_time = datetime.datetime.now() + datetime.timedelta(minutes=5)
TASK_TRIGGER_TIME = 1
trigger = task_def.Triggers.Create(TASK_TRIGGER_TIME)
trigger.StartBoundary = start_time.isoformat()
# Create action
TASK_ACTION_EXEC = 0
action = task_def.Actions.Create(TASK_ACTION_EXEC)
action.ID = 'DO NOTHING'
action.Path = 'cmd.exe'
action.Arguments = '/c "exit"'
# Set parameters
task_def.RegistrationInfo.Description = 'Test Task'
task_def.Settings.Enabled = True
task_def.Settings.StopIfGoingOnBatteries = False
# Register task
# If task already exists, it will be updated
TASK_CREATE_OR_UPDATE = 6
TASK_LOGON_NONE = 0
root_folder.RegisterTaskDefinition(
'Test Task', # Task name
task_def,
TASK_CREATE_OR_UPDATE,
'', # No user
'', # No password
TASK_LOGON_NONE)
More info on tasks and their properties here: https://learn.microsoft.com/en-us/windows/desktop/taskschd/task-scheduler-objects

- 2,400
- 24
- 23
Just to round out the option list here... How about just calling the windows command line?
import os
os.system(r'SchTasks /Create /SC DAILY /TN "My Task" /TR "C:mytask.bat" /ST 09:00')
You can launch any executable, batch file, or even another python script - assuming the system is set to execute python...
schtasks has a rich list of options and capabilities...https://learn.microsoft.com/en-us/windows/win32/taskschd/schtasks

- 767
- 7
- 14

- 163
- 3
- 7
PyWin32 provides an interface to the Task Scheduler in win32com.taskscheduler
. You can see an example of it's use here:
Also @FredP linked to a good example that's much simpler:
There is also an interesting tidbit in the wmi module's cookbook about scheduling a job, although it doesn't appear to use the Task Scheduler:

- 2,266
- 3
- 23
- 36

- 32,629
- 8
- 45
- 88
-
Warning: Do not use the WMI method. The service which it depends on seems to be deprecated and not enabled by default (Though you can enable it via registry) since Windows 8: https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-scheduledjob – xendi Sep 12 '20 at 22:43
I also needed a way to use Python to schedule a task in Windows 10. I discovered something simpler, using only subprocess
and PowerShell's Scheduled Tasks cmdlets
, which is more powerful as it gives you finer control over the task to schedule.
And there's no need for a third-party module for this one.
import subprocess
# Use triple quotes string literal to span PowerShell command multiline
STR_CMD = """
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "C:\\path\\to\\file.ps1"
$description = "Using PowerShell's Scheduled Tasks in Python"
$settings = New-ScheduledTaskSettingsSet -DeleteExpiredTaskAfter (New-TimeSpan -Seconds 2)
$taskName = "Test Script"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddSeconds(10)
$trigger.EndBoundary = (Get-Date).AddSeconds(30).ToString("s")
Register-ScheduledTask -TaskName $taskName -Description $description -Action $action -Settings $settings -Trigger $trigger | Out-Null
"""
# Use a list to make it easier to pass argument to subprocess
listProcess = [
"powershell.exe",
"-NoExit",
"-NoProfile",
"-Command",
STR_CMD
]
# Enjoy the magic
subprocess.run(listProcess, check=True)

- 779
- 8
- 16