ServiceNow UI Policies

I really thought that I’d posted about this previously, but I couldn’t find the post, and it’s something that’s tripped me up a couple of times.

When building a UI policy in ServiceNow, if you want to be able to clear the variable value, then you need to build it to hide the variable.

Or to put it another way, never build a UI Policy Action that has the ‘Clear the Variable Value’ box checked and which also has ‘Visible’ set to false.

If you do that, then when the variable is shown, the system will clear the value of the variable, which is never what you want to happen. You want the system to clear the value of the variable when the variable is hidden.

ServiceNow GlideRecord Bug

It turns out that if you use an invalid field name on a GlideRecord.addQuery() method call, it doesn’t fail (which is what I would have expected it to do). Instead, I runs through all of the records in the underlying table you’ve queried.

That’s annoying in a situation where you’re just querying for informational purposes and you get back several thousand times more records than you were expecting to get. It’s a lot worse than that if you’re in a situation where you’re making an update and you’ve got a typo in the field_name. It will result in an update being made to every record in that table.

Something else to watch for. I always recommend running any update query with a count variable and the update piece commented out first. That lets you confirm that you’re getting the expected number of records back, after which you can go ahead and perform the updates.

A hat tip to my amazing co-worker, Jasmine, who helped figure this out.

Here’s an example of how not to do it:

var gr = new GlideRecord('incident');
gr.addQuery('descriptio', 'Something...');
gr.query();

while(gr.next()) {
	gr.setValue('short_description', 'Redacted');
	gr.update();
}

As you can see, I’ve used ‘descriptio’ instead of ‘description’ in line two.

Blank Rows In Excel & Transform Maps

I recently had occasion to do some more work with transform maps in ServiceNow, and I couldn’t remember if I needed to worry about blank cells from my Excel document over-writing data in ServiceNow, so I did some experimenting.

I can confirm that blank cells in the Excel doc being imported and transformed do not overwrite existing data in the relevant field in ServiceNow.

Now it’s documented and I can refer back here the next time I have this particular question.

Table Fields that don’t show in system dictionary (ServiceNow)

I can’t think of a reason why this would or should matter, but it was not at all what I was expecting, so I thought I’d document it in case I need it at some point in the future. Maybe it will prove helpful to someone else.

I recently needed to confirm that iterating through all of the fields from within a server script would really iterate through all of the fields. Much to my surprise, I found out that there are a subset of fields that are on the glide record object (for project tasks), but which don’t show up if I go and look at the table definition in the GUI.

They are:
sys_tags
variable_pool
sys_meta
hierarchical_variables

I just used a for loop to do the iteration. Something like:

for (var field in record) {
   gs.log(field + " : " + record[field]);
}

Finding sys_audit Entries (ServiceNow)

We recently had an issue with something that required running a script to fix some values that had been incorrectly changed. The correct data we needed was in the sys_audit table, but getting to the table to verify that the data really was there turned out to be a miniature adventure all on its own.

The table checkpoints changes to nearly any field an any given form, so it’s huge. My mistake initially was in not thinking about how such a huge table can be so responsive when viewed from a form (in the history/activities section), but so slow when I’m trying to get at the records from a list view.

I’m used to tables in ServiceNow being indexed by one or more date/time fields, but obviously, that’s not how the data is being accessed from the forms.

All indications are that the sys_audit table is indexed by the documentkey field (the sys_id of the record being checkpointed or audited).

In keeping with my theme of also blogging about stuff that I’ll need to lookup at some point in the future, here is the url to get at all of the entries for a given record:

https://[instance].service-now.com/nav_to.do?uri=%2Fsys_audit_list.do%3Fsysparm_view%3D%26sysparm_first_row%3D1%26sysparm_query%3Ddocumentkey%253D[sys_id]%26sysparm_list_mode%3Dgrid%26sysparm_offset%3D

You’ll need to update the [instance] and [sys_id] with the correct fields

Adding Worknotes From a Script (ServiceNow)

I recently had a need to add work notes to a bunch of old incidents (to let the users know that they had changed and why they had been changed). My first approach was just to add a record to the sys_journal_field table.

At first blush, that seemed to work, but then a co-worker pointed out that the work note was showing up in the history tab with the wrong user, and at the wrong time.

It appears that the automation responsible for populating work notes into the activities feed in the history tab didn’t like me just inserting a record into that table.

I ended up using this code, which seems to do the trick of getting the work note into the sys_journal_field table, and pushing it into the activities feed correctly as well.

incidents['work_notes'].setJournalEntry("The text you want to appear in your work note...);

Impersonating a user from a server script (ServiceNow)

I recently needed to add a bunch of work notes to old incidents, but the comments needed to show up as being posted by someone else. This worked quite handily:

var impUser = new GlideImpersonate();
impUser.impersonate('6816f79cc0a8012341c5a33be123beaa1');

The sys_id in the code will obviously need to be changed to the user in your environment that you’re wanting to impersonate.

Built-in Translation Functionality For ServiceNow

I’ve written a bit about the translation project that I did for a client using the Google Translate API to dynamically translate incoming incident and request data.

I generally find that one of the more difficult part of most projects is figuring out what already built resources are out there that you can take advantage of.

That isn’t to say that the rest of the project is easy, necessarily, but for the most part, once I know what existing assets can be leveraged, creating the incremental improvements are usually pretty straightforward.

In the spirit of that, for anyone who might be coming at a translation-related project inside of ServiceNow, here are a couple of off the shelf translation assets that you may not know about already.

Firstly, the ability to create translations for existing field labels is a built in piece of functionality (I believe it only becomes available after you download one of the plugins for language translations (French, Spanish, etc.).

Once you’ve installed one of those plugins, you can add translations via the sys_translated table. It’s not dynamic (meaning that you have to put the values you want translated into the table before you need them, or write something of your own to dynamically populate that table), but it does create a much better experience for user who speak languages other than English.

The other bit of translation functionality that I leveraged in my project is the sys_ui_message table. Entries to this table are accessible using the built-in getMessage() function.

That allows you to put translations of common words or phrases into the table, and then pass the English value via your code and get back the translated value from the table.

I hope that one or both of those functions are helpful to one of my readers in the future!