Служба Task Scheduler в Windows — очень полезный инструмент автоматизации. Начиная с версий Windows Vista и Windows Server 2008, служба Task Scheduler была переработана. Она имеет новые типы триггеров, действия и папки задач. Кроме того, она имеет встроенный интерфейс объектов, поддерживающий выполнение сценариев для управления запланированными задачами. Компания Microsoft предоставляла этот интерфейс для Task Scheduler и в более ранних версиях Windows, но его надо было загружать отдельно. На экране 1 показано окно обновленной службы Task Scheduler в системе Windows 7.

Task Scheduler в Windows 7
Экран 1. Task Scheduler в Windows 7

В системах Windows Server 2003, Windows XP и Windows 2000 запланированные задачи представляют собой файлы с расширением. job, которые находятся в папке \%SystemRoot%\Tasks. В этих версиях операционных систем переименование задач выполняется очень просто: нажмите клавишу F2, когда задача будет выделена в проводнике Windows, или щелкните правой кнопкой мыши по заданию в окне Task Scheduler и выберите пункт Rename. В системах Windows 7, Vista и Server 2008 задания Task Scheduler больше не хранятся в виде. job-файлов в папке Tasks, поэтому переименовать запланированное задание после его создания нельзя.

Я не знаю причины, по которой эта, казалось бы, простая возможность не была реализована, но есть обходной путь: экспортировать задачу в файл XML, импортировать задачу, чтобы создать новое задание с новым именем, а затем удалить старую задачу. Эти действия я счел лишней тратой времени и написал сценарий PowerShell Rename-ScheduledTask.ps1 (листинг 1), позволяющий упростить процесс переименования задачи.

Сценарий работает только в системах Windows 7, Vista и Server 2008 по двум причинам. Во-первых, этот сценарий в более ранних версиях операционной системы не нужен. Во-вторых, интерфейс объектов, поддерживающий выполнение сценариев и используемый данным сценарием, отсутствует в более ранних версиях операционной системы. Вы можете использовать сценарий для переименования задач на локальном компьютере и на удаленных компьютерах. Если вы хотите переименовать задание на локальном компьютере, необходимо запустить сценарий в PowerShell с повышенными правами (то есть щелкнуть правой кнопкой мыши по ярлыку PowerShell и выбрать пункт Run as administrator).

Как использовать сценарий

Синтаксис командной строки сценария выглядит следующим образом:

Rename ScheduledTask
   [TaskName] 
   [NewName] 
   [ComputerName ]
   [ConnectionCredential ]
   [TaskCredential ]

Обязательными являются только параметры -TaskName и -NewName, которые вы используете, чтобы указать имя исходной задачи и новое имя соответственно. Поскольку параметры -TaskName и -NewName должны быть первым и вторым параметром в командной строке сценария, прописывать названия параметров (-TaskName и -NewName) необязательно.

Переработанная служба Task Scheduler поддерживает использование папок задач. Если указать имя задачи без имени папки задачи, сценарий посчитает, что задача находится в корневой папке задач («\»). Вы можете переместить задачу в другую папку, указав имя папки задачи как часть нового имени задачи. Если папка задачи не существует, она будет создана. Например, команда

Rename ScheduledTask
   "My Task"
   "\User Tasks\User Task 1"

переименовывает задачу с именем \My Task в \User Tasks\User Task 1. Папка \User Tasks будет создана, если она не существует.

Вы можете использовать параметр -ComputerName, чтобы указать компьютер, на котором находится задача, которая будет переименована. Вы не можете перемещать задачи между компьютерами, поэтому переименованная задача будет храниться на том же компьютере, что и старая. Если вы опустите параметр -ComputerName, сценарий посчитает, что задача, которую необходимо переименовать, находится на текущем компьютере.

Параметр -ConnectionCredential задает объект PSCredential для подключения к службе Task Scheduler на компьютере (который будет локальным, если вы пропустили параметр -ComputerName). Обратите внимание, что сценарий Rename-ScheduledTask.ps1 переименовывает задачу путем копирования исходной задачи в новую задачу, а затем удаляя исходную. Это означает, что, если исходная задача имеет сохраненные учетные данные, они не могут быть скопированы, поскольку учетные данные хранятся в защищенном виде. Поэтому, прежде чем использовать параметр -ConnectionCredential, необходимо проверить свойства задачи, чтобы узнать, имеет ли она сохраненные учетные данные. Как показано на экране 2, если выбран режим Run whether user is logged on or not, а параметр Do not store password не отмечен, учетные данные сохраняются в задаче. Следовательно, после создания новой задачи учетные данные также должны быть воссозданы.

