Beispiel #1
0
        /// <summary>
        /// Registers (creates) a new task in the folder using XML to define the task.
        /// </summary>
        /// <param name="path">The task name. If this value is NULL, the task will be registered in the root task folder and the task name will be a GUID value that is created by the Task Scheduler service. A task name cannot begin or end with a space character. The '.' character cannot be used to specify the current task folder and the '..' characters cannot be used to specify the parent task folder in the path.</param>
        /// <param name="xmlText">An XML-formatted definition of the task.</param>
        /// <param name="createType">A union of <see cref="TaskCreation"/> flags.</param>
        /// <param name="userId">The user credentials used to register the task.</param>
        /// <param name="password">The password for the userId used to register the task.</param>
        /// <param name="logonType">A <see cref="TaskLogonType"/> value that defines what logon technique is used to run the registered task.</param>
        /// <param name="sddl">The security descriptor associated with the registered task. You can specify the access control list (ACL) in the security descriptor for a task in order to allow or deny certain users and groups access to a task.</param>
        /// <returns>A <see cref="Task"/> instance that represents the new task.</returns>
        /// <example><code lang="cs"><![CDATA[
        /// // Define a basic task in XML
        /// var xml = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>" +
        ///    "<Task version=\"1.2\" xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\">" +
        ///    "  <Principals>" +
        ///    "    <Principal id=\"Author\">" +
        ///    "      <UserId>S-1-5-18</UserId>" +
        ///    "    </Principal>" +
        ///    "  </Principals>" +
        ///    "  <Triggers>" +
        ///    "    <CalendarTrigger>" +
        ///    "      <StartBoundary>2017-09-04T14:04:03</StartBoundary>" +
        ///    "      <ScheduleByDay />" +
        ///    "    </CalendarTrigger>" +
        ///    "  </Triggers>" +
        ///    "  <Actions Context=\"Author\">" +
        ///    "    <Exec>" +
        ///    "      <Command>cmd</Command>" +
        ///    "    </Exec>" +
        ///    "  </Actions>" +
        ///    "</Task>";
        /// // Register the task in the root folder of the local machine using the SYSTEM account defined in XML
        /// TaskService.Instance.RootFolder.RegisterTaskDefinition("Test", xml);
        /// ]]></code></example>
        public Task RegisterTask(string path, [NotNull] string xmlText, TaskCreation createType = TaskCreation.CreateOrUpdate, string userId = null, string password = null, TaskLogonType logonType = TaskLogonType.S4U, string sddl = null)
        {
            if (v2Folder != null)
            {
                return(Task.CreateTask(TaskService, v2Folder.RegisterTask(path, xmlText, (int)createType, userId, password, logonType, sddl)));
            }

            TaskDefinition td = TaskService.NewTask();

            XmlSerializationHelper.ReadObjectFromXmlText(xmlText, td);
            return(RegisterTaskDefinition(path, td, createType, userId ?? td.Principal.ToString(),
                                          password, logonType == TaskLogonType.S4U ? td.Principal.LogonType : logonType, sddl));
        }
        /// <summary>
        /// Registers (creates) a new task in the folder using XML to define the task.
        /// </summary>
        /// <param name="Path">The task name. If this value is NULL, the task will be registered in the root task folder and the task name will be a GUID value that is created by the Task Scheduler service. A task name cannot begin or end with a space character. The '.' character cannot be used to specify the current task folder and the '..' characters cannot be used to specify the parent task folder in the path.</param>
        /// <param name="XmlText">An XML-formatted definition of the task.</param>
        /// <param name="createType">A union of <see cref="TaskCreation"/> flags.</param>
        /// <param name="UserId">The user credentials used to register the task.</param>
        /// <param name="password">The password for the userId used to register the task.</param>
        /// <param name="LogonType">A <see cref="TaskLogonType"/> value that defines what logon technique is used to run the registered task.</param>
        /// <param name="sddl">The security descriptor associated with the registered task. You can specify the access control list (ACL) in the security descriptor for a task in order to allow or deny certain users and groups access to a task.</param>
        /// <returns>A <see cref="Task"/> instance that represents the new task.</returns>
        public Task RegisterTask(string Path, string XmlText, TaskCreation createType = TaskCreation.CreateOrUpdate, string UserId = null, string password = null, TaskLogonType LogonType = TaskLogonType.S4U, string sddl = null)
        {
            if (v2Folder != null)
            {
                return(Task.CreateTask(this.TaskService, v2Folder.RegisterTask(Path, XmlText, (int)createType, UserId, password, LogonType, sddl)));
            }

            try
            {
                TaskDefinition td = this.TaskService.NewTask();
                XmlSerializationHelper.ReadObjectFromXmlText(XmlText, td);
                return(this.RegisterTaskDefinition(Path, td, createType, UserId == null ? td.Principal.ToString() : UserId,
                                                   password, LogonType == TaskLogonType.S4U ? td.Principal.LogonType : LogonType, sddl));
            }
            catch
            {
                throw;                 // new NotV1SupportedException();
            }
        }
        /// <summary>
        /// Gets the task with the specified path.
        /// </summary>
        /// <param name="taskPath">The task path.</param>
        /// <returns>The task.</returns>
        public Task GetTask(string taskPath)
        {
            Task t = null;

            if (v2TaskService != null)
            {
                V2Interop.IRegisteredTask iTask = GetTask(this.v2TaskService, taskPath);
                if (iTask != null)
                {
                    t = Task.CreateTask(this, iTask);
                }
            }
            else
            {
                V1Interop.ITask iTask = GetTask(this.v1TaskScheduler, taskPath);
                if (iTask != null)
                {
                    t = new Task(this, iTask);
                }
            }
            return(t);
        }
