Как получить задачи из планировщика windows?
Поиск информации о планировщике показал, что есть следующие места, откуда можно получить задачи:
- Как файлы:
C:\Windows\Tasks, задачи описывались в бинарных файлах.job(до Windows Vista, соответствует Task Scheduler 1.0)C:\Windows\System32\Tasks, там каждая задача описывается в виде XML (появилось начиная с Windows Vista, соответствует Task Scheduler 2.0)
- В реестре:
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\Taskcache
- Из утилит:
schtasks.exe- консольная утилитаtaskschd.msc- графическая утилитаwmic.exe- консольная утилита к Инструментарию управления Windows (WMI)
- API:
- COM-объекты
- WMI
Возможно, есть и другие способы получить задачи планировщика.
Как видно, вариантов достаточно и мне показался привлекательным с COM-объектами, хотя и другие варианты тоже могут быть использованы.
Как на python получить список задач планировщика?
Ответы (1 шт):
Текущий способ использует API для работы с COM-объектами, а конкретно с Schedule.Service
Источники:
- https://docs.microsoft.com/en-us/windows/win32/taskschd/taskschedulerschema-task-element
- https://docs.microsoft.com/en-us/windows/win32/taskschd/execaction
- https://docs.microsoft.com/en-us/windows/win32/taskschd/comhandleraction
- https://docs.microsoft.com/en-us/windows/win32/taskschd/emailaction
- https://docs.microsoft.com/en-us/windows/win32/taskschd/showmessageaction
- https://docs.microsoft.com/en-us/windows/win32/taskschd/action-type
Внешние зависимости:
- Модуль
win32com.client, устанавливать библиотекуpywin32
Остались, правда, некоторые непонятные моменты с полями EmailAction: attachments и header_fields, что усложняется тем, что это действие запрещено (для отправки почты рекомендуется использовать, например, ExecAction с скриптом на VBS или PowerShell).
Реализация:
import datetime as DT
import enum
from dataclasses import dataclass, field
from typing import List, TypeVar
import win32com.client
TASK_ENUM_HIDDEN = 1
class TaskStateEnum(enum.IntEnum):
Unknown = 0
Disabled = enum.auto()
Queued = enum.auto()
Ready = enum.auto()
Running = enum.auto()
class TaskActionEnum(enum.IntEnum):
Exec = 0
ComHandler = 5
SendEmail = 6
ShowMessage = 7
@dataclass
class ExecAction:
path: str
working_directory: str
arguments: str
@classmethod
def get_from(cls, action: win32com.client.CDispatch) -> 'ExecAction':
return cls(
path=action.Path,
working_directory=action.WorkingDirectory,
arguments=action.Arguments,
)
@dataclass
class ComHandlerAction:
class_id: str
data: str
@classmethod
def get_from(cls, action: win32com.client.CDispatch) -> 'ComHandlerAction':
return cls(
class_id=action.ClassId,
data=action.Data,
)
@dataclass
class EmailAction:
from_: str
to: str
subject: str
body: str
server: str
# attachments: ??? # TODO: Unknown
bcc: str
cc: str
# header_fields: ??? # TODO: Unknown
reply_to: str
@classmethod
def get_from(cls, action: win32com.client.CDispatch) -> 'EmailAction':
return cls(
from_=action.From,
to=action.To,
subject=action.Subject,
body=action.Body,
server=action.Server,
# attachments=??? # TODO: Unknown
bcc=action.Bcc,
cc=action.Cc,
# header_fields=xxx, # TODO: Unknown
reply_to=action.ReplyTo,
)
@dataclass
class ShowMessageAction:
title: str
message_body: str
@classmethod
def get_from(cls, action: win32com.client.CDispatch) -> 'ShowMessageAction':
return cls(
title=action.Title,
message_body=action.MessageBody,
)
ActionType = TypeVar('ActionType', ExecAction, ComHandlerAction, EmailAction, ShowMessageAction)
@dataclass
class Task:
name: str
path: str
hidden: bool
state: str
enabled: bool
last_run_time: DT.datetime
last_task_result: int
next_run_time: DT.datetime
number_of_missed_runs: int
actions: List[ActionType] = field(default_factory=list)
@classmethod
def get_from(cls, task: win32com.client.CDispatch) -> 'Task':
try:
hidden = task.Definition.Settings.Hidden
except:
hidden = False
try:
def_actions = task.Definition.Actions
except:
def_actions = []
actions = []
for action_com_obj in def_actions:
action_type = TaskActionEnum(action_com_obj.Type)
if action_type == TaskActionEnum.Exec:
actions.append(ExecAction.get_from(action_com_obj))
elif action_type == TaskActionEnum.ComHandler:
actions.append(ComHandlerAction.get_from(action_com_obj))
elif action_type == TaskActionEnum.SendEmail:
actions.append(EmailAction.get_from(action_com_obj))
elif action_type == TaskActionEnum.ShowMessage:
actions.append(ShowMessageAction.get_from(action_com_obj))
return cls(
name=task.Name,
path=task.Path,
hidden=hidden,
state=TaskStateEnum(task.State).name,
enabled=task.Enabled,
last_run_time=task.LastRunTime,
last_task_result=task.LastTaskResult,
next_run_time=task.NextRunTime,
number_of_missed_runs=task.NumberOfMissedRuns,
actions=actions,
)
def get_tasks() -> List[Task]:
items = []
scheduler = win32com.client.Dispatch('Schedule.Service')
scheduler.Connect()
folders = [scheduler.GetFolder('\\')]
while folders:
folder = folders.pop(0)
folders += list(folder.GetFolders(0))
for task_com_obj in folder.GetTasks(TASK_ENUM_HIDDEN):
items.append(
Task.get_from(task_com_obj)
)
return items
Проверка:
items = get_tasks()
print(f'Total task: {len(items)}')
hidden_tasks = [task for task in items if task.hidden]
print(f'Total hidden tasks: {len(hidden_tasks)}')
enabled_tasks = [task for task in items if task.enabled]
print(f'Total enabled tasks: {len(enabled_tasks)}')
hidden_and_enabled_tasks = [task for task in items if task.hidden and task.enabled]
print(f'Total hidden and enabled tasks: {len(hidden_and_enabled_tasks)}')
print()
print('First 10 tasks:')
for i, task in enumerate(items[:10], 1):
print(f' {i}. {task}')
Результат:
Total task: 152
Total hidden tasks: 36
Total enabled tasks: 121
Total hidden and enabled tasks: 27
First 10 tasks:
1. Task(name='Adobe Acrobat Update Task', path='\\Adobe Acrobat Update Task', hidden=False, state='Ready', enabled=True, last_run_time=pywintypes.datetime(2022, 2, 16, 10, 48, 56, tzinfo=TimeZoneInfo('GMT Standard Time', True)), last_task_result=0, next_run_time=pywintypes.datetime(2022, 2, 16, 22, 0, tzinfo=TimeZoneInfo('GMT Standard Time', True)), number_of_missed_runs=0, actions=[ExecAction(path='C:\\Program Files (x86)\\Common Files\\Adobe\\ARM\\1.0\\AdobeARM.exe', working_directory='', arguments='')])
2. Task(name='OneDrive Reporting Task-S-1-5-21-3234346791-3903088639-3192236989-5129', path='\\OneDrive Reporting Task-S-1-5-21-3234346791-3903088639-3192236989-5129', hidden=False, state='Ready', enabled=True, last_run_time=pywintypes.datetime(2022, 2, 15, 20, 35, 18, tzinfo=TimeZoneInfo('GMT Standard Time', True)), last_task_result=0, next_run_time=pywintypes.datetime(2022, 2, 16, 20, 35, 18, tzinfo=TimeZoneInfo('GMT Standard Time', True)), number_of_missed_runs=0, actions=[ExecAction(path='%localappdata%\\Microsoft\\OneDrive\\OneDriveStandaloneUpdater.exe', working_directory='', arguments='/reporting')])
3. Task(name='OneDrive Standalone Update Task-S-1-5-21-3234346791-3903088639-3192236989-5129', path='\\OneDrive Standalone Update Task-S-1-5-21-3234346791-3903088639-3192236989-5129', hidden=False, state='Ready', enabled=True, last_run_time=pywintypes.datetime(2022, 2, 15, 19, 58, 47, tzinfo=TimeZoneInfo('GMT Standard Time', True)), last_task_result=-2147160572, next_run_time=pywintypes.datetime(2022, 2, 16, 22, 46, 49, tzinfo=TimeZoneInfo('GMT Standard Time', True)), number_of_missed_runs=0, actions=[ExecAction(path='%localappdata%\\Microsoft\\OneDrive\\OneDriveStandaloneUpdater.exe', working_directory='', arguments='')])
4. Task(name='RtkAudUService64_BG', path='\\RtkAudUService64_BG', hidden=False, state='Running', enabled=True, last_run_time=pywintypes.datetime(2022, 2, 10, 11, 7, 26, tzinfo=TimeZoneInfo('GMT Standard Time', True)), last_task_result=267009, next_run_time=pywintypes.datetime(1899, 12, 30, 0, 0, tzinfo=TimeZoneInfo('GMT Standard Time', True)), number_of_missed_runs=0, actions=[ExecAction(path='""C:\\Windows\\System32\\DriverStore\\FileRepository\\realtekservice.inf_amd64_63ffa3cb4ae6dbc0\\RtkAudUService64.exe""', working_directory='', arguments='-background')])
5. Task(name='RunUninstallTool_SkipUac', path='\\RunUninstallTool_SkipUac', hidden=False, state='Ready', enabled=True, last_run_time=pywintypes.datetime(2022, 1, 10, 12, 20, 44, tzinfo=TimeZoneInfo('GMT Standard Time', True)), last_task_result=0, next_run_time=pywintypes.datetime(1899, 12, 30, 0, 0, tzinfo=TimeZoneInfo('GMT Standard Time', True)), number_of_missed_runs=0, actions=[ExecAction(path='C:\\Program Files\\Uninstall Tool\\UninstallTool.exe', working_directory='', arguments='$(Arg0)')])
6. Task(name='Firefox Default Browser Agent 308046B0AF4A39CB', path='\\Mozilla\\Firefox Default Browser Agent 308046B0AF4A39CB', hidden=False, state='Ready', enabled=True, last_run_time=pywintypes.datetime(2022, 2, 16, 11, 8, 43, tzinfo=TimeZoneInfo('GMT Standard Time', True)), last_task_result=0, next_run_time=pywintypes.datetime(2022, 2, 17, 11, 8, 42, tzinfo=TimeZoneInfo('GMT Standard Time', True)), number_of_missed_runs=0, actions=[ExecAction(path='C:\\Program Files\\Mozilla Firefox\\default-browser-agent.exe', working_directory='', arguments='do-task "308046B0AF4A39CB"')])
7. Task(name='S-1-5-21-3234346791-3903088639-3192236989-5129', path='\\Lenovo\\Lenovo Service Bridge\\S-1-5-21-3234346791-3903088639-3192236989-5129', hidden=False, state='Ready', enabled=True, last_run_time=pywintypes.datetime(2022, 2, 16, 11, 11, 56, tzinfo=TimeZoneInfo('GMT Standard Time', True)), last_task_result=0, next_run_time=pywintypes.datetime(1899, 12, 30, 0, 0, tzinfo=TimeZoneInfo('GMT Standard Time', True)), number_of_missed_runs=0, actions=[ExecAction(path='"C:\\Users\\<...>\\AppData\\Local\\Programs\\Lenovo\\Lenovo Service Bridge\\LSBUpdater.exe"', working_directory='', arguments='')])
8. Task(name='Background monitor', path='\\Lenovo\\Power Manager\\Background monitor', hidden=False, state='Running', enabled=True, last_run_time=pywintypes.datetime(2022, 2, 10, 11, 6, 56, tzinfo=TimeZoneInfo('GMT Standard Time', True)), last_task_result=267009, next_run_time=pywintypes.datetime(1899, 12, 30, 0, 0, tzinfo=TimeZoneInfo('GMT Standard Time', True)), number_of_missed_runs=0, actions=[ExecAction(path='"C:\\Windows\\SysWOW64\\Lenovo\\PowerMgr\\PowerMgr.exe"', working_directory='', arguments='')])
9. Task(name='Office 15 Subscription Heartbeat', path='\\Microsoft\\Office\\Office 15 Subscription Heartbeat', hidden=False, state='Ready', enabled=True, last_run_time=pywintypes.datetime(2022, 2, 16, 2, 52, 14, tzinfo=TimeZoneInfo('GMT Standard Time', True)), last_task_result=0, next_run_time=pywintypes.datetime(2022, 2, 17, 0, 42, 32, tzinfo=TimeZoneInfo('GMT Standard Time', True)), number_of_missed_runs=0, actions=[ExecAction(path='%ProgramFiles%\\Common Files\\Microsoft Shared\\Office16\\OLicenseHeartbeat.exe', working_directory='', arguments='')])
10. Task(name='OfficeTelemetryAgentFallBack2016', path='\\Microsoft\\Office\\OfficeTelemetryAgentFallBack2016', hidden=False, state='Ready', enabled=True, last_run_time=pywintypes.datetime(2022, 2, 15, 23, 36, 56, tzinfo=TimeZoneInfo('GMT Standard Time', True)), last_task_result=0, next_run_time=pywintypes.datetime(1899, 12, 30, 0, 0, tzinfo=TimeZoneInfo('GMT Standard Time', True)), number_of_missed_runs=0, actions=[ExecAction(path='"C:\\Program Files\\Microsoft Office\\Office16\\msoia.exe"', working_directory='', arguments='scan upload mininterval:2880')])