aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan McNulty <bryanmcnulty@protonmail.com>2025-03-01 21:45:52 -0600
committerBryan McNulty <bryanmcnulty@protonmail.com>2025-03-01 21:45:52 -0600
commit95639314be41bbbdf092e42600f3a492d30427cc (patch)
tree19d3716c9e0d8557aff56f4d6df51cff1eaec5b9
parent6dcae18a99ba7f7ca44c246d0e72b4d9410eb60c (diff)
downloadgoexec-95639314be41bbbdf092e42600f3a492d30427cc.tar.gz
goexec-95639314be41bbbdf092e42600f3a492d30427cc.zip
Added descriptions to tsch subcommand help menus; +small fixes
-rw-r--r--cmd/tsch.go39
-rw-r--r--pkg/exec/tsch/exec.go51
2 files changed, 64 insertions, 26 deletions
diff --git a/cmd/tsch.go b/cmd/tsch.go
index 3c2038e..6be81b8 100644
--- a/cmd/tsch.go
+++ b/cmd/tsch.go
@@ -66,8 +66,20 @@ var (
}
tschRegisterCmd = &cobra.Command{
Use: "register [target]",
- Short: "Register a scheduled task with an automatic start time",
- Args: needsTarget,
+ Short: "Register a remote scheduled task with an automatic start time",
+ Long: `Description:
+ The register method calls SchRpcRegisterTask to register a scheduled task
+ with an automatic start time.This method avoids directly calling SchRpcRun,
+ and can even avoid calling SchRpcDelete by populating the DeleteExpiredTaskAfter
+ Setting.
+
+References:
+ SchRpcRegisterTask - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/849c131a-64e4-46ef-b015-9d4c599c5167
+ SchRpcRun - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/77f2250d-500a-40ee-be18-c82f7079c4f0
+ SchRpcDelete - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/360bb9b1-dd2a-4b36-83ee-21f12cb97cff
+ DeleteExpiredTaskAfter - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/6bfde6fe-440e-4ddd-b4d6-c8fc0bc06fae
+`,
+ Args: needsTarget,
Run: func(cmd *cobra.Command, args []string) {
if tschNoDelete {
log.Warn().Msg("Task will not be deleted after execution")
@@ -94,8 +106,17 @@ var (
}
tschDemandCmd = &cobra.Command{
Use: "demand [target]",
- Short: "Register a scheduled task and demand immediate start",
- Args: needsTarget,
+ Short: "Register a remote scheduled task and demand immediate start",
+ Long: `Description:
+ Similar to the register method, the demand method will call SchRpcRegisterTask,
+ But rather than setting a defined time when the task will start, it will
+ additionally call SchRpcRun to forcefully start the task.
+
+References:
+ SchRpcRegisterTask - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/849c131a-64e4-46ef-b015-9d4c599c5167
+ SchRpcRun - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/77f2250d-500a-40ee-be18-c82f7079c4f0
+`,
+ Args: needsTarget,
Run: func(cmd *cobra.Command, args []string) {
if tschNoDelete {
log.Warn().Msg("Task will not be deleted after execution")
@@ -118,8 +139,14 @@ var (
}
tschDeleteCmd = &cobra.Command{
Use: "delete [target]",
- Short: "Delete a scheduled task",
- Args: needsTarget,
+ Short: "Manually delete a scheduled task",
+ Long: `Description:
+ The delete method manually deletes a scheduled task by calling SchRpcDelete
+
+References:
+ SchRpcDelete - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/360bb9b1-dd2a-4b36-83ee-21f12cb97cff
+`,
+ Args: needsTarget,
Run: func(cmd *cobra.Command, args []string) {
module := tschexec.Module{}
cleanCfg := &exec.CleanupConfig{
diff --git a/pkg/exec/tsch/exec.go b/pkg/exec/tsch/exec.go
index 030a016..aef5836 100644
--- a/pkg/exec/tsch/exec.go
+++ b/pkg/exec/tsch/exec.go
@@ -91,6 +91,8 @@ func (mod *Module) Exec(ctx context.Context, creds *adauth.Credential, target *a
} else {
startTime := time.Now().UTC().Add(cfg.StartDelay)
+ stopTime := startTime.Add(cfg.StopDelay)
+
task := &task{
TaskVersion: "1.2", // static
TaskNamespace: "http://schemas.microsoft.com/windows/2004/02/mit/task", // static
@@ -102,16 +104,21 @@ func (mod *Module) Exec(ctx context.Context, creds *adauth.Credential, target *a
},
Principals: defaultPrincipals,
Settings: defaultSettings,
- Actions: actions{Context: defaultPrincipals.Principals[0].ID, Exec: []actionExec{{Command: ecfg.ExecutableName, Arguments: ecfg.ExecutableArgs}}},
+ Actions: actions{
+ Context: defaultPrincipals.Principals[0].ID,
+ Exec: []actionExec{
+ {
+ Command: ecfg.ExecutableName,
+ Arguments: ecfg.ExecutableArgs,
+ },
+ },
+ },
}
if !cfg.NoDelete && !cfg.CallDelete {
if cfg.StopDelay == 0 {
// EndBoundary cannot be >= StartBoundary
cfg.StopDelay = 1 * time.Second
}
- stopTime := startTime.Add(cfg.StopDelay)
-
- mod.log.Info().Time("when", stopTime).Msg("Task is scheduled to delete")
task.Settings.DeleteExpiredTaskAfter = xmlDuration(cfg.DeleteDelay)
task.TimeTriggers[0].EndBoundary = stopTime.Format(TaskXMLDurationFormat)
}
@@ -157,25 +164,29 @@ func (mod *Module) Exec(ctx context.Context, creds *adauth.Credential, target *a
} else {
mod.log.Info().Str("path", response.ActualPath).Msg("Task registered successfully")
- if !cfg.NoDelete && cfg.CallDelete {
- defer func() {
- if err = mod.Cleanup(ctx, creds, target, &exec.CleanupConfig{
- CleanupMethod: MethodDelete,
- CleanupMethodConfig: MethodDeleteConfig{TaskPath: taskPath},
- }); err != nil {
- mod.log.Error().Err(err).Msg("Failed to delete task")
+ if !cfg.NoDelete {
+ if cfg.CallDelete {
+ defer func() {
+ if err = mod.Cleanup(ctx, creds, target, &exec.CleanupConfig{
+ CleanupMethod: MethodDelete,
+ CleanupMethodConfig: MethodDeleteConfig{TaskPath: taskPath},
+ }); err != nil {
+ mod.log.Error().Err(err).Msg("Failed to delete task")
+ }
+ }()
+ mod.log.Info().Dur("ms", cfg.StartDelay).Msg("Waiting for task to run")
+ select {
+ case <-ctx.Done():
+ mod.log.Warn().Msg("Cancelling execution")
+ return err
+ case <-time.After(cfg.StartDelay + (time.Second * 2)): // + two seconds
+ // TODO: check if task is running yet; delete if the wait period is over
+ break
}
- }()
- mod.log.Info().Dur("ms", cfg.StartDelay).Msg("Waiting for task to run")
- select {
- case <-ctx.Done():
- mod.log.Warn().Msg("Cancelling execution")
return err
- case <-time.After(cfg.StartDelay + (time.Second * 2)): // + two seconds
- // TODO: check if task is running yet; delete if the wait period is over
- break
+ } else {
+ mod.log.Info().Time("when", stopTime).Msg("Task is scheduled to delete")
}
- return err
}
}
}