
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-16-2016 12:09 PM
I'm parsing a JSON object within a workflow that is supposed to cycle through a list of CI's and add comments to each one. The JSON object is an array of ServerName, Action, and Results for 'n' number of CIs. Parsing the JSON is good, but when I loop through the list the GlideRecord works on the first CI and no others (and doesn't throw an exception). Here's what I tried first:
doProcessResponse();
function doProcessResponse() {
workflow.scratchpad.decommLog = "Server Decommission Log\n";
//parse JSON string to object
var result = new global.JSON().decode(activity.output);
for ( var i=0; i < result.length; i++) {
var serverGr = new GlideRecord('cmdb_ci');
serverGr.addQuery('name', result[i].Server);
serverGr.query();
if (serverGr.next()) {
var logEntry = result[i].Server + " decommission action " + result[i].Action + " results " + result[i].Result;
gs.warn("logEntry " + logEntry);
serverGr.comments = logEntry;
serverGr.update();
workflow.scratchpad.decommLog += logEntry + "\n";
}
// destroy GlideRecord object for reuse
serverGr = null;
}
gs.warn("workflow.scratchpad.decommLog = " + workflow.scratchpad.decommLog);
}
So, knowing that objects created in functions are garbage collected and subsequent calls to the function create new objects I just moved all the logic into a function like this:
doProcessResponse();
function doProcessResponse() {
workflow.scratchpad.decommLog = "Server Decommission Log\n";
//parse JSON string to object
var result = new global.JSON().decode(activity.output);
for ( var i=0; i < result.length; i++) {
doUpdates(result[i]);
}
gs.warn("workflow.scratchpad.decommLog = " + workflow.scratchpad.decommLog);
}
function doUpdates(result) {
var serverGr = new GlideRecord('cmdb_ci');
serverGr.addQuery('name', result.Server);
serverGr.query();
if (serverGr.next()) {
var logEntry = result.Server + " decommission action " + result.Action + " results " + result.Result;
gs.warn("logEntry " + logEntry);
serverGr.comments = logEntry;
serverGr.update();
workflow.scratchpad.decommLog += logEntry + "\n";
}
}
WTF??? Again only the first result object is processed!!!
Solved! Go to Solution.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-17-2016 11:52 AM
Apologies to everyone who tried to help with this but the pain was entirely self-inflicted. Turns out the JSON object had a space char prepended to the server name EXCEPT for the first one. That extra space was causing the query to fail. Once I removed whitespace all is well. Yet another lesson in making assumptions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-16-2016 03:50 PM
This script should work for you:
(function(){
var workflow.scratchpad.decommLog = "Server Decommission Log\n";
//parse JSON string to object
var result = JSON.parse(activity.output);
//loop through the results
for ( var i=0; i < result.length; i++) {
var serverGr = new GlideRecord('cmdb_ci');
serverGr.addQuery('name', result[i].Server);
serverGr.query();
if (serverGr.next()) {
var logEntry = result[i].Server + " decommission action " + result[i].Action + " results " + result[i].Result;
gs.warn("logEntry " + logEntry);
serverGr.comments = logEntry;
serverGr.update();
workflow.scratchpad.decommLog += logEntry + "\n";
}
}
gs.warn("workflow.scratchpad.decommLog = " + workflow.scratchpad.decommLog);
})();
I replaced "global.JSON().decode" on line 4 with "JSON.parse" and that seems to fix everything. I created 4 servers with your names and passed in a JSON object with your data and they were all updated. I've read that using "parse" is the safer way to go as well.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-17-2016 04:58 AM
No Joy. I pasted your script verbatim (had to remove the 'var' in front of line 2) as shown below.
(function(){
workflow.scratchpad.decommLog = "Server Decommission Log\n";
//parse JSON string to object
var result = JSON.parse(activity.output);
gs.log(JSUtil.logObject(result));
//loop through the results
for ( var i=0; i < result.length; i++) {
var serverGr = new GlideRecord('cmdb_ci');
serverGr.addQuery('name', result[i].Server);
serverGr.query();
if (serverGr.next()) {
var logEntry = result[i].Server + " decommission action " + result[i].Action + " results " + result[i].Result;
gs.warn("logEntry " + logEntry);
serverGr.comments = logEntry;
serverGr.update();
workflow.scratchpad.decommLog += logEntry + "\n";
}
}
gs.warn("workflow.scratchpad.decommLog = " + workflow.scratchpad.decommLog);
})();
And the logs captured the object looking very much the same as using new global.JSON().decode(activity.output); with only the first CI being processed. Can you tell me how to replicate your testing - possibly I can gleam something to dig into?
Log Object
Array of 3 elements
[0]: Object
Result: string = Success
Server: string = ACAP0116
Action: string = DecommissioningStatusACSI.ps1
[1]: Object
Result: string = Success
Server: string = ACAP0126
Action: string = DecommissioningStatusACSI.ps1
[2]: Object
Result: string = Success
Server: string = ACAP0130
Action: string = DecommissioningStatusACSI.ps1
logEntry ACAP0116 decommission action DecommissioningStatusACSI.ps1 results Success
workflow.scratchpad.decommLog = Server Decommission Log
ACAP0116 decommission action DecommissioningStatusACSI.ps1 results Success
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-17-2016 05:26 AM
Long shot at this point but could you try:
serverGr.addQuery('name', result[i].Server+'');
This doesn't change the value but forces JavaScript to change the data type

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-17-2016 06:00 AM
I tried both that and 'toString()' with no change in behavior. Really appreciate the replies all - just a bit frustrating to have to work on what should be a very, very simple process.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-17-2016 08:03 AM
I knew I was going to miss removing something in the script - I had to use a variable instead of the workflow scratchpad. After creating 4 CI records with the ACAT names in your data set, this is what I used to simulate your scenario, running it in the Xplore: Developer Toolkit (or a Background Script):
var testData = [{ "Result" : "Success", "Server" : "ACAT1442", "Action" : "DecommissioningStatusACSI.ps1" }, { "Result" : "Success", "Server" : "ACAT1445", "Action" : "DecommissioningStatusACSI.ps1" }, { "Result" : "Success", "Server" : "ACAT1463", "Action" : "DecommissioningStatusACSI.ps1" }, { "Result" : "Success", "Server" : "ACAT1466", "Action" : "DecommissioningStatusACSI.ps1" }];
var testJsonData = JSON.stringify(testData);
(function(parm1){
var decommLog = "Server Decommission Log\n";
//parse JSON string to object
var result = JSON.parse(parm1);
//loop through the results
for ( var i=0; i < result.length; i++) {
var serverGr = new GlideRecord('cmdb_ci');
serverGr.addQuery('name', result[i].Server);
serverGr.query();
if (serverGr.next()) {
var logEntry = result[i].Server + " decommission action " + result[i].Action + " results " + result[i].Result;
gs.warn("logEntry " + logEntry);
serverGr.comments = logEntry;
serverGr.update();
decommLog += logEntry + "\n";
}
}
gs.warn("decommLog = " + decommLog);
})(testJsonData);
The comments field is updated each time for each of the servers. The first two lines are just for creating the JSON data and I pass it into the function on line 24.
My data seems to end up looking just like yours:
Log Object
Array of 4 elements
[0]: Object
Result: string = Success
Server: string = ACAT1442
Action: string = DecommissioningStatusACSI.ps1
[1]: Object
Result: string = Success
Server: string = ACAT1445
Action: string = DecommissioningStatusACSI.ps1
[2]: Object
Result: string = Success
Server: string = ACAT1463
Action: string = DecommissioningStatusACSI.ps1
[3]: Object
Result: string = Success
Server: string = ACAT1466
Action: string = DecommissioningStatusACSI.ps1