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

Here’s a link to a blog post that piqued my interest before taking a class on System Center Orchestrator.

I attended a remote class on orchestrator, company and instructor name withheld intentionally, shared Jon’s blog post and posed the following question, “can you randomly select a runbook server?”

The instructor said no. I thought he was a bit short-sighted.  The instructor was a proponent of saying (and implying) that you don’t need to know PowerShell.  Do you really need to know PowerShell to use System Center Orchestrator?  Technically, no.  Now, that’s “technically” a correct statement.

However, if you are going to put forth the time and effort to attend a class to learn a System Center product AND advance your skillset, AND, better leverage a product’s features, you are truly doing yourself a disservice beyond belief.  I know that won’t float well with several out there.  However, it is my opinion.  But, you have to face facts.  We are in an industry where to excel above and beyond and to be “good” you need to educate yourself and take advantage of making the fullest use of a product’s strengths as you can.  This includes spending time after hours with your own testing, learning your own, etc.  Learning PowerShell is NOT THAT HARD.  Using the command line is NOT THAT HARD.  At least familiarize yourself with PowerShell, learn the basics and see if you can use it to your advantage.  I bet you can find LOTS of ways to use PowerShell in any IT environment.  Enough said, I’ll jump off my soap box, for now.

Jon Mattivi’s blog post really made me think about this a lot. “When I design my company’s Orchestrator environment, I not only want it to be highly available, but I also want to implement the DRY principle.  I also want to extend the high availability by distributing the work load as evenly as I can.  How do I do that?”

Jon’s blog post seemed too static for my tastes.  Nothing against Jon’s post.  It’s a valid alternative.

After spending many, MANY, hours in my own home lab with Orchestrator and learning the ins and outs of building runbooks and becoming more advanced, a light clicked and I decided to try this.

I responded to Jon’s blog post with my solution.

Here’s the idea in a nutshell.  To distribute your runbook workload evenly, you can set up a global variable for each of your runbook servers.

In my example, we’ll say those two global variables are “SCORCH01” and “SCORCH02”

Next, create your initiation runbook (for more information on what an initiation runbook is, spend the best few bucks you can buy and purchase “Designing Orchestrator Runbooks” by David Ziembicki, Aaron Cushner, Andreas Rynes, and Mitch Tulloch.  It’s a very affordable book.  It is very easy to read, and in my humble opinion, the best money you can spend on a book for Orchestrator and a must have for your library).  The price is very low and frankly, it’s a must buy just because of the price!  (No, I’m not getting any commission on that, just a friendly recommendation I don’t think you should refuse.  It’s like passing up a gas station that has gasoline selling at $1.00 a gallon.  You’d be silly not to stop and top off your tank!)

In your initiation runbook, add a “Run .Net Script” activity.  Change the language to PowerShell.  Add this one liner (replace the server names in quotes and subscribe to your global variables).

<br />$RBServer = ($Server = "SCORCH01","SCORCH02") | Get-Random<br />

Set up the activity to publish the $RBServer variable to the Orchestrator bus.

Add an invoke runbook activity and link the two together. In the “Invoke Runbook” activity, in the runbook servers text box, subscribe to the published data for the data returned by the “Run .Net Script” activity.

Now, when the initiation runbook activity runs, you’ll be selecting from a random runbook server! If you have more than 2 runbook servers, this becomes a bit more useful in selecting a server at random.

So, the answer is “yes” you CAN select a random runbook server when your runbooks run.  Wasn’t that easy?

PowerShell – Refresh SCCM Updates Compliance

Here’s a quick post since I haven’t posted in a while.

Some of you SCCM users will run into circumstances where a system should be compliant with your current update deployment.  However, it doesn’t report properly in the report server within SCCM.

The “old” SMS way to do that was a common VBscript:

Ah, VBscript.  Well now, let’s do that in PowerShell!  This is so simple and only takes two lines.

You can easily do this using System Center Orchestrator as well.  Just combine the Execute PowerShell Script IP with the Configuration Manager IP for 2012 and you’re all set.  Just get collection members and then run this against each member of the collection.

Here’s the PowerShell way:

$SCCMUpdatesStore = New-Object -ComObject Microsoft.CCM.UpdatesStore


(just remember to run as “Administrator”)