System Center Orchestrator 2012 – Error Handling and Using Data in the Data Bus BETWEEN Runbooks

I will re-iterate a statement I’ve made before.  I don’t believe in re-inventing the wheel.  Before I found “Designing Orchestrator Runbooks“, I found that doing error handling using the brief bit of info I learned from the class and the other books I purchased was, frankly, a big pain.  I dropped everything I was testing with to go with the examples starting on page 36 of the book.

It takes quite a bit of thinking and experimentation with Orchestrator before you really get into how to use the tool and leverage it well.  The error handling examples are no different and they give you quite a bit of flexibility and value with your runbooks.  The examples also help clearly illustrate how to pass data between runbooks using the data bus.

I invite you to download a free copy of Designing Orchestrator Runbooks, turn to page 36 and start experimenting!

To expand on their information and also illustrate how the data bus is used, let me give you an example.  Recall that in my last blog post, from earlier this morning, I was invoking a runbook to run a report and email it.  This was done through an initiation runbook which generated a random server from a PowerShell script and used that generated server name with the invoke runbook activity.  I will show you that runbook and then an error handling runbook.

NOTE:  It is important to sit down, read through the information in Designing Orchestrator Runbooks, decide what works for you in your environment and then PLAN IT OUT and DOCUMENT it.  If you are going DNRY (Do Not Repeat Yourself) you are establishing some standards here that will be used consistently and repeatedly in all your runbook error handling.  Make sure you have everything the way you want it.  You must create your error handling runbook FIRST.  It should be present before you add an invoke runbook activity.  You have to have a road built before you can drive on it…

Runbook 1 – Error Handling


When you create your error handling runbook, you are setting the foundation for any and all data you think you would like to see in order to record errors and help indicate what problems might exist to assist in troubleshooting.

Create your variables and set their types:


Now, what do you want to do with it?  I’m emailing my data to a distribution list and writing them to the event log (event log example shown below):


That’s pretty much it for the error handling.  Now let’s get on with how to use it.

Runbook 2 – generate report and email it.  In our second runbook, we don’t care much about anything except our links and the invoke runbook activities


I have two links.  One links to an email activity, that link is utilized if my script runs ok.  If there’s an error with the script, then that link is followed.  Below is the properties of the “error” link


Notice I have two invoke runbook activites.  Both invoke runbook activities have a link with the same filters (as shown in the previous screen shot).

Both of these invoke runbook activities link to the same “Error Handling” runbook.

Now, here is where things get a bit interesting.  In your invoke runbook activity, I want to create multiple parameters.


A bit of explanation here.  I am adding parameters with names that MATCH the initialize data strings I set up in my error handling runbook.  The VALUES for these parameters are as follows:

RunbookName – subscribe to data, the runbook name from the previous activity, “Run PowerShell Script”.  What I want here is, if the script error-ed, what is the name of the runbook where this error was generated from?

ErrorMesage – subscribe to data, the error summary text from the previous activity, “Run PowerShell Script”.   What I want here is, if the script error-ed, what was the text of the error, the error message?  (if you read on in the book, they explain further how to include PowerShell error handling to the data bus as well.  So, if there’s an error WITHIN the script, you can subscribe to that too if you desire.  This only subscribes to an error message generated by the ACTIVITY, not an error in the script).

EmailAddress – subscribe to data, the global variable for my distribution list or email address of where the error should g0

Trace – I’m error handling within my script, that data is written to a temp file, so that information is being passed back via the variable “ErrorFile”.  This will become an attachment in my email or passed to the event log

Runbook – subscribe to data, the runbook name from the previous activity, “Run PowerShell Script”.  What I want here is, if the script error-ed, what server did it error out on?

ActivityName – subscribe to data, the name of the activity from the , “Run PowerShell Script”.  What I want here is, if the script error-ed, which activity did the error originate?

ActivityStatus – subscribe to data, the status of the activity from the , “Run PowerShell Script”.  What I want here is the status of the activity (failed, warning, etc).


