Skip to content

Managing Scheduled Tasks

This article describes how to manage Scheduled Tasks using PowerShell scripts and C# code. The code samples included in this article can be used in stand-alone scripts and applications as well as in PowerShell scripts executed by Business Rules, Custom Commands, and Scheduled Tasks.

Creating a Scheduled Task

To create a Scheduled Task, first you need to bind to the container where you want to create it. All container objects support the IADsContainer interface, which provides methods and properties that manage the creation, deletion, and enumeration of child objects. To create a new Scheduled Task, you need to call the Create method of the interface and pass “adm-ScheduledTask” as the first parameter of the method and the relative distinguished name (RDN) of the task as the second parameter. The object returned by the IADsContainer::Create method will support the IAdmScheduledTask and IAdmScheduledTask2 interfaces, using which you can specify the parameters of the new Scheduled Task. The IAdmScheduledTask interface is inherited from the IAdmBusinessRule interface and some Scheduled Task parameters must be set via the properties of the IAdmBusinessRule interface.

  1. Use the IAdmBusinessRule::ObjectType property to specify the type of directory objects the Scheduled Task will apply to. The Scheduled Task will be executed on each directory object of the specified type that is included in the scope of activity of the task.

    The property must be set to a string that contains the name of an object class as defined in the Active Directory schema (e.g. “user”, “group”, “computer”, “organizationalUnit”).

    Using the IAdmBusinessRule2::AdditionalObjectType property, you can specify an additional type of objects on which the Scheduled Task will be executed.

  2. Always set the IAdmBusinessRule::ExecutionMoment property of Scheduled Task objects to ADM_BUSINESSRULEEXECMOMENT_BEFORE.

  3. Always set the IAdmBusinessRule::OperationType property of Scheduled Task objects to “none”.

To save the new Scheduled Task, call IADs::SetInfo.

The following code sample creates a Scheduled Task to be executed on users.

