Running Tasks

I've had some questions regarding how to run tasks via the SDK so I thought I would post an example here. The code below shows the various ways of executing tasks in the SDK. The underlying implementation relies on query notifications from SQL 2005 to notify us whenever the status of a particular batch changes; we actually register a new notification for every batch, but since the format of the notification is the same and only parameters change, the performance is not overly affected.

The code is pretty self-explanatory. I don't recommend using the synchronous version of the API because if something unexpected happens to the task your application will be stuck on the call until it times out (30 minutes) OR if you actually expect your task to take longer than 30 minutes, this version will timeout prior to your task completing. Also, if you don't care about getting notified of the results immediately, you can use the SubmitTask(s) API without providing a callback and simply query for results at a later time using the batch id you get from the call and the GetMonitoringTaskResults method available on both ManagementGroup and MonitoringObject.

using System;

using System.Collections.ObjectModel;

using Microsoft.EnterpriseManagement;

using Microsoft.EnterpriseManagement.Configuration;

using Microsoft.EnterpriseManagement.Monitoring;

 

namespace Jakub_WorkSamples

{

    partial class Program

    {

        static void RunningTasks()

        {

            // Connect to the local management group

            ManagementGroup mg = new ManagementGroup("localhost");

 

            // First lets get the task we are going to execute

            // Note: Indexing the result like this is not necessarily the best

            // practice here, since there could be more than one task with this

            // name.

            MonitoringTaskCriteria taskCriteria = new MonitoringTaskCriteria(

                "Name = 'Microsoft.SystemCenter.GetAllFailedWorkflows'");

            MonitoringTask failedWorkflowTask =

                mg.GetMonitoringTasks(taskCriteria)[0];

 

            // Configuration allows you to specify credentials to use different

            // from the default. It also allows you to specify overrides, if

            // any are available

            MonitoringTaskConfiguration failedWorkflowTaskConfiguration =

                new MonitoringTaskConfiguration();

 

            // Now we need to get an instance of a health service

            // First get the class

            MonitoringClass healthServiceClass =

                mg.GetMonitoringClass(SystemMonitoringClass.HealthService);

           

            // Next get the object (we'll just pick the first one)

            MonitoringObject healthServiceObject =

                mg.GetMonitoringObjects(healthServiceClass)[0];

 

            // Object centric task execution

           

            // Synchronous

            ReadOnlyCollection<MonitoringTaskResult> results =

                healthServiceObject.ExecuteMonitoringTask(failedWorkflowTask,

                failedWorkflowTaskConfiguration);

 

            // Asynchronous (standard .Net implementation)

            IAsyncResult asyncTaskResult =

                healthServiceObject.BeginExecuteMonitoringTask(

                failedWorkflowTask,

                failedWorkflowTaskConfiguration,

                null, // You can specify a callback

                null); // And additional context

 

            results = healthServiceObject.EndExecuteMonitoringTask(asyncTaskResult);

 

            // Asynchronous (more advanced SCOM specific implementation)

            Guid batchId = healthServiceObject.SubmitMonitoringTask(failedWorkflowTask,

                failedWorkflowTaskConfiguration,

                MyTaskCallback);

 

            // Task execution off ManagementGroup (for multiple targets)

            PartialMonitoringObject[] targets =

                new PartialMonitoringObject[] { healthServiceObject };

 

            // Synchronous

            results = mg.ExecuteMonitoringTask(targets, failedWorkflowTask,

                failedWorkflowTaskConfiguration);

 

            // Asynchronous (standard .Net implementation)

            asyncTaskResult =

                mg.BeginExecuteMonitoringTask(

                targets,

                failedWorkflowTask,

                failedWorkflowTaskConfiguration,

                null, // You can specify a callback

                null); // And additional context

 

            results = mg.EndExecuteMonitoringTask(asyncTaskResult);

 

            // Asynchronous (more advanced SCOM specific implementation)

            batchId = mg.SubmitMonitoringTask(targets,

                failedWorkflowTask,

                failedWorkflowTaskConfiguration,

                MyTaskCallback);

 

            // Wait for the task to complete

            System.Threading.Thread.Sleep(5000);

        }

 

        private static void MyTaskCallback(Guid batchId,

           ReadOnlyCollection<MonitoringTaskResult> results,

           bool completed)

        {

            if (completed)

            {

                Console.WriteLine("Batch Id {0} is done!", batchId);

            }

        }

    }

}

Comments

  • Anonymous
    June 27, 2007
    The comment has been removed

  • Anonymous
    June 27, 2007
    The UI usually queries using Name = 'blah' OR DisplayName = 'blah'. If you know which the name is, you can exclude the other. If there is a space, it is for sure the Name, but otherwise it could be either.

  • Anonymous
    June 27, 2007
    I found that , if the task in dbo.task , I can get it , if it is in dbo.ConsoleTask , I cannot get it ? Right?

  • Anonymous
    June 27, 2007
    For console task use GetMonitoringConsoleTasks. Also in my previous comment I meant that if there is a space it is for sure the DISPLAY Name.

  • Anonymous
    March 27, 2015
    Great Article By the Way.  I am using SCOM 2012 and trying to call a task ASYNC which works fine but I cannot seem to be able to grab the SCOM BatchId and ManagementGroup from the IAsyncResult (even though I can see it in the debug visualizer).   Any suggestions on how I can get the BatchId and ManagementGroup while still calling the task asynchronously?  Thanks in advance for your help IASyncResult Result = mgManagementGroup.TaskRuntime.BeginExecuteTask(moSCOMTargets, mptSCOMTask, tcTaskConfiguration, null, null)

  • Anonymous
    April 01, 2015
    The comment has been removed

  • Anonymous
    April 03, 2015
    The comment has been removed

  • Anonymous
    April 05, 2015
    Hi, Jakub Thank you for the quick reply. I have one more question. Can you tell how to configure to specify credentials to use instead of default. Thank you

  • Anonymous
    April 05, 2015
    You can set it as part of the configuration you submit: msdn.microsoft.com/.../hh327529.aspx

  • Anonymous
    April 06, 2015
    Hi, Jakub Since "TaskCredentials" is abstract, cannot directly assign as instance.Credentials = value. Is there any other possible ways to do this. Thank you

  • Anonymous
    April 07, 2015
    You want this one: msdn.microsoft.com/.../hh327756.aspx