none
Retrieving Runbook Returned Data After Starting A Runbook Job Through C# (See Code) RRS feed

  • Question

  • I am able to start my runbook from C# with no problems at all using the sample code below from MS (almost verbatim).  Using the code below does anyone know how to get the output (Returned Data) from the runbook?  I am assuming this involves using the direction == "Out" somehow.

    If the code below is garbled you can view it directly from :  http://msdn.microsoft.com/en-us/library/hh921685.aspx

    Thanks for the assistance.

    namespace CodeSample.Microsoft.SystemCenter2012.Orchestrator.WebService
    {
       using System;
       using System.Collections.Generic;
       using System.Linq;
       using System.Text;
       using System.Net;
       using System.IO;
       using System.Collections;
       using System.Data.Services.Client;
       using SCOService;
      
       public class RunbookOperations
       {
          public void StartRunbookWithParameters()
          {
             // Details of runbook that we are going to run.
             Guid runbookId = new Guid("00000000-0000-0000-0000-000000000000");
             Hashtable parameterValues = new Hashtable();
             parameterValues.Add("Param1","This is the value for Param1.");
             parameterValues.Add("Param2","This is the value for Param2.");
               
             // Path to Orchestrator web service
             string serviceRoot = "http://server01.contoso.com:81/Orchestrator2012/Orchestrator.svc";

             // Create Orchestrator context
             SCOService.OrchestratorContext context = new SCOService.OrchestratorContext(new Uri(serviceRoot));

             // Set credentials to default or a specific user.
             context.Credentials = System.Net.CredentialCache.DefaultCredentials;
             //context.Credentials = new System.Net.NetworkCredential("user", "pwd", "domain");

             // Retrieve parameters for the runbook
             var runbookParams = context.RunbookParameters.Where(runbookParam => runbookParam.RunbookId == runbookId && runbookParam.Direction == "In");
               
             // Configure the XML for the parameters
             StringBuilder parametersXml = new StringBuilder();
             if (runbookParams != null && runbookParams.Count() > 0)
             {
                parametersXml.Append("<Data>");
                foreach (var param in runbookParams)
                {
                   parametersXml.AppendFormat("<Parameter><ID>{0}</ID><Value>{1}</Value></Parameter>", param.Id.ToString("B"), parameterValues[param.Name]);                   
                }
                parametersXml.Append("</Data>");
             }

             try
             {
                // Create new job and assign runbook Id and parameters.
                Job job = new Job();
                job.RunbookId = runbookId;
                job.Parameters = parametersXml.ToString();

                // Add newly created job.
                context.AddToJobs(job);
                context.SaveChanges();

                Console.WriteLine("Successfully started runbook. Job ID: {0}", job.Id.ToString());
             }
             catch (DataServiceQueryException ex)
             {
                throw new ApplicationException("Error starting runbook.", ex);
             }
          }
       }
    }

    Wednesday, August 14, 2013 7:20 PM

Answers

  • I solved my own problem, I am sure there is an easier way to do this (especially how to wait until the SR is fully created before pulling it back).  I had to put the do loop in there as Service Manager took a while to actually create the service request and then even longer to populate the out parameter (in my case I return the Service Request ID).

    <See Rest of Code Above>

    // Add newly created job.
                context.AddToJobs(job);
                context.SaveChanges();

               ////////////////////////////////////////////////////////

               //////      RETREIVE THE JOB RETURNED DATA        //////

               ////////////////////////////////////////////////////////

                // Get the newly created Job ID (use it to find the output)

                Guid Jobid = job.Id;

                DataServiceQueryContinuation<RunbookInstance> nextRunbookInstanceLink = null;

                try

                {

                    // Retreive the runbook instance that we just created.  SM is a little slow so you may have to wait for it to be created first.

                    int Counter = 0;

                    while (NewServiceRequestID == "" && Counter <= 60)  // Keep looping until the Returned Data is present

                    {

                        // QUERY

                        RunbookInstance runbookInstance = (from rbkInstance in context.RunbookInstances

                                                           where rbkInstance.RunbookId == runbookId & rbkInstance.JobId == Jobid  // our Runbook ID and Job ID

                                                           orderby rbkInstance.CreationTime descending

                                                           select rbkInstance).FirstOrDefault();

                       

                       

                        // If the runbook instance is not yet created don't grab the parameters.

                        if (runbookInstance != null)

                        {

                            // Query for the parameters of the runbook instance (if the runbook instance was found)

                            IEnumerable<RunbookInstanceParameter> runbookInstanceParameters = context.RunbookInstanceParameters.Where(rip => rip.RunbookInstanceId == runbookInstance.Id);

                           

                            // Loop through each of the parameters to ensure the "Returned Data" (Out) was found.  If not wait and start again.

                            foreach (RunbookInstanceParameter runbookInstanceParameter in runbookInstanceParameters)

                            {

                                // DEBUGGING //

                                // ReturnStatus += "Runbook ID:  " + runbookId.ToString() + "  | Job ID:  " + job.Id.ToString() + "  | Runbook Parameter Direction:  " + runbookInstanceParameter.Direction.ToString() + " | Name:  " + runbookInstanceParameter.Name + " | Value:  " + runbookInstanceParameter.Value;

                               

                                // Return just the Service Request ID

                                if (runbookInstanceParameter.Direction.ToString() == "Out" & runbookInstanceParameter.Name.ToString() == "ServiceRequestID")

                                {

                                    NewServiceRequestID += runbookInstanceParameter.Value;

                                }

                            }

                        }

                        Counter += 1;

                        System.Threading.Thread.Sleep(1000);  // If the runbook instance or the out parameter was not found wait a seconda and loop

                    }

                    // If the counter ran out then apply an error message:  Otherwise it should equal the SR Number.

                    if (NewServiceRequestID == null || NewServiceRequestID == "")

                    {

                        NewServiceRequestID = "ERROR:  RunbookID:  " + runbookId + "  |  JobID:  " + Jobid;

                    }

                }

                catch (DataServiceQueryException ex)

                {

                    throw new ApplicationException("An error occurred during query execution.", ex);

                }     

            }

            catch (DataServiceQueryException ex)

            {

                throw new ApplicationException("Error starting runbook.", ex);

            }

                // Return the SR Number.

                return NewServiceRequestID;

        }

    // And HERE IS THE REST

     

     

    #endregion

    }

    }

     

    • Marked as answer by Robert Hydell Tuesday, August 27, 2013 11:42 AM
    Monday, August 19, 2013 7:16 PM

