Updating a Scheduled Task's Credentials

Use this PowerShell script to overcome Schtasks limitations

Downloads
142570.zip

The Task Scheduler service in Windows Vista and Windows Server 2008 and later has been updated with greater functionality. However, the OSs' Schtasks tool, which ostensibly lets you manage scheduled tasks from the command line, hasn't kept up. You can no longer use the Schtasks command to update a scheduled task's stored credentials, as you could in earlier versions. This issue becomes a significant problem if the password changes for an account that's used to run numerous scheduled tasks. In this article, I'll present a Windows PowerShell script, Set-ScheduledTaskCredential.ps1, that lets you update one or more scheduled tasks' stored credentials via a single command.

Setting a Scheduled Task's Credentials

The Task Scheduler service in current Windows OSs has some useful new features that are unavailable in OS versions prior to Vista and Server 2008. For example, you can send an email message or display a message box in addition to running a program. You also have more options for when a task should execute: You can specify a task to execute when a specific event appears in the event log, for example. Each task also has a separate History tab in the Task Scheduler console. These are great improvements to a core Windows system service.

However, the Task Scheduler upgrade hasn't been without a few issues. One of the first things I noticed about the new service is that you can't use the Task Scheduler console to rename a scheduled task. I rectified this shortcoming by writing a PowerShell script that can rename a scheduled task on the newer OSs (see " PowerShell Script: Rename Scheduled Tasks in Windows 7, Windows Server 2008, and Windows Vista "). The next problem I noticed was that there was no good way to get a list of scheduled tasks on one or more computers; as I wrote in " How-To: Use PowerShell to Report on Scheduled Tasks ," using Schtasks with the /query parameter is inadequate for the job.

Having spent more time using the new Task Scheduler service, I noticed another problem with the Schtasks command: You can no longer use Schtasks with the /change parameter to set a scheduled task's stored credentials (i.e., the username and password that the task uses when running) from the command line. When you attempt to do so, the command simply outputs the message ERROR: The parameter is incorrect. Figure 1 shows my attempt to set the stored credentials for a scheduled task on a Windows 7 machine. This command syntax works fine on earlier versions (Figure 2 shows how I successfully used the command on a Windows XP system).

Figure 1: Using Schtasks /change in Windows 7
Figure 1: Using Schtasks /change in Windows 7 

 

 Figure 2: Using Schtasks /change in Windows XP
Figure 2: Using Schtasks /change in Windows XP

It turns out that if you use Schtasks with the /create parameter to create the scheduled task, then you can use Schtasks with the /change parameter to update a task's stored credentials. However, you can't use Schtasks /change to set the stored credentials for tasks that were created using the Task Scheduler console, which is likely how the vast majority of administrators create scheduled tasks. This limitation has the potential to be time consuming for many organizations. Setting stored task credentials one at a time in the Task Scheduler console becomes incredibly inefficient as the number of scheduled tasks increases.

Using Set-ScheduledTaskCredential.ps1

To overcome this limitation, I wrote a PowerShell script, Set-ScheduledTaskCredential.ps1. The script's command-line syntax is as follows:

Set-ScheduledTaskCredential -TaskName  [-TaskCredential ] [-ComputerName ] [-ConnectionCredential ] 

The -TaskName parameter specifies the task that has stored credentials. You can specify more than one task name as an array, but you can't use wildcard characters. You can omit the -TaskName parameter name if the parameter's argument (i.e., the task name or list of task names) is first on the command line. Because the Task Scheduler service (on Vista and later) supports task folders, you must specify the full path to the task name (e.g., \task folder \task name). If you omit a folder name, the script assumes that the task lives in the root folder (i.e., \). This parameter also supports pipeline input.

The -TaskCredential parameter is a PSCredential object that specifies the stored credentials (i.e., the username and password that the task or tasks will use when running) for the task or tasks. The -TaskCredential parameter is optional; if you don't specify it, then the script prompts for credentials to use. The -TaskCredential parameter is analogous to the Schtasks /change /RU and /RP parameters.

