This project has moved. For the latest updates, please go here.

COMException (18,8) LogonType trying to create task with user id and password

Aug 10, 2011 at 8:29 AM

Hi David,

I'm trying to create a task on Win 2008 R2 to run a batch script (that eventually calls powershell but that's irrelevant for now, I think).

The code is as below. The trouble is, I'm simply unable to get this to work in various combinations. I've tried to debug through it, and I see that it ends up calling the RegisterTaskDefinition method in the ITaskDefinition COM object as follows:

	if (v2Folder != null)
		return new Task(this.TaskService, v2Folder.RegisterTaskDefinition(Path, definition.v2Def, (int)createType, UserId, password, LogonType, sddl));

I have checked in the debugger that the user name, password and logon type are set correctly (LogonType is set to TaskLogonType.Password, and UserId and Password are valid values which I know work).

The error I get is COMException (18,8) LogonType. The HRESULT seems to be 0x80070534  (I searched around the internet and it seems to be related to the message: "No mapping between account names and security IDs was done").

The MSDN documentation for ITaskDefinition.RegisterTaskDefinition says that the 0x80070534 error occurs when called by the System Account with user paramter = NULL, password = NULL and LogonType = SERVICE_ACCOUNT. But I've checked that the caller is not the system account (more on this later), and the user is a non-null string containing a DOMAIN\Username.

Now, a little bit more about how and where this code is used:

It is part of a ASP.NET web application that runs under Windows Authentication with ASP.NET Impersonation turned on. I've logged the Exception to the Event log and I see that the identity is indeed being impersonated:

System.Runtime.InteropServices.COMException (0x80070534): (18,8):LogonType:

at Microsoft.Win32.TaskScheduler.V2Interop.ITaskFolder.RegisterTaskDefinition(String Path, ITaskDefinition pDefinition, Int32 flags, Object UserId, Object password, TaskLogonType LogonType, Object sddl)

at Microsoft.Win32.TaskScheduler.TaskFolder.RegisterTaskDefinition(String Path, TaskDefinition definition, TaskCreation createType, String UserId, String password, TaskLogonType LogonType, String sddl) in C:\Users\krishna.nadiminti\Downloads\taskscheduler-68509\TaskService\TaskFolder.cs:line 220

at ADM.Sharepoint.SiteAdmin.Web.Services.OperationService.CreateOperation(Operation operation) in C:\Users\krishna.nadiminti\Work\...\Services\OperationService.cs:line 136

Win identity Name: MyDOMAIN\MyUserName, SID: S-1-5-21-1078621877-1660878857-569397357-10089, IsSystem: False, ImpersonationLevel: Impersonation

Thread identity: MyDOMAIN\MyUserName

Svc Ctxt identity: MyDOMAIN\MyUserName

LogonType:Password

UserId:MyDOMAIN\\MyUserName

RunLevel:Highest

DisplayName:

Id:

 

 


My code: (the part that does not work is commented out - but I need that to work) :


            var logonDetails = string.Empty;
            try
            {
                using (var ts = GetTaskService())
                {
                    var folder = ts.RootFolder.SubFolders.FirstOrDefault(f => f.Name == FolderName);
                    if (folder == null)
                    {
                        folder = ts.RootFolder.CreateFolder(FolderName);
                    }

                    var taskNameToGenerate = operation.GetTaskName();
                    if (folder.Tasks.Count(t => t.Name == taskNameToGenerate) >= 1)
                    {
                        throw new ValidationException(string.Format(ValidationErrorResources.ValidationErrorOperationAlreadyExists, taskNameToGenerate));
                    }

                    var taskDef = ts.NewTask();
                    taskDef.Settings.Compatibility = TaskCompatibility.V2;

                    taskDef.Data = SerializeOperation(operation);
                    taskDef.RegistrationInfo.Source = "Parish Admin Site Tool";
                    taskDef.RegistrationInfo.Description = "Created by the Parish Admin Site Tool";

                    var execAction = new ExecAction(GetTaskExecActionCommand(), GetTaskExecActionArgs(operation));
                    taskDef.Actions.Add(execAction);
                    taskDef.Triggers.Add(new TimeTrigger(operation.Scheduled));

                    //COMMENTED OUT since this doesn't seem to work: but we need it to run the task with the highest privilege, regardless of whether the user is logged on or not.
		  //taskDef.Principal.UserId = this.ServiceContext.User.Identity.Name; //commented out 
                    //taskDef.Principal.RunLevel = TaskRunLevel.Highest; //TODO do we need this? on Win7, I get access denied, on Win 2008, COMException
                    //taskDef.Principal.LogonType = TaskLogonType.Password;
                    //logonDetails = "LogonType:" + taskDef.Principal.LogonType.ToString();
                    //logonDetails += "\nUserId:" + taskDef.Principal.UserId;
                    //logonDetails += "\nRunLevel:" + taskDef.Principal.RunLevel;
                    //logonDetails += "\nDisplayName:" + taskDef.Principal.DisplayName;
                    //logonDetails += "\nId:" + taskDef.Principal.Id;

                    var task = folder.RegisterTaskDefinition(taskNameToGenerate, taskDef);

                    //var task = folder.RegisterTaskDefinition(taskNameToGenerate, taskDef,
                    //    TaskCreation.Create,
                    //    taskDef.Principal.UserId, operation.PasswordForNonInteractiveUser, TaskLogonType.Password);

                    var path = task.Path;
                    task.Dispose();

                    operation.GeneratedId = path;
                }
            }
            catch (Exception ex) //a bit ugly, but this will do for this simple utility


Any ideas / help, greatly appreciated.
Regards,
Krishna
Coordinator
Aug 11, 2011 at 2:53 PM

Do not set the Principal.UserId or LogonType properties by assignment in code. Use the parameters in the RegisterTaskDefinition method to set the username, password, and logon type as noted below. Please note that the username must be in the "domain\username" format. I believe your code only pulls the username.

folder.RegisterTaskDefinition(taskNameToGenerate, taskDef, TaskCreation.Create, "domain\userid", "password", TaskLogonType.Password);