0 votes

I have a PowerShell Script (being run in a Custom Command) that creates a Scheduled Task that runs another Custom Command but I want the resulting Scheduled Task to delete itself once it has run. Essentially, I'm creating a schedulable Custom Command workflow that's fire-and-forget.

What is the safest way to do this? I don't want to rely on a batch job to clear out said Tasks from a Container.

Some example code I have been playing with:

$UserDisplayName = "%displayName%"
$UserObjectDN = "%distinguishedName%"
$ScheduledDate = [datetime]::ParseExact("%param-ScheduledDateTime%","dd/MM/yyyy HH:mm:ss",$null)
$TasksContainerDN = "CN=Once-Off,CN=Scheduled Tasks,CN=Configuration Objects,CN=Adaxes Configuration,CN=Adaxes" #Or Perhaps $Context.GetWellKnownContainerPath("ScheduledTasks")
$CustomCommandID = "{00000000-0000-0000-0000-000000000000}"
$CustomCommandDN = "CN=My Custom Command,CN=Custom Commands,CN=Configuration Objects,CN=Adaxes Configuration,CN=Adaxes"
$CustomCommandParamValues = @{
    MyParamOne = "%param-MyParamOne%"
    MyParamTwo = "%param-MyParamTwo%"
}

$scheduledTasksContainer = $Context.BindToObject($TasksContainerDN)
$scheduledTasksContainer.Filter = @("adm-ScheduledTask")
$existingTaskFound = $false
foreach($scheduledTask in $scheduledTasksContainer)
{
    if($scheduledTask.TaskName -eq "My Custom Command - $($UserDisplayName) %objectGUID%") {
        $existingTaskFound = $true
        $Context.Cancel("$($UserDisplayName) is already scheduled for My Custom Command.")
    }
}

if(!$existingTaskFound) {
    $task = $scheduledTasksContainer.Create("adm-ScheduledTask", "CN=My Custom Command - $($UserDisplayName) %objectGUID%")

    $task.ObjectType = "user"
    $task.Description = "My Custom Command - $($UserDisplayName) %objectGUID% (Created by %adm-InitiatorFullName%)"
    $task.Disabled = $False
    $task.ExecutionMoment = "ADM_BUSINESSRULEEXECMOMENT_BEFORE"
    $task.OperationType = "none"

    $recurrencePattern = $task.GetRecurrencePattern()
    $recurrencePattern.RecurrenceType = "ADM_RECURRENCEPATTERNTYPE_ONCE"
    $recurrencePattern.PatternStartDateTime = $ScheduledDate
    $task.SetRecurrencePattern($recurrencePattern)
    $task.DeleteTaskAfterExecution = $True
    $task.SetInfo()

    $actionsAndConditions = $task.ConditionedActions.Create()
    $actionsAndConditions.ConditionsLogicalOperation = "ADM_LOGICALOPERATION_AND"
    $actionsAndConditions.SetInfo()

    $action = $actionsAndConditions.Actions.CreateEx("adm-CustomCommandAction")
    $action.ExecutionOptions = "ADM_ACTIONEXECUTIONOPTIONS_SYNC"
    $customCommand = $Context.BindToObjectByDN($CustomCommandDN)
    $arguments = $customCommand.CreateArguments()
    foreach($Parameter in $CustomCommandParamValues.Keys) {
        $arguments.SetParameterValue($Parameter, $CustomCommandParamValues.Item($Parameter))
    }
    $customCommandAction = $action.GetAction()
    $customCommandAction.CustomCommandId = $CustomCommandID
    $customCommandAction.Arguments = $arguments
    $action.SetAction($customCommandAction)
    $action.SetInfo()
    $actionsAndConditions.Actions.Add($action)

    $task.ConditionedActions.Add($actionsAndConditions)

    $scopeItem = $task.ActivityScopeItems.Create()
    $scopeItem.BaseObject = $Context.BindToObject("Adaxes://$($UserObjectDN)")
    $scopeItem.Type = "ADM_SCOPEBASEOBJECTTYPE_CONTAINER "
    $scopeItem.Inheritance = "ADS_SCOPE_BASE"
    $scopeItem.Exclude = $False
    $scopeItem.SetInfo()

    $task.ActivityScopeItems.Add($scopeItem)

    $task.SetInfo()
}
by (350 points)

1 Answer

+1 vote
by (270k points)
selected by
Best answer

Hello,

The correct way to create a scheduled task that will run once and then delete itself is by setting the DeleteTaskAfterExecution property of the task to $True which you already have in your script. As per our check, the only thing you need to change in the script is replacing this line

$scheduledTasksContainer = $Context.BindToObject($TasksContainerDN)

with the below one

$scheduledTasksContainer = $Context.BindToObjectByDN($TasksContainerDN)

The update is required because method BindToObject requires an ADS path as parameter, not a distinguished name.

If you have issues with the script, please, provide all the possible details and live examples.

0

Strange, as they tasks weren't deleting after execution. Thank you for the code review.

Related questions

0 votes
1 answer

I have an ADP Sync scheduled task that modifies and creates users from a csv file. I also have reports that show new users created and management history for user ... ADP Sync scheduled task so that they only run after the ADP Sync task is complete?

asked Jan 7, 2020 by barberk (60 points)
0 votes
0 answers

I am creating a new scheduled task and form. We would like to have the ability to schedule the reassignment of a staff member to a different location in the future. ... context, my manager won't necessarily know when he tries to move somebody. Thanks everybody

asked May 21, 2020 by jcalvert (60 points)
0 votes
1 answer

On Approval Requests, in the web console, Initiator shows "N/A" instead of the custom command scheduled task. The admin console shows the custom command scheduled task though. Any way to fix that?

asked Jan 21, 2021 by mark.it.admin (2.3k points)
0 votes
1 answer

Hello - I'm working on my companies off boarding process and need to run a Custom Command that turns off access to different systems and resources at the ... -9612-c7c982baa49f}" $user.ExecuteCustomCommand($commandID) # Save the Scheduled Task $task.SetInfo()

asked Jul 16, 2015 by jakesomething (190 points)
0 votes
1 answer

Hi, I followed this example: https://www.adaxes.com/sdk/IAdmTop6.html, but because the Custom Command is disabled, I get the following error message: System.Management.Automation ... if I enable the Custom Command. I am using Adaxes 2018.2 Best Regards Martin

asked Feb 19, 2020 by Martin (100 points)
3,326 questions
3,025 answers
7,724 comments
544,675 users