As all of you (NAV developers) already knows, Microsoft Dynamics NAV has a built-in job scheduler (Job Queue) useful if you want to schedule tasks like Codeunits or Reports. Job Queue is often used for managing long running tasks that you want to be executed periodically and in the background; on NAV, under the Departments/Administration/Application Setup/Job Queue/Job Queue Entries menu, you have a user interface for managing your tasks.
I’ve to admit that I’m not a big fan of NAV Job Queue. In my personal opinion, NAV Job Queue is not always so reliable and it’s more useful for scheduling tasks for an IT department of a customer. In many ERP implementations there’s instead the need for the partner (solution developer) to schedule complex NAV tasks that, for example, populates data for a BI system, perform calculations or data manipulations and so on. In these cases:
- I don’t want to have these tasks visible in Job Queue Entries
- I don’t want that external people (like the customer’s IT department) could start/stop/reschedule these tasks
- I don’t want that these tasks will depend on NAS
As a plus, there are scenarios where I would like to schedule a Task A and:
- If Task A is a success, the operation is complete
- If Task A fails, I would like to log the failure and I would like to start Task B (but only if Task A is failed).
A quick solution that permits to have a more “flexible” and reliable NAV Task Scheduler is using a scheduled Powershell script.
As an example, I’ve created a codeunit in NAV called My Task Scheduler (ID = 50001) and inside this codeunit I’ve created two different functions (Task1 and Task2) that will be executed:
I want to schedule this codeunit and, if one of these tasks fails (Task2 in this example), I want to log the error returned by NAV and I want to execute a new Task3 function in the codeunit called My Task Scheduler Restore I’ve created (ID = 50002):
Here is the Powershell script I’m using:
Import-Module ‘C:\Program Files\Microsoft Dynamics NAV\100\Service\Microsoft.Dynamics.Nav.Management.dll’
$Logfile = “C:\TEMP\$(gc env:computername).log”
Function WriteLogFile
{
Param ([string]$logstring)$Stamp = (Get-Date).toString(“yyyy/MM/dd HH:mm:ss”)
$logstring = $Stamp + ‘: ‘ + $logstringAdd-content $Logfile -value $logstring
}
try
{
Invoke-NAVCodeunit navostp -CodeunitId 50001 -CompanyName ‘EID’ -ErrorAction Stop
}
catch [Exception]
{
WriteLogFile “Error returned from NAV: $PSItem”
Invoke-NAVCodeunit navostp -CodeunitId 50002 -CompanyName ‘EID’ -ErrorAction Stop
}
In this script (executed on the NAV Service Tier):
- I create a function called WriteLogFile that writes a log file on the server file system. The log file is called <ServerName>.log.
- I call the Invoke-NAVCodeunit Powershell function to call my first codeunit
- I catch the returned exception from NAV and
- I log the error message returned from NAV on the log file (inside the catch block, there is an automatic variable ($PSItem or $_) of type ErrorRecord that contains the details about the exception).
- I start the codeunit 50002 (conditionally).
This Powershell script (NAVTaskScheduler.ps1) can be easily scheduled via Windows Task Scheduler as a normal windows task. The only thing to remember is that on the New Action window you’ve to set the parameters as follows:
- Action: Select “Start a program”.
- Program/script: Type in “powershell”.
- Add arguments (optional): Type the path to your script as the following:
-File “C:\NAVTasks\NAVTaskScheduler.ps1”.
You’re ready to go! Your NAV tasks will be up and running in a reliable and performant way…