Skip to content

TaskSecurity

David Hall edited this page Jun 18, 2019 · 4 revisions

Below are some discussions and sample code related to the following tasks:

If you really want to understand the full security picture, or the information below is not helping resolve your issue, here are the links to the Microsoft documentation:

Connecting to a remote server or local server with different credentials

Connecting to both a local and a remote server to manage tasks is done through the TaskService constructor.

public TaskService(
   // The name of the computer that you want to connect to. If the this parameter is
   // null or empty, then this will connect to the local computer.
   string targetServer,
   // The user name that is used during the connection to the computer. If the user
   // is not specified, then the current token is used.
   string userName = null,
   // The domain of the user specified in the userName parameter.
   string accountDomain = null,
   // The password that is used to connect to the computer. If the user name and
   // password are not specified, then the current token is used.
   string password = null,
   // If set to true force Task Scheduler 1.0 compatibility and disallow 2.0
   // functionality.
   bool forceV1 = false
)

Important Note

If you just need an instance to the local computer under the current user's credentials, then you do NOT need to create a TaskService instance. Use instead the static property TaskService.Instance whose value you should NEVER dispose.

In calling the constructor, there are some settings to note:

  • Either do not use the last boolean parameter (as in the example below) or set the value to 'false' to make sure that the newest version of the library is used.
  • Do not put backslashes in front of the server name.
  • If calling this method from within code, make sure that UAC or IIS settings aren't preventing your full rights from being available.
// Connect to the computer "REMOTE" using credentials
TaskService ts = new TaskService("REMOTE", "myusername", "MYDOMAIN", "mypassword");

There are some important security considerations too:

  • By default, to schedule a task, you must be a member of the Administrators, Backup Operators, or Server Operators group on the local computer.
  • By default, when creating a scheduled task, you cannot enter a user who belongs to a group that has more rights than the group you belong to.
  • By default, a user who creates a task can read, update, delete, and run the task.
  • Members of the Administrators group or the SYSTEM account can read, update, delete, and run any tasks. Members of the Users group, the LocalService account, and the NetworkService account can only read, update, delete, and run the tasks that they have created.
  • If you are connecting to a remote computer running Windows Vista or Windows Server 2008 from a computer running Windows Vista or Windows Server 2008, you need to enable the Remote Scheduled Tasks Management firewall exception on the remote computer. To allow this exception click Start , Control Panel , Security , Allow a program through Windows Firewall , and then select the Remote Scheduled Tasks Management check box. Then click the Ok button in the Windows Firewall Settings dialog box.
  • If you are connecting to a remote computer running Windows XP or Windows Server 2003 from a computer running Windows Vista or Windows Server 2008, you need to allow the File and Printer Sharing firewall exception on the remote computer. To allow this exception click Start , Control Panel , double-click Windows Firewall , select the Exceptions tab, and then select the File and Printer Sharing firewall exception. Then click the Ok button in the Windows Firewall dialog box.

Creating tasks that run as a system account

If you have the permissions (see above) to create a task for the desired system account, you can do so by registering it with that well-known account name ("SYSTEM" in the example below) and using the TaskLogonType.ServiceAccount value for the logonType parameter. You must set the password parameter to null.

This is a common model for running tasks that interact only with the system non-interactively and is generally required whenever using Triggers that run based on system events (boot, events, system state changes).

ts.RootFolder.RegisterTaskDefinition("TaskName", taskDefinition,
   TaskCreation.CreateOrUpdate, "SYSTEM", null,
   TaskLogonType.ServiceAccount);

Creating tasks that run as a different user

The only way to run a task as a user other than the one specified when instantiating the TaskService (or the current user if calling the default TaskService constructor), is to specify the user credentials, password and using the TaskLogonType.Password value for the logonType parameter. When registered

ts.RootFolder.RegisterTaskDefinition("TaskName", taskDefinition,
   TaskCreation.CreateOrUpdate, "userDomain\\userName", "userPassword",
   TaskLogonType.Password);

Running tasks with Administrator rights that ignore UAC warnings

Applications running from the Desktop in Windows Vista and later run under an access controlled environment unless specifically run "as Administrator" even if the user has Administrator rights. If you are getting Access Denied errors when registering tasks, this is often the cause.

To run tasks in a heightened security mode, you must set the Task.Definition.Principal.RunLevel to Highest. If a task is registered using the Builtin\Administrator account or the Local System or Local Service accounts, then the RunLevel property will be ignored. The property value will also be ignored if User Account Control (UAC) is turned off.

If a task is registered using the Administrators group for the security context of the task, then you must also set the RunLevel property to Highest if you want to run the task.

TaskDefinition td = ts.NewTask();
td.Principal.RunLevel = TaskRunLevel.Highest;
// Set trigger and action and other properties...
ts.RootFolder.RegisterTaskDefinition("Test", td);

Prompting for a password

At times when interacting with a user or allowing the user to edit a task, the task may require capture of a password for assignment to the TaskDefinition.Principal class. This is done automatically when using TaskEditDialog and setting the RegisterTaskOnAccept property to true. However, if you need to do this programatically, you can use the CredentialsDialog class as follows:

// taskDefinition is a TaskDefinition instance that has been initialized
var userName = taskDefinition.Principal.ToString();
string pwd = null;
if (taskDefinition.Principal.RequiresPassword())
{
   var dlg = new CredentialsDialog("Task name", "Please provide a password", userName) { ValidatePassword = true };
   if (dlg.ShowDialog(owner) != DialogResult.OK || dlg.Password == null)
   {
      throw new System.Security.Authentication.AuthenticationException("Password must be provided.");
   }
   pwd = dlg.Password;
}
TaskService.RootFolder.RegisterTaskDefinition(taskName, taskDefinition, TaskCreation.CreateOrUpdate, userName, pwd, taskDefinition.Principal.LogonType);