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 (289k 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

I have a few reports that I want to add to a custom command workflow such that the report is executed and exported to a csv in a pre-defined (variable) path. I was ... a script to run the report and export it, but could not locate information on that process.

asked Oct 28 by aweight (60 points)
3,548 questions
3,238 answers
8,232 comments
547,810 users