Now, rinse and repeat for subsequent activities.  So, example, if my “Send Email” activity succeeds, well, that’s it.  It succeeds do nothing more.  If my “Send Email” activity fails, then invoke the “Error Handling” runbook and pass all that data to that runbook so it can use it to send an email about what my activity failed and also write to the event log on the server.

Selecting a Random Runbook Server – Part 2 – a Closer Look

It’s been quite a while since my last post.  I’ve had several people email me and ask for a closer look at selecting a random runbook server.

A bit of a review, refer to the previous post for reference.  But, I was curious about how you could genuinely select a RANDOM server rather than rely on a “primary” and or “secondary” that were “static”.  (Please read the disclaimer at the bottom of this post)

Since this is a closer look, I’ll try to keep things simple and include screen shots.

I will show you how to subscribe to and use data within the data bus.

First, a bit of design explanation.  For simplicity, there are two runbook servers.  Their names are “SCORCH01” and “SCORCH02”.  Tying into Jon Mattivi’s post, we will create two variables.

Here’s an example of creating the first variable “RBServer1”.


You should now have two variables as in the example below:



I have an initiation runbook that starts another runbook.  For an explanation of what an initiation runbook folder is, download this free book “Designing System Center Runbooks“from Microsoft.

The other runbook is invoked from the initiation runbook that runs a PowerShell script, queries groups for members, creates a report and emails it to a distribution list.

For the purpose of this blog post, we don’t care about the contents of the runbook that generates a report so that won’t be discussed.

I want to point something out here.  My initiation run book is NOT using a random server!  What I want to do is edit the properties of the runbook so that I am overriding the default roles and I add any and all servers I want to be able to run this.  The top server listed is the primary.  If the primary isn’t available, then the secondary is used.

Here is a screen shot showing the properties of my initiation runbook.  click the “Runbook Servers” tab, then override and select your servers to use when this RB runs.



The initiation runbook looks like this:


The activity “Run .Net Script” titled “Generate Random RB Server” is our primary focus here.

Type in your PowerShell script:


$RBServer = ($Server = “”,””) | Get-Random.


Now, you could add the data to subscribe the data.  The easy way is to RIGHT click and subscribe to the data.  So, as you type in the script after the first double quotes, right click the mouse.  Then, select your first variable.  Add the closing double quotes, then the comma, then the double quotes again, right click, subscribe, then close double quotes then right parenthesis.

That will give you this:


Now, DO NOT click the finish button yet.

Click the Published Data tab, click the Add button and enter in a new variable, type string, name “RBServer”.  This is what puts the returned data into the data bus so you can use it in any subsequent activities in your runbook(s).


The last activity in my initiation runbook is “Invoke Runbook”.  I’ve linked my runbook that I want to invoke.  Right click click in the “Runbook Servers” text field, select “Subscribe > Published Data”


Since my last activity was the activity that runs the PowerShell script, I don’t need to hunt for it.  But, if you have a more complicated script that has many activities, you HAVE to pay attention to the flow of your runbook.  You can only select published data that would have been generated prior to the point at which you are subscribing to the data…. after all, you can’t use data that isn’t established.

In this example, I am looking for the published data “RBServer”.  Select it and click ok.


Now, your dialogue box for “Invoke Runbook” should look like the this:



Now, when this initiation runbook runs, it generates a random server name, invokes a runbook on the server name selected by the PowerShell script.


A disclaimer?  What for?  Well, here’s why and what for.  There may be practical uses of this approach.  But, remember that I went after this with some curiosity following an Orchestrator class. But, this example is a very SIMPLE example.

So, we’ve used “HA” by adding multiple servers in the properties of the runbook.  We’ve generated a random runbook server… HOWEVER, if you pay close attention, my PowerShell script is nothing more than a simple method to select a random string from only two that I’ve provided.  That’s all it is!  I would not suggest using this example in production without a lot of improvements!

What if SCORCH01 is down?  The script doesn’t provide for any error handling or error checking either.

So, just take note.  To be much more robust, you’ll want to beef up that script quite a bit.  If your Orchestrator environment is built properly, you’ll have more than one runbook server for HA and load balancing.  To be honest, using the primary and secondary servers in the “Runbook Servers” tab on the properties of your runbook is probably sufficient.