[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

# Connect to the Adaxes service
$admNS = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$admService = $admNS.GetServiceDirectly("localhost")

# Bind to the 'Scheduled Tasks' container
$scheduledTasksPath = $admService.Backend.GetConfigurationContainerPath(
    "ScheduledTasks")
$scheduledTasksContainer = $admService.OpenObject($scheduledTasksPath,
     $NULL, $NULL, 0)

# Create a new Scheduled Task
$task = $scheduledTasksContainer.Create("adm-ScheduledTask", "CN=My Task")

$task.ObjectType = "user"
$task.Description = "My description"
$task.Disabled = $False
$task.ExecutionMoment = "ADM_BUSINESSRULEEXECMOMENT_BEFORE"
$task.OperationType = "none"

# [TODO] Specify the schedule for the task

# Save the Scheduled Task
$task.SetInfo()
using System;
using Interop.Adsi;
using Interop.Adsi.BusinessRules;
using Interop.Adsi.ScheduledTasks;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;
class Program
{
    static void Main(string[] args)
    {
        // Connect to the Adaxes service
        AdmNamespace adsNS = new AdmNamespace();
        IAdmService admService = adsNS.GetServiceDirectly("localhost");

        // Bind to the 'Scheduled Tasks' container
        String scheduledTasksPath = admService.Backend.GetConfigurationContainerPath(
            "ScheduledTasks");
        IADsContainer scheduledTasksContainer = (IADsContainer)admService.OpenObject(
            scheduledTasksPath, null, null, 0);

        // Create a new Scheduled Task
        IAdmScheduledTask task = (IAdmScheduledTask)scheduledTasksContainer.Create(
            "adm-ScheduledTask", "CN=My Task");

        task.ObjectType = "user";
        task.Description = "My description";
        task.Disabled = false;
        task.ExecutionMoment =
            ADM_BUSINESSRULEEXECMOMENT_ENUM.ADM_BUSINESSRULEEXECMOMENT_BEFORE;
        task.OperationType = "none";

        // [TODO] Specify the schedule for the task

        // Save the Scheduled Task
        task.SetInfo();
    }
}

If your script is executed by a Business Rule, Custom Command, or Scheduled Task, you can use a predefined PowerShell variable $Context to get the ADS path of the Scheduled Tasks container and bind to the container. The type of the $Context variable is ExecuteScriptContextClass.

# Bind to the 'Scheduled Tasks' container
$scheduledTasksPath = $Context.GetWellKnownContainerPath("ScheduledTasks")
$scheduledTasksContainer = $Context.BindToObject($scheduledTasksPath)

# Create a new Scheduled Task
$task = $scheduledTasksContainer.Create("adm-ScheduledTask", "CN=My Task")

$task.ObjectType = "user"
$task.Description = "My description"
$task.Disabled = $False
$task.ExecutionMoment = "ADM_BUSINESSRULEEXECMOMENT_BEFORE"
$task.OperationType = "none"

# [TODO] Specify the schedule for the task

# Save the Scheduled Task
$task.SetInfo()
How to create a Scheduled Task in a specific container

The following code sample creates a Scheduled Task in the container called My Container. The scheduled task will apply to Group objects.

[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

# Connect to the Adaxes service
$admNS = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$admService = $admNS.GetServiceDirectly("localhost")

# Bind to the 'Scheduled Tasks' container
$scheduledTasksPath = $admService.Backend.GetConfigurationContainerPath(
    "ScheduledTasks")
# Build the ADS path of the child container 'My Container'
$scheduledTasksPathObj = New-Object "Softerra.Adaxes.Adsi.AdsPath"`
    $scheduledTasksPath
$myContainerAdsPath = $scheduledTasksPathObj.CreateChildPath("CN=My Container")

$myContainer = $admService.OpenObject($myContainerAdsPath, $NULL, $NULL, 0)

# Create a new Scheduled Task
$task = $myContainer.Create("adm-ScheduledTask", "CN=My Task")

$task.ObjectType = "group"
$task.Description = "My description"
$task.Disabled = $False
$task.ExecutionMoment = "ADM_BUSINESSRULEEXECMOMENT_BEFORE"
$task.OperationType = "none"

# [TODO] Specify the schedule for the task

# Save the Scheduled Task
$task.SetInfo()
using System;
using Interop.Adsi;
using Interop.Adsi.BusinessRules;
using Interop.Adsi.ScheduledTasks;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;
class Program
{
    static void Main(string[] args)
    {
        // Connect to the Adaxes service
        AdmNamespace adsNS = new AdmNamespace();
        IAdmService admService = adsNS.GetServiceDirectly("localhost");

        // Bind to the 'Scheduled Tasks' container
        String scheduledTasksPath = admService.Backend.GetConfigurationContainerPath(
            "ScheduledTasks");
        // Build the ADS path of the child container 'My Container'
        AdsPath scheduledTasksPathObj = new AdsPath(scheduledTasksPath);
        AdsPath myContainerAdsPath = scheduledTasksPathObj.CreateChildPath(
            "CN=My Container");

        IADsContainer myContainer = (IADsContainer)admService.OpenObject(
            myContainerAdsPath.ToString(), null, null, 0);

        // Create a new Scheduled Task
        IAdmScheduledTask task = (IAdmScheduledTask)myContainer.Create(
            "adm-ScheduledTask", "CN=My Task");

        task.ObjectType = "group";
        task.Description = "My description";
        task.Disabled = false;
        task.ExecutionMoment =
            ADM_BUSINESSRULEEXECMOMENT_ENUM.ADM_BUSINESSRULEEXECMOMENT_BEFORE;
        task.OperationType = "none";

        // [TODO] Specify the schedule for the task

        // Save the Scheduled Task
        task.SetInfo();
    }
}

Tip

For information on how to create containers for Scheduled Tasks, see Creating Scheduled Task containers.

Defining the schedule

To define the schedule for a task, use the GetRecurrencePattern and SetRecurrencePattern methods of the IAdmScheduledTask interface. A task schedule is represented by the IAdmRecurrencePattern interface.

  • Use the IAdmRecurrencePattern::RecurrenceType property to specify the type of schedule recurrence (once, minutely, hourly, daily, weekly or monthly). For a list of possible recurrence types, see the ADM_RECURRENCEPATTERNTYPE_ENUM enumeration.

    Tip

    If you set the recurrence type to ADM_RECURRENCEPATTERNTYPE_ONCE, you can mark the task to be automatically deleted after execution by setting the DeleteTaskAfterExecution property of the IAdmScheduledTask interface to TRUE.

  • To set the start date and time for the Scheduled Task, use the IAdmRecurrencePattern::PatternStartDateTime property.

  • To set the date and time before which the task must not be executed, use the IAdmRecurrencePattern::NotBeforeDateTime property.

  • Use the IAdmRecurrencePattern::Interval property to set the interval between occurrences of the task. The Interval property makes sense only if the RecurrenceType property is set to ADM_RECURRENCEPATTERNTYPE_MINUTELY, ADM_RECURRENCEPATTERNTYPE_HOURLY or ADM_RECURRENCEPATTERNTYPE_DAILY. Depending on the recurrence type, the Interval property determines the number of minutes, hours or days between occurrences of the task.

  • Use the IAdmRecurrencePattern::DayOfWeekMask property to set the days of week on which the task is to be executed. The property gets a bitmask that represents the combination of ADM_DAYSOFWEEK_ENUM enumeration values that make up a recurrence pattern.

    The DayOfWeekMask property is valid only for the ADM_RECURRENCEPATTERNTYPE_WEEKLY recurrence type.

  • Use the IAdmRecurrencePattern::DayOfMonth property to set the day of the month on which the task is to be executed. The value must be between 1 and 31, inclusive, or -1 for the last day in month.

    The DayOfMonth property is valid only for the ADM_RECURRENCEPATTERNTYPE_MONTHLY recurrence type.

Example 1: Schedule a task to be executed only one time (in 30 days after creation) and configure the task to be deleted after execution

# The $task variable refers to a Scheduled Task          

$recurrencePattern = $task.GetRecurrencePattern()
$recurrencePattern.RecurrenceType = "ADM_RECURRENCEPATTERNTYPE_ONCE"
$recurrencePattern.PatternStartDateTime = (Get-Date).AddDays(30)
$task.SetRecurrencePattern($recurrencePattern)
$task.DeleteTaskAfterExecution = $True
// The task variable refers to a Scheduled Task

IAdmRecurrencePattern recurrencePattern = task.GetRecurrencePattern();
recurrencePattern.RecurrenceType =
    ADM_RECURRENCEPATTERNTYPE_ENUM.ADM_RECURRENCEPATTERNTYPE_ONCE;
recurrencePattern.PatternStartDateTime = DateTime.Now.AddDays(30);
task.SetRecurrencePattern(recurrencePattern);
task.DeleteTaskAfterExecution = true;

Example 2: Schedule a task to be executed every two hours

# The $task variable refers to a Scheduled Task

$recurrencePattern = $task.GetRecurrencePattern()
$recurrencePattern.RecurrenceType = "ADM_RECURRENCEPATTERNTYPE_HOURLY"
$recurrencePattern.Interval = 2
$task.SetRecurrencePattern($recurrencePattern)
// The task variable refers to a Scheduled Task

IAdmRecurrencePattern recurrencePattern = task.GetRecurrencePattern();
recurrencePattern.RecurrenceType =
    ADM_RECURRENCEPATTERNTYPE_ENUM.ADM_RECURRENCEPATTERNTYPE_HOURLY;
recurrencePattern.Interval = 2;
task.SetRecurrencePattern(recurrencePattern);

Example 3: Schedule a task to be executed every day at 4:00am

# The $task variable refers to a Scheduled Task

$recurrencePattern = $task.GetRecurrencePattern()
$recurrencePattern.RecurrenceType = "ADM_RECURRENCEPATTERNTYPE_DAILY"
$recurrencePattern.Interval = 1
$now = Get-Date
$recurrencePattern.PatternStartDateTime = Get-Date `
    -year $now.Year `
    -month $now.Month `
    -day $now.Day `
    -hour 4 `
    -minute 0 `
    -second 0
$recurrencePattern.NotBeforeDateTime = $now
$task.SetRecurrencePattern($recurrencePattern)
// The task variable refers to a Scheduled Task

IAdmRecurrencePattern recurrencePattern = task.GetRecurrencePattern();
recurrencePattern.RecurrenceType =
    ADM_RECURRENCEPATTERNTYPE_ENUM.ADM_RECURRENCEPATTERNTYPE_DAILY;
recurrencePattern.Interval = 1;
DateTime now = DateTime.Now;
recurrencePattern.PatternStartDateTime = new DateTime(now.Year,
    now.Month, now.Day, 4, 0, 0);
recurrencePattern.NotBeforeDateTime = now;
task.SetRecurrencePattern(recurrencePattern);

Example 4: Schedule a task to be executed every Wednesday and Saturday at 2:00am

# The $task variable refers to a Scheduled Task

$recurrencePattern = $task.GetRecurrencePattern()
$recurrencePattern.RecurrenceType = "ADM_RECURRENCEPATTERNTYPE_WEEKLY"
$recurrencePattern.DayOfWeekMask =
    "ADM_DAYSOFWEEK_WEDNESDAY, ADM_DAYSOFWEEK_SATURDAY"
$now = Get-Date
$recurrencePattern.PatternStartDateTime = Get-Date `
    -year $now.Year `
    -month $now.Month `
    -day $now.Day `
    -hour 2 `
    -minute 0 `
    -second 0
$recurrencePattern.NotBeforeDateTime = $now
$task.SetRecurrencePattern($recurrencePattern)
// The task variable refers to a Scheduled Task

IAdmRecurrencePattern recurrencePattern = task.GetRecurrencePattern();
recurrencePattern.RecurrenceType =
    ADM_RECURRENCEPATTERNTYPE_ENUM.ADM_RECURRENCEPATTERNTYPE_WEEKLY;
recurrencePattern.DayOfWeekMask =
    ADM_DAYSOFWEEK_ENUM.ADM_DAYSOFWEEK_WEDNESDAY |
    ADM_DAYSOFWEEK_ENUM.ADM_DAYSOFWEEK_SATURDAY;
DateTime now = DateTime.Now;
recurrencePattern.PatternStartDateTime = new DateTime(now.Year,
    now.Month, now.Day, 2, 0, 0);
recurrencePattern.NotBeforeDateTime = now;
task.SetRecurrencePattern(recurrencePattern);

Example 5: Schedule a task to be executed on the last day of each month at 1:00pm

# The $task variable refers to a Scheduled Task

$recurrencePattern = $task.GetRecurrencePattern()
$recurrencePattern.RecurrenceType = "ADM_RECURRENCEPATTERNTYPE_MONTHLY"
$recurrencePattern.DayOfMonth = -1
$now = Get-Date
$recurrencePattern.PatternStartDateTime = Get-Date `
    -year $now.Year `
    -month $now.Month `
    -day $now.Day `
    -hour 13 `
    -minute 0 `
    -second 0
$recurrencePattern.NotBeforeDateTime = $now
$task.SetRecurrencePattern($recurrencePattern)
// The task variable refers to a Scheduled Task

IAdmRecurrencePattern recurrencePattern = task.GetRecurrencePattern();
recurrencePattern.RecurrenceType =
    ADM_RECURRENCEPATTERNTYPE_ENUM.ADM_RECURRENCEPATTERNTYPE_MONTHLY;
recurrencePattern.DayOfMonth = -1;
DateTime now = DateTime.Now;
recurrencePattern.PatternStartDateTime = new DateTime(now.Year,
    now.Month, now.Day, 13, 0, 0);
recurrencePattern.NotBeforeDateTime = now;
task.SetRecurrencePattern(recurrencePattern);

Defining actions and conditions

To define actions and conditions for a Scheduled Task, you need to use the ConditionedActions property of the IAdmBusinessRule interface (the IAdmScheduledTask interface is inherited from the IAdmBusinessRule interface). The ConditionedActions property is a collection that supports the IAdmCollection interface. Each item in the collection represents a set of conditions and actions.

For information on how to manage Scheduled Task actions and conditions, see Defining actions and conditions.

Defining the scope of activity

The activity scope of a Scheduled Task determines the objects affected by the task. A Scheduled Task is executed on each directory object included in the activity scope of the task. Activity scope can include whole domains, members of groups and Business Units, objects located in specific Organizational Units, etc.

To define the scope of activity of a Scheduled Task, you need to use the ActivityScopeItems property of the IAdmBusinessRule interface.

For information on how to define the activity scope of a Scheduled Task, see Defining the scope of activity.

Modifying a Scheduled Task

To modify an existing Scheduled Task, first you need to bind to the directory object representing the Scheduled Task. For more information on how to bind to Adaxes-specific objects, see Binding to Adaxes-specific objects.

After you’ve bound to a Scheduled Task object, you can use ADSI interfaces like IAdmScheduledTask, IAdmBusinessRule and IADs to modify the Scheduled Task. To save the changes, call IADs::SetInfo.

The following code sample disables a Scheduled Task and changes the type of directory objects to which the Scheduled Task applies.

[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

# Connect to the Adaxes service
$admNS = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$admService = $admNS.GetServiceDirectly("localhost")

$tasksPath = $admService.Backend.GetConfigurationContainerPath(
    "ScheduledTasks")
$tasksPathObj = New-Object "Softerra.Adaxes.Adsi.AdsPath" $tasksPath
$taskPath = $tasksPathObj.CreateChildPath("CN=My Task")
$task = $admService.OpenObject($taskPath.ToString(), $NULL, $NULL, 0)

$task.ObjectType = "contact"
$task.Disabled = $True

# Save the changes
$task.SetInfo()
using System;
using Interop.Adsi.ScheduledTasks;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;
class Program
{
    static void Main(string[] args)
    {
        AdmNamespace adsNS = new AdmNamespace();
        IAdmService admService = adsNS.GetServiceDirectly("localhost");

        String tasksPath = admService.Backend.GetConfigurationContainerPath(
            "ScheduledTasks");
        AdsPath tasksPathObj = new AdsPath(tasksPath);
        AdsPath taskPath = tasksPathObj.CreateChildPath("CN=My Task");
        IAdmScheduledTask task =
            (IAdmScheduledTask)admService.OpenObject(taskPath.ToString(), null, null, 0);

        task.ObjectType = "contact";
        task.Disabled = true;

        // Save the changes
        task.SetInfo();
    }
}

If your script is executed by a Business Rule, Custom Command or Scheduled Task, you can use a predefined PowerShell variable $Context to get the ADS path of the Scheduled Tasks container and bind to the Scheduled Task.

$tasksPath = $Context.GetWellKnownContainerPath("ScheduledTasks")
$tasksPathObj = New-Object "Softerra.Adaxes.Adsi.AdsPath" $tasksPath
$taskPath = $tasksPathObj.CreateChildPath("CN=My Task")
$task = $Context.BindToObject($taskPath)

$task.ObjectType = "contact"
$task.Disabled = $True

# Save the changes
$task.SetInfo()

The following code sample clears the activity scope and deletes all actions and conditions from a Scheduled Task located in the container named My Container.

[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

# Connect to the Adaxes service
$admNS = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$admService = $admNS.GetServiceDirectly("localhost")

$tasksPath = $admService.Backend.GetConfigurationContainerPath(
    "ScheduledTasks")
$tasksPathObj = New-Object "Softerra.Adaxes.Adsi.AdsPath" $tasksPath
$containerPathObj = $tasksPathObj.CreateChildPath("CN=My Container")
$taskPath = $containerPathObj.CreateChildPath("CN=My Task")
$task = $admService.OpenObject($taskPath.ToString(), $NULL, $NULL, 0)

$task.ConditionedActions.Clear()
$task.ActivityScopeItems.Clear()
using System;
using Interop.Adsi.ScheduledTasks;
using Interop.Adsi.BusinessRules;
using Softerra.Adaxes.Adsi;
using Softerra.Adaxes.Interop.Adsi.PersistentObjects;
class Program
{
    static void Main(string[] args)
    {
        AdmNamespace adsNS = new AdmNamespace();
        IAdmService admService = adsNS.GetServiceDirectly("localhost");

        String tasksPath = admService.Backend.GetConfigurationContainerPath(
            "ScheduledTasks");
        AdsPath tasksPathObj = new AdsPath(tasksPath);
        AdsPath containerPathObj = tasksPathObj.CreateChildPath("CN=My Container");
        AdsPath taskPath = containerPathObj.CreateChildPath("CN=My Task");
        IAdmScheduledTask task =
            (IAdmScheduledTask)admService.OpenObject(taskPath.ToString(),
            null, null, 0);

        task.ConditionedActions.Clear();
        task.ActivityScopeItems.Clear();
    }
}

See also