Свойства задачи
Экран 2. Свойства задачи

Если исходная задача содержит сохраненные учетные данные, сценарий Rename-ScheduledTask.ps1 попросит вас задать учетные данные при создании копии. Если вы не хотите, чтобы сценарий запрашивал у вас учетные данные, можете указать параметр -TaskCredential, который запрашивает объект PSCredential в качестве аргумента (подробнее об этом рассказано во врезке «Неразбериха с учетными записями» для получения дополнительной информации о параметрах -ConnectionCredential и -TaskCredential).

Помимо неспособности скопировать учетные данные, у сценария есть еще один важный побочный эффект: новая копия задачи не будет иметь журнала событий исходной задачи, который отображается во вкладке History страницы настроек. Если журнал событий задачи важен для вас, перед переименованием сохраните историю в файл.

Интерактивная справка сценария содержит полный список образцов команд. Чтобы просмотреть примеры команд, запустите следующий код в строке PowerShell:

Get-Help Rename ScheduledTask -full |
   more

Внутри сценария

Сценарий Rename-ScheduledTask.ps1 использует программный идентификатор Schedule.Service, чтобы обратиться к объекту TaskService, который обеспечивает доступ к службе Task Scheduler для управления зарегистрированными задачами. Объект TaskService не существует в версиях Windows, выпущенных до появления Vista и Server 2008. Дополнительную информацию об объекте TaskService и объектах, связанных с ним, можно найти в статье «Task Scheduler Scripting Objects» (msdn.microsoft.com/enus/library/aa383607.aspx).

Затем сценарий использует метод Connect объекта TaskService, чтобы попытаться подключиться к службе Task Scheduler. Если параметр -ConnectionCredential присутствует в командной строке, сценарий использует функцию get-plaintextpwd, как показано в листинге 2, для получения свойства Password объекта PSCredential в виде текстовой строки. Сценарий работает подобным образом в связи с тем, что метод Connect объекта TaskService не поддерживает работу с объектами PSCredential.

После подключения к службе Task Scheduler сценарий проверяет свойство HighestVersion объекта TaskService. Это свойство является 32-разрядным целым числом без знака, которое содержит внутренний номер версии службы Task Scheduler. Старшие 16 разрядов содержат основной номер версии, а младшие 16 разрядов представляют дополнительный номер версии. Версия службы Task Scheduler в системах Windows 7, Vista и Server 2008 имеет внутренний номер 1.2 (65538), поэтому сценарий следит за тем, чтобы значение HighestVersion было, по крайней мере, не ниже данного значения, прежде чем продолжить работу. Если версия службы слишком старая, сценарий выдает ошибку и завершает работу.

Если версия службы Task Scheduler удовлетворяет условию, сценарий использует метод GetFolder объекта TaskService, чтобы получить корневую папку задач. Затем сценарий использует функцию Get-taskname, как показано в листинге 3, чтобы получить список всех имен задач из всех папок задач. Он обращается к списку имен задач, чтобы проверить правильность параметров -TaskName и -NewName.

Далее, сценарий Rename-ScheduledTask.ps1 получает объект TaskDefinition для задачи с именем, указанным в параметре TaskName. Объект TaskDefinition определяет все компоненты задачи. Если задача имеет сохраненные учетные данные, сценарий проверяет, был ли задан параметр -TaskCredential. Если он не был задан, сценарий использует команду Get-Credential для выполнения запроса на ввод учетных данных. Отмена этого запроса генерирует ошибку и завершает работу сценария. Если параметр -TaskCredential был задан, сценарий использует функцию get-plaintextpwd для преобразования свойства Password объекта PSCredential в обычный текст.

И наконец, сценарий использует метод RegisterTaskDefinition для создания копии задачи. Заметим, что, если задача требует наличия учетных данных, но предоставленные учетные данные не являются допустимыми, задача не будет создана и сценарий выдаст ошибку. Если сценарий успешно создаст новую задачу, он использует метод DeleteTask объекта TaskFolder исходной задачи, чтобы удалить ее.