All replies

  • I solved my own problem, I am sure there is an easier way to do this (especially how to wait until the SR is fully created before pulling it back).  I had to put the do loop in there as Service Manager took a while to actually create the service request and then even longer to populate the out parameter (in my case I return the Service Request ID).

    <See Rest of Code Above>

    // Add newly created job.
                context.AddToJobs(job);
                context.SaveChanges();

               ////////////////////////////////////////////////////////

               //////      RETREIVE THE JOB RETURNED DATA        //////

               ////////////////////////////////////////////////////////

                // Get the newly created Job ID (use it to find the output)

                Guid Jobid = job.Id;

                DataServiceQueryContinuation<RunbookInstance> nextRunbookInstanceLink = null;

                try

                {

                    // Retreive the runbook instance that we just created.  SM is a little slow so you may have to wait for it to be created first.

                    int Counter = 0;

                    while (NewServiceRequestID == "" && Counter <= 60)  // Keep looping until the Returned Data is present

                    {

                        // QUERY

                        RunbookInstance runbookInstance = (from rbkInstance in context.RunbookInstances

                                                           where rbkInstance.RunbookId == runbookId & rbkInstance.JobId == Jobid  // our Runbook ID and Job ID

                                                           orderby rbkInstance.CreationTime descending

                                                           select rbkInstance).FirstOrDefault();

                       

                       

                        // If the runbook instance is not yet created don't grab the parameters.

                        if (runbookInstance != null)

                        {

                            // Query for the parameters of the runbook instance (if the runbook instance was found)

                            IEnumerable<RunbookInstanceParameter> runbookInstanceParameters = context.RunbookInstanceParameters.Where(rip => rip.RunbookInstanceId == runbookInstance.Id);

                           

                            // Loop through each of the parameters to ensure the "Returned Data" (Out) was found.  If not wait and start again.

                            foreach (RunbookInstanceParameter runbookInstanceParameter in runbookInstanceParameters)

                            {

                                // DEBUGGING //

                                // ReturnStatus += "Runbook ID:  " + runbookId.ToString() + "  | Job ID:  " + job.Id.ToString() + "  | Runbook Parameter Direction:  " + runbookInstanceParameter.Direction.ToString() + " | Name:  " + runbookInstanceParameter.Name + " | Value:  " + runbookInstanceParameter.Value;

                               

                                // Return just the Service Request ID

                                if (runbookInstanceParameter.Direction.ToString() == "Out" & runbookInstanceParameter.Name.ToString() == "ServiceRequestID")

                                {

                                    NewServiceRequestID += runbookInstanceParameter.Value;

                                }

                            }

                        }

                        Counter += 1;

                        System.Threading.Thread.Sleep(1000);  // If the runbook instance or the out parameter was not found wait a seconda and loop

                    }

                    // If the counter ran out then apply an error message:  Otherwise it should equal the SR Number.

                    if (NewServiceRequestID == null || NewServiceRequestID == "")

                    {

                        NewServiceRequestID = "ERROR:  RunbookID:  " + runbookId + "  |  JobID:  " + Jobid;

                    }

                }

                catch (DataServiceQueryException ex)

                {

                    throw new ApplicationException("An error occurred during query execution.", ex);

                }     

            }

            catch (DataServiceQueryException ex)

            {

                throw new ApplicationException("Error starting runbook.", ex);

            }

                // Return the SR Number.

                return NewServiceRequestID;

        }

    // And HERE IS THE REST

     

     

    #endregion

    }

    }

     

    • Marked as answer by Robert Hydell Tuesday, August 27, 2013 11:42 AM
    Monday, August 19, 2013 7:16 PM
  • Just what I was looking for, thanks for posting

    Warm Fuzzies!

    Tuesday, November 11, 2014 1:07 PM
  • Thank You!
    It helped me a lot.

    • Edited by ament Friday, July 24, 2015 12:19 PM
    Friday, July 24, 2015 12:18 PM
  • Geate code, thanks! 

    Karol Kozłowski

    Friday, July 15, 2016 10:37 AM
  • Direction never comes back == "Out".  Always "In".  Any thoughts?
    Wednesday, April 26, 2017 8:51 PM