Script Repository


Schedule changes to be made at later date

July 28, 2020
1786

The scripts allow you to schedule certain changes to be made to an AD object to a later date. To implement the scripts in your environment, you need to:

  1. Add a property for specifying dates to the Web Interface forms used for creating and editing objects. The property will be used to specify a date when to make the changes in Active Directory.
  2. Create a Business Rule triggered before creating or updating an AD object that will send an operation for approval to a Scheduled Task.
  3. Create a Scheduled Task that will approve operations on the dates specified for them.

1. Add property for specifying a date to Web Interface forms

For information on how to add properties to Web Interface forms, see Customize Forms for User Creation and Editing, step 6. We recommend using one of Adaxes Custom Attributes that allows storing date/time values, for example, CustomAttributeDate1. Such attributes are not stored in AD, but can be used the same as any other attributes of AD objects.

2. Create Business Rule to send operation for approval

Create a Business Rule triggered before creating or updating an AD object that will send the operation for approval. For example, to schedule changes to existing user accounts, create a Business Rule triggered before updating a user. The Business Rule must execute the below script if the date specified in the Custom Attribute is set in the future.

Sample Business Rule:

Parameters:

  • $scheduledTaskName - specifies the name of the Scheduled Task that you will create on step 3;
  • $dateAttribute - specifies the name of the custom attribute you added on step 1.
Edit Remove
PowerShell
$scheduledTaskName = "Delayed Modification Task" # TODO: modify me
$dateAttribute = "adm-CustomAttributeDate1" # TODO: modify me

function FindObjects($filter, $basePath, $propertiesToLoad)
{
    $searcher = $Context.BindToObject($basePath)
    $searcher.SearchFilter = $filter
    $searcher.SearchScope = "ADS_SCOPE_SUBTREE"
    $searcher.PageSize = 500
    $searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
    $searcher.SetPropertiesToLoad($propertiesToLoad)
    
    try
    {
        $searchResultIterator = $searcher.ExecuteSearch()
        $searchResults = $searchResultIterator.FetchAll()

        return ,$searchResults
    }
    finally
    {
        # Release resources
        if ($searchResultIterator){ $searchResultIterator.Dispose() }
    }
}

# Find the Scheduled Task
$scheduledTasksPath = $Context.GetWellKnownContainerPath("ScheduledTasks")
$searchResults = FindObjects "(&(objectCategory=adm-ScheduledTask)(name=$scheduledTaskName))" $scheduledTasksPath @("distinguishedName", "objectGUID")

if ($searchResults.Length -gt 1)
{
    $Context.LogMessage("Found more than one Scheduled Task with name '$scheduledTaskName'.", "Error")
    return
}
if ($searchResults.Length -eq 0)
{
    $Context.LogMessage("Scheduled Task '$scheduledTaskName' does not exist.", "Error")
    return
}

# Get property name
$propertyList = $Context.Action.PropertyList
for ($i = 1; $i -le 30; $i++)
{
    try
    {
        $item = $propertyList.GetPropertyItem("adm-CustomAttributeText$i", "ADSTYPE_CASE_IGNORE_STRING")
    }
    catch
    {
        $propertyName = "adm-CustomAttributeText$i"
        break
    }
}

if ($NULL -eq $propertyName)
{
    $Context.Cancel("All the attributes allowed for storing the date are used in the operation.")
    return
}

# Get date
$date = $Context.GetModifiedPropertyValue($dateAttribute)
$dateString = $date.ToString("dd\/MM\/yyyy")
$randomGuid = [Guid]::NewGuid()

# Create a property value
$propertyValue = New-Object "Softerra.Adaxes.Adsi.AdsPropertyValue"
$propertyValue.CaseIgnoreString = "{$randomGuid} $dateString {$randomGuid}"
$propertyValue.ADsType = "ADSTYPE_CASE_IGNORE_STRING"

# Create a property entry
$propertyEntry = New-Object "Softerra.Adaxes.Adsi.AdsPropertyEntry"
$propertyEntry.Name = $propertyName
$propertyEntry.Values = @([Softerra.Adaxes.Interop.Adsi.Cache.IADsPropertyValue]$propertyValue)
$propertyEntry.ControlCode = "ADS_PROPERTY_DELETE"
$propertyEntry.ADsType = "ADSTYPE_CASE_IGNORE_STRING"

# Add date in the format suitable for the Scheduled Task
$propertyList.ResetPropertyItem($dateAttribute)
$propertyList.PutPropertyItem($propertyEntry)

# Create Approval Request
$scheduledTaskDN = $searchResults[0].Properties["distinguishedName"].Value
$Context.SubmitForApproval(@($scheduledTaskDN), $False, $False, $False, $False)

3. Create Scheduled Task to approve operations

To approve the requests on the dates specified for them, create a Scheduled Task for the Domain-DNS object type that runs the below script. The name of your task must be exactly the same as you specified in $scheduledTaskName on step 2.

Edit Remove
PowerShell
# Get all pending Approval Requests
$containerPath = $Context.GetWellKnownContainerPath("ApprovalRequests")
$container = $Context.BindToObject($containerPath)

$requests = $container.GetApprovalRequests("ADM_APPROVALSTATE_PENDING")

foreach ($requestID in $requests)
{
    # Bind to the Approval Request
    $guid = [Guid]$requestID
    $request = $Context.BindToObjectEx("Adaxes://<GUID=$guid>", $True)
    
    $approversInfo = $request.GetApproversInfo()
    if (-not ($approversInfo.IsApproverEx($Context.Initiator.UserAdsObject, $request.Requestor, $request.TargetObject)))
    {
        continue # The Scheduled Task is not an approver
    }
    
    # Get date when modifications are due
    $operation = $request.DescriptionOfOperationToApprove
    $result = $operation | Select-String -Pattern "(?<=\{.{8}-.{4}-.{4}-.{4}-.{12}\}\s)\d{2}\/\d{2}\/\d{4}(?=\s\{.{8}-.{4}-.{4}-.{4}-.{12}\})"

    if ($result -eq $NULL)
    {
        $Context.LogMessage("Cannot find a date when to execute the following operation: '$operation'.", "Warning")
        continue
    }
    
    try
    {
        $date = [Datetime]::ParseExact($result.Matches[0].Value, "dd/MM/yyyy", $NULL)
    }
    catch
    {
        $Context.LogMessage("Cannot convert a date when to execute the following operation: '$operation'.", "Warning")
        continue
    }
    
    if ($date -gt [System.Datetime]::UtcNow)
    {
        continue
    }
    
    # Approve the request
    $request.Approve()
}


Comments ( 2 )
avatar
Tom Whalen - RIHousing
Aug 11, 2020
I am trying this right now but instead of on an user update, i am doing it on the user create. No matter what I try i keep getting "cannot find a date when to execute the following operation"
avatar
Support
Aug 12, 2020

Hello Tom,

 

For troubleshooting purposes, please, send us (support[at]adaxes.com) screenshots of the Business Rule and the Schedule Task that you configured along with the scripts used in the rule and the task in TXT format.

Leave a comment