Beispiel #4
0
        /// <summary>
        /// Gets the task with the specified path.
        /// </summary>
        /// <param name="taskPath">The task path.</param>
        /// <returns>The <see cref="Task"/> instance matching the <paramref name="taskPath"/>, if found. If not found, this method returns <c>null</c>.</returns>
        public Task GetTask([NotNull] string taskPath)
        {
            Task t = null;

            if (v2TaskService != null)
            {
                V2Interop.IRegisteredTask iTask = GetTask(v2TaskService, taskPath);
                if (iTask != null)
                {
                    t = Task.CreateTask(this, iTask);
                }
            }
            else
            {
                taskPath = System.IO.Path.GetFileNameWithoutExtension(taskPath);
                V1Interop.ITask iTask = GetTask(v1TaskScheduler, taskPath);
                if (iTask != null)
                {
                    t = new Task(this, iTask);
                }
            }
            return(t);
        }
Beispiel #5
0
        /// <summary>
        /// Registers (creates) a task in a specified location using a <see cref="TaskDefinition" /> instance to define a task.
        /// </summary>
        /// <param name="path">The task name. If this value is NULL, the task will be registered in the root task folder and the task name will be a GUID value that is created by the Task Scheduler service. A task name cannot begin or end with a space character. The '.' character cannot be used to specify the current task folder and the '..' characters cannot be used to specify the parent task folder in the path.</param>
        /// <param name="definition">The <see cref="TaskDefinition" /> of the registered task.</param>
        /// <param name="createType">A union of <see cref="TaskCreation" /> flags.</param>
        /// <param name="userId">The user credentials used to register the task.</param>
        /// <param name="password">The password for the userId used to register the task.</param>
        /// <param name="logonType">A <see cref="TaskLogonType" /> value that defines what logon technique is used to run the registered task.</param>
        /// <param name="sddl">The security descriptor associated with the registered task. You can specify the access control list (ACL) in the security descriptor for a task in order to allow or deny certain users and groups access to a task.</param>
        /// <returns>
        /// A <see cref="Task" /> instance that represents the new task. This will return <c>null</c> if <paramref name="createType"/> is set to <c>ValidateOnly</c> and there are no validation errors.
        /// </returns>
        /// <exception cref="System.ArgumentOutOfRangeException">
        /// Task names may not include any characters which are invalid for file names.
        /// or
        /// Task names ending with a period followed by three or fewer characters cannot be retrieved due to a bug in the native library.
        /// </exception>
        /// <exception cref="NotV1SupportedException">This LogonType is not supported on Task Scheduler 1.0.
        /// or
        /// Security settings are not available on Task Scheduler 1.0.
        /// or
        /// Registration triggers are not available on Task Scheduler 1.0.
        /// or
        /// XML validation not available on Task Scheduler 1.0.</exception>
        /// <remarks>This method is effectively the "Save" method for tasks. It takes a modified <c>TaskDefinition</c> instance and registers it in the folder defined by this <c>TaskFolder</c> instance. Optionally, you can use this method to override the user, password and logon type defined in the definition and supply security against the task.</remarks>
        /// <example>
        /// <para>This first example registers a simple task with a single trigger and action using the default security.</para>
        /// <code lang="cs"><![CDATA[
        /// // Create a new task definition for the local machine and assign properties
        /// TaskDefinition td = TaskService.Instance.NewTask();
        /// td.RegistrationInfo.Description = "Does something";
        ///
        /// // Add a trigger that, starting tomorrow, will fire every other week on Monday and Saturday
        /// td.Triggers.Add(new WeeklyTrigger(DaysOfTheWeek.Monday | DaysOfTheWeek.Saturday, 2));
        ///
        /// // Create an action that will launch Notepad whenever the trigger fires
        /// td.Actions.Add("notepad.exe", "c:\\test.log");
        ///
        /// // Register the task in the root folder of the local machine using the current user and the S4U logon type
        /// TaskService.Instance.RootFolder.RegisterTaskDefinition("Test", td);
        /// ]]></code>
        /// <para>This example registers that same task using the SYSTEM account.</para>
        /// <code lang="cs"><![CDATA[
        /// TaskService.Instance.RootFolder.RegisterTaskDefinition("TaskName", taskDefinition, TaskCreation.CreateOrUpdate, "SYSTEM", null, TaskLogonType.ServiceAccount);
        /// ]]></code>
        /// <para>This example registers that same task using a specific username and password along with a security definition.</para>
        /// <code lang="cs"><![CDATA[
        /// TaskService.Instance.RootFolder.RegisterTaskDefinition("TaskName", taskDefinition, TaskCreation.CreateOrUpdate, "userDomain\\userName", "userPassword", TaskLogonType.Password, @"O:BAG:DUD:(A;ID;0x1f019f;;;BA)(A;ID;0x1f019f;;;SY)(A;ID;FA;;;BA)(A;;FR;;;BU)");
        /// ]]></code></example>
        public Task RegisterTaskDefinition([NotNull] string path, [NotNull] TaskDefinition definition, TaskCreation createType, string userId, string password = null, TaskLogonType logonType = TaskLogonType.S4U, string sddl = null)
        {
            if (definition.Actions.Count < 1 || definition.Actions.Count > 32)
            {
                throw new ArgumentOutOfRangeException(nameof(definition.Actions), @"A task must be registered with at least one action and no more than 32 actions.");
            }

            userId = userId ?? definition.Principal.Account;
            if (userId == string.Empty)
            {
                userId = null;
            }
            User user = new User(userId);

            if (v2Folder != null)
            {
                definition.Actions.ConvertUnsupportedActions();
                if (logonType == TaskLogonType.ServiceAccount)
                {
                    if (string.IsNullOrEmpty(userId) || !user.IsServiceAccount)
                    {
                        throw new ArgumentException(@"A valid system account name must be supplied for TaskLogonType.ServiceAccount. Valid entries are ""NT AUTHORITY\SYSTEM"", ""SYSTEM"", ""NT AUTHORITY\LOCALSERVICE"", or ""NT AUTHORITY\NETWORKSERVICE"".", nameof(userId));
                    }
                    if (password != null)
                    {
                        throw new ArgumentException(@"A password cannot be supplied when specifying TaskLogonType.ServiceAccount.", nameof(password));
                    }
                }

                /*else if ((LogonType == TaskLogonType.Password || LogonType == TaskLogonType.InteractiveTokenOrPassword ||
                 *      (LogonType == TaskLogonType.S4U && UserId != null && !user.IsCurrent)) && password == null)
                 * {
                 *      throw new ArgumentException("A password must be supplied when specifying TaskLogonType.Password or TaskLogonType.InteractiveTokenOrPassword or TaskLogonType.S4U from another account.", nameof(password));
                 * }*/
                else if (logonType == TaskLogonType.Group && password != null)
                {
                    throw new ArgumentException(@"A password cannot be supplied when specifying TaskLogonType.Group.", nameof(password));
                }
                // The following line compensates for an omission in the native library that never actually sets the registration date (thanks ixm7).
                if (definition.RegistrationInfo.Date == DateTime.MinValue)
                {
                    definition.RegistrationInfo.Date = DateTime.Now;
                }
                var iRegTask = v2Folder.RegisterTaskDefinition(path, definition.v2Def, (int)createType, userId ?? user.Name, password, logonType, sddl);
                if (createType == TaskCreation.ValidateOnly && iRegTask == null)
                {
                    return(null);
                }
                return(Task.CreateTask(TaskService, iRegTask));
            }

            // Check for V1 invalid task names
            string invChars = Regex.Escape(new string(System.IO.Path.GetInvalidFileNameChars()));

            if (Regex.IsMatch(path, @"[" + invChars + @"]"))
            {
                throw new ArgumentOutOfRangeException(nameof(path), @"Task names may not include any characters which are invalid for file names.");
            }
            if (Regex.IsMatch(path, @"\.[^" + invChars + @"]{0,3}\z"))
            {
                throw new ArgumentOutOfRangeException(nameof(path), @"Task names ending with a period followed by three or fewer characters cannot be retrieved due to a bug in the native library.");
            }

            // Adds ability to set a password for a V1 task. Provided by Arcao.
            TaskFlags flags = definition.v1Task.GetFlags();

            if (logonType == TaskLogonType.InteractiveTokenOrPassword && string.IsNullOrEmpty(password))
            {
                logonType = TaskLogonType.InteractiveToken;
            }
            switch (logonType)
            {
            case TaskLogonType.Group:
            case TaskLogonType.S4U:
            case TaskLogonType.None:
                throw new NotV1SupportedException("This LogonType is not supported on Task Scheduler 1.0.");

            case TaskLogonType.InteractiveToken:
                flags |= (TaskFlags.RunOnlyIfLoggedOn | TaskFlags.Interactive);
                definition.v1Task.SetAccountInformation(user.Name, IntPtr.Zero);
                break;

            case TaskLogonType.ServiceAccount:
                flags &= ~(TaskFlags.Interactive | TaskFlags.RunOnlyIfLoggedOn);
                definition.v1Task.SetAccountInformation((String.IsNullOrEmpty(userId) || user.IsSystem) ? String.Empty : user.Name, IntPtr.Zero);
                break;

            case TaskLogonType.InteractiveTokenOrPassword:
                flags |= TaskFlags.Interactive;
                using (CoTaskMemString cpwd = new CoTaskMemString(password))
                    definition.v1Task.SetAccountInformation(user.Name, cpwd.DangerousGetHandle());
                break;

            case TaskLogonType.Password:
                using (CoTaskMemString cpwd = new CoTaskMemString(password))
                    definition.v1Task.SetAccountInformation(user.Name, cpwd.DangerousGetHandle());
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(logonType), logonType, null);
            }
            definition.v1Task.SetFlags(flags);

            switch (createType)
            {
            case TaskCreation.Create:
            case TaskCreation.CreateOrUpdate:
            case TaskCreation.Disable:
            case TaskCreation.Update:
                if (createType == TaskCreation.Disable)
                {
                    definition.Settings.Enabled = false;
                }
                definition.V1Save(path);
                break;

            case TaskCreation.DontAddPrincipalAce:
                throw new NotV1SupportedException("Security settings are not available on Task Scheduler 1.0.");

            case TaskCreation.IgnoreRegistrationTriggers:
                throw new NotV1SupportedException("Registration triggers are not available on Task Scheduler 1.0.");

            case TaskCreation.ValidateOnly:
                throw new NotV1SupportedException("XML validation not available on Task Scheduler 1.0.");

            default:
                throw new ArgumentOutOfRangeException(nameof(createType), createType, null);
            }
            return(new Task(TaskService, definition.v1Task));
        }
        /// <summary>
        /// Registers (creates) a task in a specified location using a <see cref="TaskDefinition" /> instance to define a task.
        /// </summary>
        /// <param name="Path">The task name. If this value is NULL, the task will be registered in the root task folder and the task name will be a GUID value that is created by the Task Scheduler service. A task name cannot begin or end with a space character. The '.' character cannot be used to specify the current task folder and the '..' characters cannot be used to specify the parent task folder in the path.</param>
        /// <param name="definition">The <see cref="TaskDefinition" /> of the registered task.</param>
        /// <param name="createType">A union of <see cref="TaskCreation" /> flags.</param>
        /// <param name="UserId">The user credentials used to register the task.</param>
        /// <param name="password">The password for the userId used to register the task.</param>
        /// <param name="LogonType">A <see cref="TaskLogonType" /> value that defines what logon technique is used to run the registered task.</param>
        /// <param name="sddl">The security descriptor associated with the registered task. You can specify the access control list (ACL) in the security descriptor for a task in order to allow or deny certain users and groups access to a task.</param>
        /// <returns>
        /// A <see cref="Task" /> instance that represents the new task. This will return <c>null</c> if <paramref name="createType"/> is set to <c>ValidateOnly</c> and there are no validation errors.
        /// </returns>
        /// <exception cref="System.ArgumentOutOfRangeException">
        /// Path;Task names may not include any characters which are invalid for file names.
        /// or
        /// Path;Task names ending with a period followed by three or fewer characters cannot be retrieved due to a bug in the native library.
        /// </exception>
        /// <exception cref="NotV1SupportedException">This LogonType is not supported on Task Scheduler 1.0.
        /// or
        /// Security settings are not available on Task Scheduler 1.0.
        /// or
        /// Registration triggers are not available on Task Scheduler 1.0.
        /// or
        /// Xml validation not available on Task Scheduler 1.0.</exception>
        public Task RegisterTaskDefinition(string Path, TaskDefinition definition, TaskCreation createType, string UserId, string password = null, TaskLogonType LogonType = TaskLogonType.S4U, string sddl = null)
        {
            if (v2Folder != null)
            {
                definition.Actions.ConvertUnsupportedActions();
                var iRegTask = v2Folder.RegisterTaskDefinition(Path, definition.v2Def, (int)createType, UserId, password, LogonType, sddl);
                if (createType == TaskCreation.ValidateOnly && iRegTask == null)
                {
                    return(null);
                }
                return(Task.CreateTask(this.TaskService, iRegTask));
            }

            // Check for V1 invalid task names
            string invChars = System.Text.RegularExpressions.Regex.Escape(new string(System.IO.Path.GetInvalidFileNameChars()));

            if (System.Text.RegularExpressions.Regex.IsMatch(Path, @"[" + invChars + @"]"))
            {
                throw new ArgumentOutOfRangeException("Path", "Task names may not include any characters which are invalid for file names.");
            }
            if (System.Text.RegularExpressions.Regex.IsMatch(Path, @"\.[^" + invChars + @"]{0,3}\z"))
            {
                throw new ArgumentOutOfRangeException("Path", "Task names ending with a period followed by three or fewer characters cannot be retrieved due to a bug in the native library.");
            }

            // Adds ability to set a password for a V1 task. Provided by Arcao.
            V1Interop.TaskFlags flags = definition.v1Task.GetFlags();
            if (LogonType == TaskLogonType.InteractiveTokenOrPassword && string.IsNullOrEmpty(password))
            {
                LogonType = TaskLogonType.InteractiveToken;
            }
            if (string.IsNullOrEmpty(UserId))
            {
                UserId = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
            }
            switch (LogonType)
            {
            case TaskLogonType.Group:
            case TaskLogonType.S4U:
            case TaskLogonType.None:
                throw new NotV1SupportedException("This LogonType is not supported on Task Scheduler 1.0.");

            case TaskLogonType.InteractiveToken:
                flags |= (V1Interop.TaskFlags.RunOnlyIfLoggedOn | V1Interop.TaskFlags.Interactive);
                if (String.IsNullOrEmpty(UserId))
                {
                    UserId = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
                }
                definition.v1Task.SetAccountInformation(UserId, IntPtr.Zero);
                break;

            case TaskLogonType.ServiceAccount:
                flags &= ~(V1Interop.TaskFlags.Interactive | V1Interop.TaskFlags.RunOnlyIfLoggedOn);
                definition.v1Task.SetAccountInformation((String.IsNullOrEmpty(UserId) || UserId.Equals("SYSTEM", StringComparison.CurrentCultureIgnoreCase)) ? String.Empty : UserId, IntPtr.Zero);
                break;

            case TaskLogonType.InteractiveTokenOrPassword:
                flags |= V1Interop.TaskFlags.Interactive;
                using (V1Interop.CoTaskMemString cpwd = new V1Interop.CoTaskMemString(password))
                    definition.v1Task.SetAccountInformation(UserId, cpwd.DangerousGetHandle());
                break;

            case TaskLogonType.Password:
                using (V1Interop.CoTaskMemString cpwd = new V1Interop.CoTaskMemString(password))
                    definition.v1Task.SetAccountInformation(UserId, cpwd.DangerousGetHandle());
                break;

            default:
                break;
            }
            definition.v1Task.SetFlags(flags);

            switch (createType)
            {
            case TaskCreation.Create:
            case TaskCreation.CreateOrUpdate:
            case TaskCreation.Disable:
            case TaskCreation.Update:
                if (createType == TaskCreation.Disable)
                {
                    definition.Settings.Enabled = false;
                }
                definition.V1Save(Path);
                break;

            case TaskCreation.DontAddPrincipalAce:
                throw new NotV1SupportedException("Security settings are not available on Task Scheduler 1.0.");

            case TaskCreation.IgnoreRegistrationTriggers:
                throw new NotV1SupportedException("Registration triggers are not available on Task Scheduler 1.0.");

            case TaskCreation.ValidateOnly:
                throw new NotV1SupportedException("Xml validation not available on Task Scheduler 1.0.");

            default:
                break;
            }
            return(new Task(this.TaskService, definition.v1Task));
        }