russ_sarbora
ServiceNow Employee
ServiceNow Employee

It seems that most of the time I'm writing Runbooks, I'm focused on doing something to my target systems. The output of something tends to not be very interesting. For the most part, all I care about is that something doesn't bomb out and cause my activity to fail. Recently, however, I needed to return a chunk of structured data from a Run Powershell activity. More importantly, I needed to be able to walk through that structured data and examine pieces of it.

Now, Powershell is very good at dealing with XML data. so it would seem that having my Powershell generate XML would be the way to go. But on the other hand, I had to use Javascript to manipulate that data once it got back to my instance. Walking and/or XPathing through a complex XML DOM in Javascript didn't sound like much fun. So I started thinking about making the Powershell return JSON that would be decoded into Javascript objects for my sensor script to interact with. Problem is, Powershell is not good at generating JSON, in fact, it doesn't have any built-in support for serializing objects into JSON. In a perfect world, I mused, I could write my Powershell to return XML, and then have it magically converted into Javascript objects to write script against.

It turns out, we don't need a perfect world, Runbook will already do this bit of alchemy for us. When an activity's payload can be parsed as valid xml data, it will automatically be converted into Javascript objects and made available to your sensor script in document.result.output.

For example: if your activity is returning this xml:



<a>
<b>1</b>
<c>2</c>
</a>


You can access that data from your sensor_script (or the onProbe_complete handler if you're writing a custom activity) with the following


var b=document.result.output.b;
var c=document.result.output.c;


If the XML contains multiple elements with the same name, they are converted into an array.


<a>
<b>1</b>
<b>2</b>
</a>




for (var i=0;i<document.result.output.b.length;i++) {
var b=document.result.output.b<i>;
}


Pretty cool. Even better, this works from any Runbook activity, not just Run Powershell!

Thanks to Chuck Tomasi for his post on how this works in Discovery sensors, which made me realize it would probably also work in Runbook.