peass-ng/PEASS-ng · error · ArgumentOutOfRangeException

A task must be registered with at least one action and no…

Error message

A task must be registered with at least one action and no more than 32 actions.

What it means

RegisterTaskDefinition validates that the task definition has between 1 and 32 actions and throws ArgumentOutOfRangeException otherwise. The Windows Task Scheduler requires at least one action per registered task and caps actions at 32.

Solutions

  1. Add at least one action, e.g. definition.Actions.Add(new ExecAction("cmd.exe", "/c script")), before registering
  2. Split tasks exceeding 32 actions into multiple registered tasks or chained tasks
  3. Validate definition.Actions.Count in [1,32] before calling RegisterTaskDefinition

Example fix

// before
var td = ts.NewTask();
// forgot to add an action
rootFolder.RegisterTaskDefinition("MyTask", td);
// after
var td = ts.NewTask();
td.Actions.Add(new ExecAction("notepad.exe"));
rootFolder.RegisterTaskDefinition("MyTask", td);
Defensive patterns

Strategy: validation

Validate before calling

if (definition.Actions.Count < 1 || definition.Actions.Count > 32) throw new InvalidOperationException("Task must have 1-32 actions");

Try / catch

try { root.RegisterTaskDefinition(name, td); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "definition.Actions") { /* add/split actions */ }

Prevention

When it happens

Trigger: Calling RegisterTaskDefinition (directly or via RegisterTask) with a TaskDefinition whose Actions collection is empty, or programmatically appending more than 32 actions.

Common situations: Building a TaskDefinition without calling Actions.Add (forgot to add an ExecAction); loops that batch-generate tasks and exceed the 32-action cap; merging action lists from configuration without bounding them.

Related errors


AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02). Data as JSON: /api/errors/7ad54baa98fd2997. Report an issue: GitHub.

Appendix: source

Thrown at winPEAS/winPEASexe/winPEAS/TaskScheduler/TaskFolder.cs:484

        /// 
        /// // 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 ??= 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));

View on GitHub (pinned to 53fb989abc)