How to Synchronously Run a Management Pack Task

Updated: January 31, 2012

Applies To: System Center 2012 - Operations Manager

Operations Manager anagement pack tasks can run in either a synchronous mode or an asynchronous mode. When a software development kit (SDK) client runs a task in a synchronous mode, the task runs in the client's thread. This requires the client to delay until the task is complete.

Example

The following example demonstrates how to synchronously run a task to get the names of rules and monitors that are running on a specific agent-managed computer:

/// <summary>
/// Synchronously runs a task to get a list of 
/// rules or monitors running on a specific agent-managed computer.
/// </summary>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Microsoft.EnterpriseManagement;
using Microsoft.EnterpriseManagement.Administration;
using Microsoft.EnterpriseManagement.Common;
using Microsoft.EnterpriseManagement.Configuration;
using Microsoft.EnterpriseManagement.Monitoring;
using System.Xml;
using System.Text;

namespace SDKSamples
{
	class Program
	{
		static void Main(string[] args)
		{
			ManagementGroup mg = new ManagementGroup("localhost");

			Console.WriteLine("Synchronously running a Management Pack task...");

			// Get the task.
			string query = "DisplayName = 'Show running rules and monitors for this health service'";

			ManagementPackTaskCriteria taskCriteria = new ManagementPackTaskCriteria(query);
			IList<ManagementPackTask> tasks =
				mg.TaskConfiguration.GetTasks(taskCriteria);
			ManagementPackTask task = null;
			if (tasks.Count == 1)
				task = tasks[0];
			else
				throw new InvalidOperationException(
					"Error! Expected one task with: " + query);

			// Get the agent class.
			query = "Name = 'Microsoft.SystemCenter.Agent'";
			ManagementPackClassCriteria criteria = new ManagementPackClassCriteria(query);

			IList<ManagementPackClass> classes = 
				mg.EntityTypes.GetClasses(criteria);
			if (classes.Count != 1)
				throw new InvalidOperationException(
					"Error! Expected one class with: " + query);

			// Create a MonitoringObject list containing a specific agent (the 
			// target of the task).
			string fullAgentName = "EnterFullyQualifiedAgentNameHere";
			List<MonitoringObject> targets = new List<MonitoringObject>();
			query = "DisplayName = '" + fullAgentName + "'";
			MonitoringObjectCriteria targetCriteria = 
				new MonitoringObjectCriteria(query, classes[0]);
			targets.AddRange(mg.EntityObjects.GetObjectReader<MonitoringObject>(targetCriteria, ObjectQueryOptions.Default));
			if (targets.Count != 1)
				throw new InvalidOperationException(
					"Error! Expected one target.");

			// Use the default task configuration.
			Microsoft.EnterpriseManagement.Runtime.TaskConfiguration config = new Microsoft.EnterpriseManagement.Runtime.TaskConfiguration();

			// Run the task.
			Console.WriteLine("Starting task \"" +
				task.DisplayName + "\" on the following target: ");
			foreach (MonitoringObject target in targets)
			{
				Console.WriteLine(target.DisplayName);
		}
			Console.WriteLine("Task started.");
			IList<Microsoft.EnterpriseManagement.Runtime.TaskResult> results = 
				mg.TaskRuntime.ExecuteTask(targets, task, config);
			if (results.Count == 0)
				throw new InvalidOperationException(
					"Failed to return any results.");

			// Display the task results.
			int resultNo = 0;
			foreach (Microsoft.EnterpriseManagement.Runtime.TaskResult res in results)
			{
				resultNo++;
				if (res.Status == Microsoft.EnterpriseManagement.Runtime.TaskStatus.Failed)
				{
					Console.WriteLine("Target #" + resultNo + " failed.");
					Console.WriteLine("Reason: " + res.ErrorCode.Value);
			}
				else
				{
					Console.WriteLine("Target #" + resultNo + " succeeded.");

					// Convert the task Output element from a string to XML.
					XmlDocument xmlDoc = new XmlDocument();
					xmlDoc.LoadXml(res.Output);

					// Parse and display the output.
					string xPathQry = @"/DataItem/Count";
					System.Xml.XmlNode countNode = xmlDoc.SelectSingleNode(xPathQry);
					Console.WriteLine("Target contains " + countNode.InnerText + " running rules or monitors.");
					xPathQry = @"//Workflow";
					System.Xml.XmlNodeList instanceList = xmlDoc.SelectNodes(xPathQry);
					int cnt = 0;
					foreach (System.Xml.XmlNode thisInstance in instanceList)
					{
						cnt++;
						Console.WriteLine(cnt.ToString() + ". " + thisInstance.InnerText);
				}
			}
		}
	}
}
}

See Also