0 votes


You have previously advised that scheduled tasks run on the instance that they were first created on, and only if that instance is unavailable will it promote another one.

Two/three questions:-

We are looking at implementing a dedicated instance to run background scheduled tasks (especially as you know we have a growing number of custom scripted jobs). Is there any way to 're-assign' existing jobs to this new serveras their primary instance (other than completely deleting them and re-creating that we'd rather not, if possible)?

For non-script jobs where we do not have the opportunity to manually point to alternative instances in the script file, is there anyway to get them to offload to a specific instance (this is less important - generally it's anything that we've scripted ourselves that we'd like to be able to point away from the local instance).

And, out of interest, if, for example, we turn off the WAN between our Live and DR sites (which we do for DR scenario testing) and a scheduled task runs, would it run on both the Live and DR servers (our 2 current instances)?

by (11k points)

Sorry - one more, different technical subject, but same realm.

We've been tweaking the IIS settings to maximise UI performance (not that we're having any material issues, just trying to make it as smooth as possible).

As part of this we tried moving our two main portals (User Self Service and IT Operations) into separate AppPools, but found that if a user had both open that there were causing constant logouts i.e. doing anything in one caused the other to logout.

Generally each would be a separate tab in the same browser window, and we don't currently enable Kerberos auth (and we when do it will be for the SelfService portal only).

Is this expected behaviour?

1 Answer

0 votes
by (215k points)


Scheduled Task question
By default, a Scheduled Task is owned and executed on the instance that it was created on. So, if you want a specific Scheduled Task to be executed by a specific Adaxes instance in a configuration set, you need to delete it and recreate on the Adaxes service you need. However, keep in mind that if that Adaxes service goes down for a long time for some reason, another Adaxes service in the configuration set will take ownership of that Scheduled Task. Currently, there is no functionality in Adaxes to change this behavior.

As to breaking the connection between services in a configuration set, keep in mind that another Adaxes service will not take ownership of a Scheduled Task right at the time when the connection breaks. Usually, it takes about two hours before another Adaxes service takes ownership of a Scheduled Task of another service.

Web Interface issue
Actually, this is how the ASP.NET Forms Authentication works. We've assigned our Web Interface programmers the task to investigate whether it is possible to tweak the mechanism and allow being logged in to two Web Interface types simultaneously. If they find a way how to do this, we'll fix this behavior in one of our nearest releases.



  1. Yes, the FilterBuilder class is a helper class in Adaxes that helps to build LDAP filters requiring a special format. A good example of such filters are filters that search by a certain binary property, for example, GUID.

    If you are going to build LDAP filters in your scripts, we think the following article by Microsoft will help you to better understand the LDAP filter format: Active Directory: LDAP Syntax Filters.

  2. If you mean the foreach loop that starts with foreach ($requestID in $requests), we actually wanted to make sure that we handle all the approval requests that match the search criteria. Now, after a second thought, we understand that if there are multiple Approval Requests generated by the Scheduled Task for the same user, it is probably some error / undesired behavior. We've changed the script a bit so that it handles situations when there is 1 Approval Request and when there are several Approval Requests differently. We've also left a TODO for you there so that you can decide for yourself, what the script should do if there is more than one Approval Request.

  3. The first method that you tried is missing a line. It should be something like:

     $approvalGuidInByte = $request.Get("objectGUID")
     $approvalGuid = New-Object "System.Guid" (,$approvalGuidInByte)
     $approvalGuidInByteString = $approvalGuid.ToString("D")

    However, it involves binding to the AD object that represents the Approval Request. As we've already mentioned, it can sometimes be an expensive operation and requires extra calls.

    The second method that you tried is a good alternative, however, you should always remember that when using the method you should fetch the required properties in the search. That is, you need to set the properties as the properties that should be loaded using the SetPropertiesToLoad method of the searcher object. Otherwise, any attempt to get the properties will fail as the properties are not fetched and thus not present in the property cache.

    We've modified the script to use the second method that you tried (as it is much faster) and have set the objectGUID property as a property that should be fetched when searching for Approval Requests.

Also, we've found one more place where we can optimize the script a bit. The thing is that in the previous version of the script the necessary Scheduled Task was specified by the Task name. With this approach, the script execution always started with searching for the DN of the Scheduled Task to be able to bind to it and get the Task GUID. However, if the DN of the Scheduled Task is specified directly in the script, we can skip searching for the Task DN and thus save one call to the AD. This will help to make the script faster a bit.

So, to summarize, the following changes have been made to the task:

  1. Introduced different behavior when there is more than one Approval Request for a certain Subordinate and left a TODO for you so that you can decide what the script will do when there is more than one Approval Request.
  2. The Approval Request GUID is now returned by the search.
  3. The Approval Request GUID returned by the search can now be converted to a string so that you can use it in a URL.
  4. The Scheduled Task is now specified not by the Task name, but by the Task Relative Distinguished Name (RDN) in order to construct the task DN and avoid searching for the Task each time the script runs.

Here's the text of the script:

$scheduledTaskRdn = "CN=Account Review - Users" # TODO: modify me

    $subordinateDNs = $Context.TargetObject.GetEx("directReports") | sort-object
    $subordinateDNs = $NULL

if ($subordinateDNs -ne $NULL)
    # Get Scheduled Task 'Account Review - Users' GUID
    $scheduledTasksContainerPath = $Context.GetWellKnownContainerPath("ScheduledTasks")
    $scheduledTasksContainerPathObj = New-Object "Softerra.Adaxes.Adsi.AdsPath" $scheduledTasksContainerPath
    $scheduledTaskPath = $scheduledTasksContainerPathObj.CreateChildPath($scheduledTaskRdn)

    $scheduledTask = $Context.BindToObject($scheduledTaskPath)
    $scheduledTaskGuidInByte = $scheduledTask.Get("objectGUID")
    $scheduledTaskGuid = [Softerra.Adaxes.Ldap.FilterBuilder]::Create("adm-ApprovalRequestorGuid", $scheduledTaskGuidInByte)

    foreach ($subordinateDN in $subordinateDNs)
        if ($subordinateDN -like "*CN=Users,DC=root,DC=net") # This is a fudge fix to stop references to the AD root domain causing errors
            $subordinateDN = "'root' DN trapped and excluded"
            $context.LogMessage($subordinateDN, "Warning")


        $subordinate = $Context.BindToObjectByDN($subordinateDN)
        $reviewDate = $subordinate.Get("adm-CustomAttributeDate1").ToString("dd/MM/yyy")
        $reviewStatus = $subordinate.Get("adm-CustomAttributeText4")

        if ($reviewStatus.startsWith("Review In Progress"))
            $searchFilter = "(&(objectCategory=adm-ApprovalRequest)(adm-ApprovalState=0)$scheduledTaskGuid"

            $objectGuidInByte = $subordinate.Get("objectGUID")
            $objectGuid = [Softerra.Adaxes.Ldap.FilterBuilder]::Create("adm-TargetObjectGuid", $objectGuidInByte)
            $searchFilter += "$objectGuid)"

            $containerPath = $Context.GetWellKnownContainerPath("ApprovalRequests")

            $searcher = New-Object "Softerra.Adaxes.Adsi.Search.DirectorySearcher" $NULL, $False
            $searcher.SearchParameters.BaseObjectPath = $containerPath
            $searcher.SearchParameters.PageSize = 500
            $searcher.SearchParameters.SearchScope = "ADS_SCOPE_SUBTREE"
            $searcher.SearchParameters.Filter = $searchFilter
            $searcher.SearchParameters.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"

            $searcherResult = $searcher.ExecuteSearch()
            $requests = $searcherResult.FetchAll()

            if ($requests.Count -eq 1)
                $requestGuidInByte = $requests[0].Properties["objectGUID"].Value
                $requestGuid = New-Object "System.Guid" (, $requestGuidInByte)
                # TOOD: Some code to handle situations when there is more than one Approval Request for the current subordinate

In the script, $scheduledTaskRdn specifies the Scheduled Task Distinguished Name relative to the Scheduled Tasks container. For example, if your Scheduled Task is called Account Review - Users, and it is located directly in the Scheduled Tasks container, you should specify CN=Account Review - Users.


By the way, we've decided to include some of the features that you requested in our next release. The following features requested by you will be available starting from Adaxes 2013.2:

  1. If several Adaxes services share common configuration, you will be able to explicitly specify the service that runs a Scheduled Task.
  2. The Scheduled Tasks that are currently running will be highlighted in the Console Tree pane of Adaxes Administration Console.
  3. If you select a Scheduled Task that is currently running, you will be able to see for how long it has been running in the Result Pane (located on the right).

Thanks very much, and the 2013.2 scheduled task management features sound perfect!

One thing that did occur to me re: the script - and this is a generic statement for anyone who may use it as a basis for their own custom actions, and also ties into the approval queue filters you're going to add in the web UI in a later release.

Currently we use the clickable link to point directly to the (single) approval ticket that applies to the review for the object. However, it could easily be adjusted so that the script (for example) locates all requests for users to be added to a group (so the ForEach loop etc would be expected to pull back multiple entries).

Therefore, if your new web UI supports the queue filter settings being passed as a URL variable, it should be possible to construct a link that when selected drops them directly into their approval queue and pre-filters the page so that they are only looking at the approval requests that apply to that object etc.



In our new Web Interface it will be possible to filter objects, and we'll think on a way how to pass filters in URLs. It should be quite easy to implement. Thanks for the suggestion!



Today we released Adaxes 2013.2. Starting from this version, you can:

  1. Explicitly specify an Adaxes service that runs a Scheduled Task in a configuration set and disallow reassigning it to another service;
  2. See, which Scheduled Tasks are currently running (they are now displayed in bold in the Console Tree of the Administration Console);
  3. See, how long a Scheduled Task is running and stop it, if necessary.

You can download the new version here.

Upgrade Instructions.

For a complete list of new features and improvements, see What's New.

Related questions

0 votes
1 answer

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 ... Exclude = $False $scopeItem.SetInfo() $task.ActivityScopeItems.Add($scopeItem) $task.SetInfo() }

asked Apr 1 by Staj (1.8k points)
0 votes
1 answer

Hello After adding or removing users (from WebUI) from certaing sec. groups, I let a Business Rule execute two Scheduled Tasks, as shown in this http://www.adaxes.com ... a user via the Adaxes Administration Console throws the same error. - Thanks in advance.

asked Jan 22, 2016 by Boxx.dk (11.9k points)
0 votes
1 answer

Hi, I need to execute custom commands on a quarterly and yearly base, Is it possible to achieve that within Adaxes? Maybe with a scheduled task? kind regards Ingemar

asked Sep 21, 2015 by ijacob (6.1k points)
0 votes
1 answer

Hi Forum, is it possible in a Multi Server Setup to define One Server for scheduled Tasks? How does Adaxes choose the server executing the tasks? Thanks for your help Cheers

asked Jul 20, 2015 by esoAdxAdmin (3.6k points)
0 votes
1 answer

hi- I am setting up a scheduled task that will disable expired accounts and move them to a specific OU. I'd also like to send the results to my manager. Would including ... disabled and moved or is there a another attribute that will display it in a nicer way?

asked Jan 21, 2014 by MeliOnTheJob (10.6k points)
2,466 questions
2,215 answers
335,371 users