If you want to set scheduled task credentials on a remote computer, use the -ComputerName parameter to specify the computer's name.

 

If the current user account (i.e., the account that you're using to run the script) doesn't have permission to change scheduled tasks, you can use the -ConnectionCredential parameter. Use this parameter to specify a PSCredential object that contains the credentials that are used to connect to the Task Scheduler service. You can use the syntax

-ConnectionCredential (Get-Credential) 

to prompt for the PSCredential parameter. The -ConnectionCredential parameter is analogous to the Schtasks /change /U and /P parameters.

You need to be aware of three caveats about the Set-ScheduledTaskCredential.ps1 script:

  • The script won't work on earlier OS versions (i.e., it won't set scheduled task credentials on OS versions older than Vista or Server 2008). To prevent errors, the script checks the Task Scheduler service version. If the service version is too old, then the script outputs an error. This shouldn't be a big problem because you can still use Schtasks /change on older platforms.
  • The script outputs an error if a scheduled task doesn't have stored credentials. That is, if the task isn't configured with stored credentials, then the script can't set the credentials.
  • The script uses the Task Scheduler scripting objects (see the list on the Task Scheduler Script Objects page) to do its work. These objects don't support encrypted credentials internally, so the script must temporarily retrieve a PSCredential object's passwords as plaintext when using a password with the scripting objects. These passwords aren't sent in plaintext over the network, but they're temporarily decrypted in memory when the script is running. Thus, there's a remote possibility that if the computer running the script crashes, the computer's memory dump information might contain a plaintext copy of a password.

Sample Usage

The simplest way to use the script is to set stored credentials for a scheduled task on the current computer:

PS C:\> Set-ScheduledTaskCredential "My Task" 

This command prompts for the credentials to use for the task named My Task. Note that this example omits the -TaskName parameter name. The script prompts for the stored credentials to use.

As I mentioned, the -TaskName parameter supports pipeline input, so if you need to set stored credentials for multiple tasks on a computer, you can put the task names in a text file and pipe the output of the Get-Content cmdlet to Set-ScheduledTaskCredential.ps1:

PS C:\> Get-Content TaskNames.txt |
Set-ScheduledTaskCredential 

This command sets the stored credentials for all the tasks that are listed in the file TaskNames.txt. The script prompts for which credentials to use.

Even though the script's -ComputerName parameter supports only one computer name, you can still connect to multiple computers by using PowerShell's ForEach-Object cmdlet:

PS C:\> "server1","server2" |
>> ForEach-Object { Set-ScheduledTaskCredential `
>> -TaskName "My Task" -ComputerName $_ } 

This command sets the stored credentials for a task named My Task on server1 and server2. If you run this command, you'll notice that you'll be prompted twice for task credentials; this is because the ForEach-Object cmdlet runs the script twice (once for each computer name). To work around this annoyance, create a PSCredential object first, and then use it with the -TaskCredential parameter:

PS C:\> $cred = Get-Credential "MYDOMAIN\MyUserName"
PS C:\> "server1","server2" |
>> ForEach-Object { Set-ScheduledTaskCredential `
>> -TaskName "My Task" -TaskCredential $cred `
>> -ComputerName $_ } 

The first command creates a PSCredential object and stores it in the $cred variable, and the second command uses this set of credentials to set the credentials for the scheduled task named My Task on server1 and server2.

If you're using an account that doesn't have permission to change scheduled tasks on a computer, you can use the -ConnectionCredential parameter to specify credentials for the connection:

PS C:\> Set-ScheduledTaskCredential "My Task" `
>> -ComputerName "server1" `
>> -ConnectionCredential (Get-Credential) 

This command generates two credential prompts. The first prompt is for the credentials for the -ConnectionCredential parameter, and the second prompt is for the credentials for the scheduled task. Of course, you can avoid the prompts by creating PSCredential objects before running the script.

Tackle Task Credentials

The Task Scheduler service in Vista and Server 2008 and later provides some nice new features, but unfortunately the Schtasks /change command can no longer change stored task credentials. With the Set-ScheduledTaskCredential.ps1 script, you don't need to worry about this limitation.

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish