how to use a Group Managed service account to run a schedule task and make it "Run whether user is logged on or not"?

Topics: Setup
Mar 22, 2016 at 10:20 AM
how can I use a Group Managed service account to run a schedule task and make it "Run whether user is logged on or not"?
https://technet.microsoft.com/en-us/library/hh831782.aspx this is some thing about Group Managed service accounts,
I tried several ways:
. use AddTask directly
    TaskService.Instance.AddTask("Test", new MST.DailyTrigger { DaysInterval = 1 },
                                    new MST.ExecAction("notepad.exe", "c:\\test.log", "c:\\program files\\"), "myDomain\\testMSA$", null, TaskLogonType.None);
only TaskLogonType.None can AddTask successfully, but the task is "Run only when user is logged on"

. RegisterTaskDefinition
MyTask.Folder.RegisterTaskDefinition(MyTask.Name, MyTask.Definition,
                            TaskCreation.CreateOrUpdate, "rmad\\testMSA$", null, TaskLogonType.None);
TaskLogonType.InteractiveToken and TaskLogonType.None can AddTask successfully, but the task is "Run only when user is logged on"

. change Principal
MyTask.Definition.Principal.UserId = "rmad\\testMSA$";
MyTask.Definition.Principal.LogonType = TaskLogonType.None;
MyTask.Folder.RegisterTaskDefinition(MyTask.Name, MyTask.Definition);
only TaskLogonType.InteractiveToken can AddTask successfully, but the task is "Run only when user is logged on"
at the same time, when I assigned TaskLogonType.None and TaskLogonType.Group, I got error "Value does not fall within the expected range"

In short, I can create a schedule task using Group Managed service accounts to run, but just can't make the task "Run whether user is logged on or not"
Coordinator
Mar 28, 2016 at 4:29 PM
Can you use the system "Task Scheduler" applet to create a task using a Group Managed Service Account? If so, then export the XML and then copy it into your response. I should then be able to tell you how to do it programmatically using the library.
Mar 29, 2016 at 6:55 AM
Hi dahall, thinks for your reply. I use the following Powershell commands to create a schedule task with GMSA on a windows server 2012R2 machine:
$action = New-ScheduledTaskAction  "C:\PowerSlim\test.cmd"
$trigger = New-ScheduledTaskTrigger -At 20:43 -Daily
$principal = New-ScheduledTaskPrincipal -UserID er\zz$ -LogonType Password
Register-ScheduledTask msaTask –Action $action –Trigger $trigger –Principal $principal
then the xml of "msaTask" is like below:
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo />
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2016-03-29T20:43:00</StartBoundary>
      <Enabled>true</Enabled>
      <RandomDelay>P0DT0H0M0S</RandomDelay>
      <ScheduleByDay>
        <DaysInterval>1</DaysInterval>
      </ScheduleByDay>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>er\zz$</UserId>
      <LogonType>Password</LogonType>
      <RunLevel>LeastPrivilege</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <Duration>PT10M</Duration>
      <WaitTimeout>PT1H</WaitTimeout>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
    <UseUnifiedSchedulingEngine>false</UseUnifiedSchedulingEngine>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>C:\PowerSlim\test.cmd</Command>
    </Exec>
  </Actions>
</Task>
Coordinator
Mar 29, 2016 at 3:50 PM
Edited Mar 29, 2016 at 4:10 PM
I thought you needed a trigger that fires at logon?

To accomplish what you have in your PowerShell example:
var action = new ExecAction("C:\PowerSlim\test.cmd");
var trigger = new DailyTrigger(DateTime.Today.AddHours(20));
TaskService.Instance.AddTask("msaTask", trigger, action, "er\zz$", "", TaskLogonType.Password);
-or-
TaskService.Instance.AddTask("msaTask", QuickTriggerType.Daily,
   "C:\PowerSlim\test.cmd", null, "er\zz$", "", TaskLogonType.Password);
Mar 30, 2016 at 7:43 AM
these tow ways are not working, here is my test code, I test it on windows server 2012R2:
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32.TaskScheduler;

namespace WrapperDemo
{
    internal static class Program
    {
        public static void Main(string[] args)
        {
            try
            {
                var action = new ExecAction(@"C:\PowerSlim\test.cmd");
                var trigger = new DailyTrigger(1);
                trigger.StartBoundary = DateTime.Today.AddHours(20);
                TaskService.Instance.AddTask("msaTask", trigger, action, @"er\zz$", "", TaskLogonType.Password);
            }
            catch (COMException exception)
            {
                Console.WriteLine(exception.ToString());
            }

        }
    }
}
I got exception like following on the console output:

System.Runtime.InteropServices.COMException (0x8007052E): The username or password is incorrect. (Exception from HRESULT: 0x8007052E)
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)
at Microsoft.Win32.TaskScheduler.TaskService.AddTask(String path, Trigger trigger, Action action, String UserId, String Password, TaskLogonType LogonType)
at WrapperDemo.Program.Main(String[] args) in C:\Users\lhuang2\Documents\Visual Studio 2015\Projects\WrapperDemo\WrapperDemo\Program.cs:line 20
Coordinator
Mar 30, 2016 at 3:13 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Marked as answer by dahall on 4/29/2016 at 10:05 AM
Coordinator
Apr 2, 2016 at 7:39 PM
Please check the link to the created issue (from previous post). I have posted some code and test assemblies for you to test.
Apr 6, 2016 at 3:21 AM
Hi dahall, I tried, your assemblies work well.
Coordinator
Apr 7, 2016 at 2:39 PM
Thanks. I'll get this out shortly as 2.5.17.
Marked as answer by dahall on 4/29/2016 at 10:05 AM