GlideScopedEvaluator not working

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-17-2017 04:13 AM
We have added an Attribute field to the sys_user table. It is a GlideList field that points at a table of attributes and the condition that causes them to be added to the user. We do this to make reporting reasons. Recently we have had the need to update the user record in certain ways when certain attributes are added to a user record. I have been experimenting with ways to go about this and wanted to use a script field. So I have been testing out how to use the GlideScopedEvaluator by running it as a background script in a sub prod instance and it does not seam to be working. Below is the test code and the results.
Any thoughts would be appreciated.
var g = new GlideScopedEvaluator();
var s = new GlideRecord("sys_script");
s.initialize();
s.setValue("script", "gr.setValue('locked_out', false);");
gs.print(s.getValue("script"));
var u = new GlideRecord("sys_user");
u.get("30e473300a0a3c5401d64c7b0a5dc988");
gs.print(u.getValue("locked_out"));
g.putVariable("gr", u);
g.evaluateScript(s, 'script', null);
u = g.getVariable("gr");
gs.print(u.getValue("locked_out"));
eval("u.setValue('locked_out', false);");
gs.print("After Eval used: " + u.getValue("locked_out"));
Output
*** Script: gr.setValue('locked_out', false);
*** Script: 1
*** Script: 1
*** Script: After Eval used: 0
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-17-2017 06:57 AM
Drew,
I tried something like this in a OOTB instance and it worked :
var evaluator = new GlideScopedEvaluator();
var s = new GlideRecord('sys_script_include');
s.initialize();
s.script = "gr.setValue('locked_out', true);gr.update();";
s.insert();
var u = new GlideRecord("sys_user");
u.get("62826bf03710200044e0bfc8bcbe5df1");
var vars = {'gr' : u};
evaluator.putVariable('gr', u);
evaluator.evaluateScript(s, 'script', null);

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-17-2017 07:37 AM
I added var vars = {"gr": u}; and passed that instead of NULL and that did not work either. How do you know it worked? I want to run code that will update the user record but not call the update method. I want it to send back the updated GlideRecord so that I can do some other things then update the record one time.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-17-2017 09:47 AM
Ok, we have a potential fix for the issue. Credit my colleague: David Sturman
Issue
The issue is that the GlideScopedEvaluator will only execute script which is specified in a GlideRecord object. Previously it has been sufficient to just initialize one in memory and pass it to the .evaluateScript() method without saving the record first. It appears that ServiceNow has implemented a change which prevents this usage. (Whether on purpose or not, I have no idea. I cannot find any documentation for this change.)
Steps to Reproduce Issue
Running the following in a background script will print a sentence to screen on Istanbul_Patch2 but fail to do so on Patches 4 and later (not tested on 3):
Steps to workaround
Option 1 — insert prior to execution. The following works perfectly fine, but it does mean that you end up with unnecessary records in the system.
var evaluator = new GlideScopedEvaluator();
var gr = new GlideRecord('sys_script');
- gr.initialize();
- gr.script = 'gs.print("This script has executed and my user id is " + gs.getUserID());';
- gr.insert();
- evaluator.evaluateScript(gr, 'script');
Option 2 — retrieve any record with a script field, dynamically set the script value but don't actually update and it will still execute the updated script. For extra protection against any inadvertent updates, I suggest doing this against a record with a 'Read-only' protection policy.
var evaluator = new GlideScopedEvaluator();
var gr = new GlideRecord('sys_script');
- gr.addQuery('sys_policy','read'); //additional protection against accidental update
- gr.setLimit(1);
- gr.query();
if (gr.next()) {
gr.setValue('script','gs.print("This script has executed and my user id is " + gs.getUserID());');
try {
evaluator.evaluateScript(gr, 'script');
}
catch (e) {
gs.error(e);
}
}
else {
throw new Error('No rows were found to dynamically use GlideScopedEvaluator against');
}
I've also thrown some error handling in here. See if that works for you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-17-2017 09:49 AM
I pasted the above from an email I wrote for internal use at my company and therefore didn't tailor it to your specific use case but I hope you get the drift. You should still be able to use putVariable and getVariable etc. Good luck!