Task Scheduler TaskRunLevel

Oct 23, 2012 at 7:51 AM
Edited Oct 24, 2012 at 12:18 PM

I am trying to create a scheduled task using Win32.TaskScheduler. I need to create it at the logon event (the code below is called at logon). The user who is creating the task (always just a domain user) has to have the rights to create Scheduled Tasks. I have accomplished this as if I use the code below then the scheduled task is created (I have given rights on the Tasks folder to domain users).

As you can see from the code, I am creating the task under the rights assigned to the person currently logged in: (userId = string.Concat(Environment.UserDomainName, "\\", Environment.UserName);

The userid (currently logged on user) is what appears under the heading "when running the task use the following user account" when the task is created.

However, I need to run the task when the user is logged out. When the code below is run, the task is created with the box "run while user is logged out" ticked so I thought this would ensure the task runs while the user is logged out but it doesn't. I have discovered it will only run while the user is logged out if the task created by the code below also has the box "runs with highest priveleges" ticked . No problem I thought;I just added the line tdall.Principal.RunLevel = TaskRunLevel.Highest.

However when I do this it gives me an access denied error in the catch block. This makes no sense because I can manually change the run level on the PC while logged on as the user the code is running under (by ticking the box "runs with highest priveleges").

I tried it another way by removing the line that causes the error (tdall.Principal.RunLevel = TaskRunLevel.Highest.) and also changing the line

 ts.RootFolder.RegisterTaskDefinition(taskName, tdall, TaskCreation.CreateOrUpdate, userId, LogonType: TaskLogonType.S4U);

to

 ts.RootFolder.RegisterTaskDefinition(taskName, tdall, TaskCreation.CreateOrUpdate, "SYSTEM", LogonType: TaskLogonType.S4U);

This is because entering "SYSTEM" guarantees a task will run while logged out. 

SYSTEM will appear under the heading "when running the task use the following user account".

However, when I try to do this, I also get  access denied error in the catch block.

If I log on as Administrator I can do all of the above no problem. As I say, it makes no sense as the Domain user has the same rights as the Administrator on the Tasks folder.

Any help would be appreciated, thanks                                 

 

try
                        {
                            string userId = string.Concat(Environment.UserDomainName, "\\", Environment.UserName);


                           
                            TaskDefinition tdall = ts.NewTask();
                            userId = string.Concat(Environment.UserDomainName, "\\", Environment.UserName);
                           
                            tdall.RegistrationInfo.Description = schtask.ToString() + i.ToString();
                            tdall.Principal.LogonType = TaskLogonType.S4U;
                            tdall.Principal.RunLevel = TaskRunLevel.Highest;
                            tdall.Principal.UserId = userId;
                           
                            DailyTrigger dtall = new DailyTrigger();

                            // Add a trigger that will fire the task at this time every day
                            dtall = (DailyTrigger)tdall.Triggers.Add(new DailyTrigger { DaysInterval = 1 });
                            dtall.StartBoundary = schtime;


                            tdall.Actions.Add(new ExecAction("psshutdown.exe", "-d -accepteula", @"C:\EnergyWatchIT\App_Files\"));

                            i++;
                            string taskName = "EWITSchedSleepAll" + schtask.ToString() + i.ToString();

                            

                            ts.RootFolder.RegisterTaskDefinition(taskName, tdall, TaskCreation.CreateOrUpdate, userId, LogonType: TaskLogonType.S4U);



                            
                        }
                        catch (Exception j)
                        {
                            Logger.append("j is  " + j.Message + Environment.NewLine + j.StackTrace, Logger.ALL);
                            MessageBox.Show("j is " + j.ToString());
                        }

Oct 23, 2012 at 7:51 AM

I think it is maybe a problem with the permissions set to the domain user on the server and a way around it might be to create a unique user account on the domain for task scheduler to use and then  hardcode the user values into the code above (assign them to the variable userid).

I would rather not do this though.

Coordinator
Oct 23, 2012 at 2:18 PM

Which operating system are you running this on and will you provide the constructor in your code for TaskService? I think this may be a problem with the version of the underlying COM library.

Oct 23, 2012 at 3:11 PM
Edited Oct 23, 2012 at 3:12 PM

It's Windows 7.

The entire code is below:

                using (TaskService ts = new TaskService())
                {
                    // Create a new task definition and assign properties



                    if (schday == "ALL")
                    {

try
                        {
                            string userId = string.Concat(Environment.UserDomainName, "\\", Environment.UserName);


                           
                            TaskDefinition tdall = ts.NewTask();
                            userId = string.Concat(Environment.UserDomainName, "\\", Environment.UserName);
                           
                            tdall.RegistrationInfo.Description = schtask.ToString() + i.ToString();
                            tdall.Principal.LogonType = TaskLogonType.S4U;
                            tdall.Principal.RunLevel = TaskRunLevel.Highest;
                            tdall.Principal.UserId = userId;
                           
                            DailyTrigger dtall = new DailyTrigger();

                            // Add a trigger that will fire the task at this time every day
                            dtall = (DailyTrigger)tdall.Triggers.Add(new DailyTrigger { DaysInterval = 1 });
                            dtall.StartBoundary = schtime;


                            tdall.Actions.Add(new ExecAction("psshutdown.exe", "-d -accepteula", @"C:\EnergyWatchIT\App_Files\"));

                            i++;
                            string taskName = "EWITSchedSleepAll" + schtask.ToString() + i.ToString();

                            

                            ts.RootFolder.RegisterTaskDefinition(taskName, tdall, TaskCreation.CreateOrUpdate, userId, LogonType: TaskLogonType.S4U);



                            
                        }
                        catch (Exception j)
                        {
                            Logger.append("j is  " + j.Message + Environment.NewLine + j.StackTrace, Logger.ALL);
                            MessageBox.Show("j is " + j.ToString());
                        }

try
                        {
                            string userId = string.Concat(Environment.UserDomainName, "\\", Environment.UserName);


                           
                            TaskDefinition tdall = ts.NewTask();
                            userId = string.Concat(Environment.UserDomainName, "\\", Environment.UserName);
                           
                            tdall.RegistrationInfo.Description = schtask.ToString() + i.ToString();
                            tdall.Principal.LogonType = TaskLogonType.S4U;
                            tdall.Principal.RunLevel = TaskRunLevel.Highest;
                            tdall.Principal.UserId = userId;
                           
                            DailyTrigger dtall = new DailyTrigger();

                            // Add a trigger that will fire the task at this time every day
                            dtall = (DailyTrigger)tdall.Triggers.Add(new DailyTrigger { DaysInterval = 1 });
                            dtall.StartBoundary = schtime;


                            tdall.Actions.Add(new ExecAction("psshutdown.exe", "-d -accepteula", @"C:\EnergyWatchIT\App_Files\"));

                            i++;
                            string taskName = "EWITSchedSleepAll" + schtask.ToString() + i.ToString();

                            

                            ts.RootFolder.RegisterTaskDefinition(taskName, tdall, TaskCreation.CreateOrUpdate, userId, LogonType: TaskLogonType.S4U);



                            
                        }
                        catch (Exception j)
                        {
                            Logger.append("j is  " + j.Message + Environment.NewLine + j.StackTrace, Logger.ALL);
                            MessageBox.Show("j is " + j.ToString());
                        }




  static void sleepmethod(String schtask, String schday, DateTime schtime, int i)
        {

            try
            {


                using (TaskService ts = new TaskService())
                {
                    // Create a new task definition and assign properties



                    if (schday == "ALL")
                    {
                        try
                        {
                            string userId = string.Concat(Environment.UserDomainName, "\\", Environment.UserName);


                            MessageBox.Show("In try");
                            TaskDefinition tdall = ts.NewTask();
                            userId = string.Concat(Environment.UserDomainName, "\\", Environment.UserName);
                            MessageBox.Show(userId);
                            tdall.RegistrationInfo.Description = schtask.ToString() + i.ToString();
                            tdall.Principal.LogonType = TaskLogonType.S4U;
                            tdall.Principal.GroupId = "Users";
                            //tdall.Principal.RunLevel = TaskRunLevel.Highest;
                            tdall.Principal.UserId = userId;
                           
                            DailyTrigger dtall = new DailyTrigger();

                            // Add a trigger that will fire the task at this time every day
                            dtall = (DailyTrigger)tdall.Triggers.Add(new DailyTrigger { DaysInterval = 1 });
                            dtall.StartBoundary = schtime;


                            tdall.Actions.Add(new ExecAction("psshutdown.exe", "-d -accepteula", @"C:\EnergyWatchIT\App_Files\"));

                            i++;
                            string taskName = "EWITSchedSleepAll" + schtask.ToString() + i.ToString();



                            ts.RootFolder.RegisterTaskDefinition(taskName, tdall, TaskCreation.CreateOrUpdate, "NETWORK SERVICE", LogonType: TaskLogonType.Group);



                            
                        }
                        catch (Exception j)
                        {
                            Logger.append("j is  " + j.Message + Environment.NewLine + j.StackTrace, Logger.ALL);
                            MessageBox.Show("j is " + j.ToString());
                        }
                    }

}
}