PowerShell script makes a Task Scheduler limitation less annoying
What is in this article?:
The -ConnectionCredential parameter specifies a PSCredential object for connecting to the Task Scheduler service on the computer (which is the local computer if you omit the -ComputerName parameter). Note that Rename-ScheduledTask.ps1 renames a task by copying the original task to a new task, then deleting the original task. This means that if the original task has saved credentials, they can't be copied because credentials are stored securely. So, before you use the -ConnectionCredential parameter, you should check the task's properties to see whether the task has saved credentials. As Figure 2 shows, when the Run whether user is logged on or not option is selected and the Do not store password option isn't selected, the credentials are saved. Thus, the credentials must be re-created when the new task is created.
Figure 2: Task properties
If the original task has saved credentials, Rename-ScheduledTask.ps1 will prompt you for credentials when creating the copy. If you don't want the script to prompt you for credentials, you can include the -TaskCredential parameter, which requires a PSCredential object as its argument. (See the sidebar "Clarifying Credential Confusion" for more information about the -ConnectionCredential and -TaskCredential parameters.)
Aside from the inability to copy credentials, there is one other notable side-effect of copying a task: The new copy of the task won't have the original task's history of events, which appear on the History tab of the properties page. If the task's event history is important, save the task's history to a file before renaming it.
The script's online help provides a comprehensive list of sample commands. To view the sample commands, run the following code at a PowerShell prompt:
Get-Help Rename ScheduledTask -full | more
Inside the Script
Rename-ScheduledTask.ps1 uses the Schedule.Service programmatic identifier (ProgID) to create the TaskService object, which provides access to the Task Scheduler service for managing registered tasks. The TaskService object doesn't exist on Windows versions prior to Vista and Server 2008. See the "Task Scheduler Scripting Objects" web page for more information about the TaskService object and its associated objects.
Next, the script uses the TaskService object's Connect method to try to connect to the Task Scheduler service. If the -ConnectionCredential parameter exists on the command line, the script uses the get-plaintextpwd function, shown in Listing 1, to return the PSCredential object's Password property as a plain-text string. The script does this because the TaskService object's Connect method doesn't support PSCredential objects.
After connecting to the Task Scheduler service, the script checks the HighestVersion property of the TaskService object. This property is a 32-bit unsigned integer that contains the internal version number of the Task Scheduler service. The most significant 16 bits represent the major version number, and the least significant 16 bits represent the minor version. Internally, the Task Scheduler version in Windows 7, Vista, and Server 2008 is 1.2 (65538), so the script checks that the HighestVersion property is at least this version before continuing. If the service's version is too old, the script throws an error and exits.
If the Task Scheduler service version is recent enough, the script uses the TaskService object's GetFolder method to get the root tasks folder. The script then uses the get-taskname function, shown in Listing 2, to retrieve a list of all task names from all task folders. It uses the list of task names to check the validity of the -TaskName and -NewName parameters.
Next, Rename-ScheduledTask.ps1 retrieves the TaskDefinition object for the task named with the
-TaskName parameter. The TaskDefinition object defines all the components of the task. If the task has stored credentials, the script checks whether the -TaskCredential parameter was specified. If it wasn't specified, the script uses the Get-Credential cmdlet to prompt for credentials. (Canceling this prompt throws an error and ends the script.) If -TaskCredential was specified, the script uses the get-plaintextpwd function to convert the PSCredential object's Password property to plain text.
Finally, the script uses the RegisterTaskDefinition method to create a copy of the task. Note that if the task requires credentials but the supplied credentials aren't valid, the task won't be created and the script will throw an error. If the script creates the new task successfully, it uses the DeleteTask method of the original task's TaskFolder object to delete the original task.
Make the Rename Restriction Less Annoying
The overhauled Task Scheduler service includes many improvements over earlier versions, but the inability to rename a scheduled task is an annoying limitation. However, with the Rename-ScheduledTask.ps1 script in hand, it's a nuisance you're no longer forced to live with.