4

One of the frequent problems that I have seen with Sitecore is the inability to control the exact time that a scheduled task should run. Since the machine's clock will be far more accurate, what I would like to do is call Sitecore from a Windows Scheduled Task.

I assume that I am going to need to set up a WebApi endpoint for the Windows Task to call, but how do I write/setup a Windows task to call it? Am I able to make the endpoint accept POST requests, or just GET?

4 Answers 4

4

The built-in Sitecore scheduler can certainly be frustrating in its limitations.

So using a WebApi endpoint that the task can call is certainly one way of doing things. You should keep security in mind though; if your URL can easily be guessed and doesn't require authentication then anonymous users can potentially trigger it. You should definitely consider some kind of access control (e.g. credentials, tokens, IP restriction).

You have a couple of options for triggering it. Off the top of my head, you could install a windows port of curl and use that, you could write your own console application, or you can use PowerShell. My preference would be the latter. You can easily create a simple script as follows:

$url = "http://www.example.com"
$request = [System.Net.WebRequest]::Create($url)
$response = $request.GetResponse()
$response.Close()

Then you set up the scheduled task to execute your PowerShell script. That will fire off the request to your server.

The thing you need to be careful of with this is that web requests can time out; and this can cause your tasks to register as failed. You can execute the task on a separate thread, but this means you can no longer return failure codes to the scheduler.

In my opinion, a better option would be to use the Sitecore Powershell Extensions module, and then use the remoting feature to connect and invoke your job on the server. You can then wait on the job, which means that you shouldn't have to work around timeout problems.

4
  • I agree that SPE would be a great option. Check out the page here for more details. sitecorepowershell.gitbooks.io/sitecore-powershell-extensions/… Commented Nov 1, 2016 at 22:50
  • @MichaelWest, are you sure that you're not just a little bit biased? ;) I was actually thinking that there had to be a SPE solution. Do you think you could provide a solution for how I could do this? I'm still ramping up on SPE and I didn't see what I was looking for in the docs. Commented Nov 1, 2016 at 23:00
  • If you look at the linked page about remoting, there's a section titled "Advanced Script Sessions". The first example about re-building the links database should serve as a starting point for you. Just replace the bit inside the remote script block with what you want to do. :)
    – Matt
    Commented Nov 1, 2016 at 23:17
  • Thanks, Matt! I was just skimming through that page and I think I missed that one Commented Nov 1, 2016 at 23:20
5

Here is a low complexity example using Sitecore PowerShell Extensions.

Make sure that the SPE Remoting Module files are saved to a path configured in $env:PSModulePath.

Save script to desired path:

Import-Module -Name SPE
$session = New-ScriptSession -Username "admin" -Password "b" -ConnectionUri "http://remotesitecore/"
Invoke-RemoteScript -ScriptBlock {
    # See Import-Function and Invoke-Script for more examples
    Get-ChildItem -Path "master:\" | Measure-Object
} -Session $session 
Stop-ScriptSession -Session $session

Setup scheduled task:

  • Start program C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
  • Argument "PATH_TO_SCRIPT\[SCRIPT_NAME].ps1"

You can find more details here. We also have a Web API feature that doesn't require using a password since it relies on what is published. Documentation here.

0
1

You can decorate your WebApi endpoint method with [HttpPost]. When you post to the WebApi and there's a matching route for your request it will invoke that method. I don't have a code example at hand but I'll see if I can find one. Otherwise have a look here https://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

That being said I think the most common way to achieve this is to set a Sitecore scheduled task to run very frequent and then abort the task if the server time is not in your desired time interval. I.e. you would have a configuration item associated with your Sitecore scheduled task and in your task you would check against that configuration item to see if it should be allowed to run. And also check against the scheduled task's time stamp to see when it was last run so it doesn't fire twice within your interval. But if you want to control the exact time, the Windows task/WebApi solution is the way to go.

1
  • I would like to avoid running a Scheduled Task 1440+ times/day (1+ per minute), and the keyword in the OP is that I am looking for a way to control the exact time that the task executes. I could go the "binary search route", but it's really not what I'm looking for. Thanks for your answer, though. It might help someone else with a different situation. Commented Nov 1, 2016 at 22:55
1

How do I write/setup a Windows task to call it?

I would recommend using something like Hangfire. (http://hangfire.io)

They support a cron-based scheduling for re-occurring tasks. Check their official doc: http://docs.hangfire.io/en/latest/background-methods/performing-recurrent-tasks.html

This can be easily configured for use in the Windows Service.

Am I able to make the endpoint accept POST requests, or just GET?

You can configure a standard ASP.net MVC web API 2 for that. It is quite easy with lots of examples from Microsoft. (https://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api)

Very important thing is: if you consider using standard MVC routing, make sure that your route doesn't conflict with default Sitecore routes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.