.

Неразбериха с учетными записями

При переименовании запланированного задания при помощи сценария Rename-Scheduled

Task.ps1 вам могут потребоваться два набора учетных данных.

  • Параметр -ConnectionCredential задает учетные данные, используемые для подключения к службе Task Scheduler на локальном или удаленном компьютере, где хранится задача. Если вы не являетесь членом группы администраторов на компьютере, где размещается задача, вы можете подключиться к службе Task Scheduler с помощью учетных данных администратора.
  • Параметр -TaskCredential при необходимости задает учетные данные для самой задачи. Учетные данные задания необходимы только тогда, когда опция Run whether user is logged on or not выбрана, а опция Do not store password не отмечена. Если учетные данные требуются, а вы не указали параметр -TaskCredential, сценарий попросит ввести учетные данные.

Оба параметра, -ConnectionCredential и -TaskCredential, запрашивают в качестве аргумента объект PSCredential. Объект PSCredential надежно хранит имя пользователя и пароль для применения в операциях, требующих повышенной безопасности. Однако существует важная оговорка, о которой нужно помнить: сценарий Rename-ScheduledTask.ps1 преобразует пароли безопасности в объектах PSCredential в простой текст, так как модель объектов, поддерживающая выполнение сценариев, не работает с объектами PSCredential.

Вы можете легко создавать объекты PSCredential с помощью команды Get-Credential. Запустите команду

Get-Help Get-Credential

в строке оболочки PowerShell для получения дополнительной информации об объектах PSCredential.

Листинг 1. Сценарий Rename-ScheduledTask.ps1

# Rename-ScheduledTask.ps1
# Written by Bill Stewart (bstewart@iname.com)

#requires -version 2

<#
.SYNOPSIS
Renames a scheduled task on a computer by copying an existing task to a new task, then deleting the original task.

.DESCRIPTION
Renames a scheduled task on a computer by copying an existing task to a new task, then deleting the original task. Requires schedule service version 1.2 or later (i.e., at least Windows Vista or Server 2008). If you rename a scheduled task that has saved credentials, you must recreate the task's credentials (if you omit the -TaskCredential parameter, you will be prompted for credentials).

.PARAMETER TaskName
The scheduled task you want to rename. If you don't specify a folder name, the root folder ("\") is the default. If the task has saved credentials, you will be prompted for the task's credentials if you don't specify -TaskCredential.

.PARAMETER NewName
The new name for the task. You can specify a new folder name for the task. If you don't specify a different folder name, the default is to save the new task in the same folder as the original task. If the task has saved credentials, you will be prompted for the task's credentials if you don't specify -TaskCredential. If the folder name does not exist, it will be created.

.PARAMETER ComputerName
The computer on which the task exists. The current computer is the default.

.PARAMETER ConnectionCredential
The connection to the task scheduler service will be made using these credentials. If you don't specify this parameter, the currently logged on user's credentials are assumed.

.PARAMETER TaskCredential
If the scheduled task you are renaming has saved credentials, use these credentials when creating the new task. If the scheduled task has saved credentials and you don't specify this parameter, you will be prompted for new credentials.

.EXAMPLE
PS C:\> Rename-ScheduledTask "Scheduled Task 0" "Scheduled Task 1"
This command renames \Scheduled Task 0 to \Scheduled Task 1.

.EXAMPLE
PS C:\> Rename-ScheduledTask \TaskFolder1\Task0 Task1
This command renames \TaskFolder1\Task0 to \TaskFolder1\Task1.

Листинг 2. Функция get-plaintextpwd

function get-plaintextpwd($credential) {
   $сredential.GetNetworkCredential().Password
}

Листинг 3. Функция Get-taskname

function get-taskname($taskFolder) {
   $tasks = $taskFolder.GetTasks(0)
   $tasks | foreach-object { $_Path }
   $taskFolders = $taskFolder.GetFolders(0)
   $taskFolders | foreach-object
           { get-taskname $_ }
}

Билл Стюарт (bill.stewart@frenchmortuary.com) — системный и сетевой администратор компании French Mortuary, Нью-Мехико