Mark Roethof
Tera Patron
Tera Patron

Articles, Blogs, Videos, Podcasts, Share projects - Experiences from the field

 

Hi there,

 

Big change you've seen or even had to deal with the official ServiceNow HealthScan Scorecard at customers. The "ServiceNow HealthScan Scorecard provides an automated review of an instance". The PDF document optionally is accompanied with an Excel file pointing to all findings in detail.

 

While I'm not a fan of the HealthScan at all, I do feel the need to dive into some of the findings and share learnings I encounter at every single customer. In a few articles I will try to give a bit of explanation on findings, what you can do to solve them, and perhaps what you can do to prevent them in the first place. Some of the findings are solid gold, some of them are…

 

The first articles in this series will be a bit cherry picking, and then slowly progressing to more complex or time-consuming findings. Starting with the easy to solve findings to improve scores quickly and with minimal effort. Scores that often people in decision making places are sensitive to. Later on diving into more complex or time consuming findings, which are way more interesting for genuine developers.

 

Topics in this series of articles (I will update this section when publishing new articles):
- Update Sets should be named uniquely
- Use Notification Categories
- Populate Knowledge Base articles fully

- Report shared with a group which has no users
- Differs from baseline

- ...


HealthScan

"ServiceNow HealthScan Scorecard provides an automated review of an instance, to better understand instance health. HealthScan Scorecard uses a pre- defined library of best practice called definitions to inspect the instance. Only aggregated information is collected during this inspection scan, which is then analysed and compared. Details such as script names are not collected. The scores reflect alignment to the ServiceNow best practices, and give a high level summary only."

 

"ServiceNow HealthScan Scorecard is a high level overview of instance health. To get more detailed information, including advice on remediation, please contact the ServiceNow Customer Outcomes team who can advise you of options."


Update Sets should be named uniquely

One of the definitions within the "Manageability" category concerns "Update Sets should be named uniquely". ServiceNow explains this definition as:

"Duplication of update sets can pose a risk to the release process such as false positive previews and incorrectly being committed, Duplicate update sets should be removed or renamed if being used for active development."

 

Out-of-the-box, ServiceNow does not prevent one from creating Update Sets with names that are not unique. Depending on the process in your company, the way of working, the experience of colleagues, this might also not be needed at all. Though it's not a weird definition defined by ServiceNow. And for this article… a definition that can easily influence the manageability score within the HealthScan Scorecard! At three recent customers this single definition accounted for more than one third of all findings within the manageability category.

 

As mentioned out-of-the-box the name of an Update Set does not need to be unique. It also can't be, for example "Default" will already be present multiple times in any given instance. For sure you can come up with more scenarios where the Update Set name would not be unique.


Identifying findings

The optional detailed Excel file provided with the ServiceNow HealthScan Scorecard will list all records identified as findings for this definition. Also links are included that take you to the findings in your instance directly.

 

How ServiceNow exactly determines the findings, I can't tell. Those details are not shared. What I can imagine though:
- Records in table Update Set [sys_update_set]
- With a query like:
-- State is not ignore and Default set is false [state!=ignore^is_default=false]
-- Group by Name
-- Having two or more

If you do not have the detailed Excel file, you could identify Update Sets that don't have a unique name in multiple ways. From a list and group by, background script with a GlideAggregate and Group by, or my first go to: Instance Scan 😀.

 

Script Only Check

(function (engine) {

    var cntUpdateSet = new GlideAggregate('sys_update_set');
    cntUpdateSet.addEncodedQuery('state!=ignore^is_default=false');
    cntUpdateSet.addAggregate('COUNT', 'name');
    cntUpdateSet.addHaving('COUNT', '>=', '2');
    cntUpdateSet._query();

    while(cntUpdateSet._next()) {
        engine.finding.setCurrentSource(cntUpdateSet)
		engine.finding.increment();

        engine.finding.setValue('count', cntUpdateSet.getAggregate('COUNT', 'name'));
        engine.finding.setValue('finding_details', gs.getProperty('glide.servlet.uri') + 'sys_update_set_list.do?sysparm_query=' + encodeURIComponent('name=' + cntUpdateSet.name.toString()));
    }

})(engine);


Resolving findings

Having all findings available, we can start working on resolving them. How to resolve them depends a bit on your situation and your process. When it only concerns a hundred findings, you might solve them within 15 minutes by manually renaming the Update Sets by adding a suffix like "_2", or "v2". When it concerns a few hundred findings or more, you might consider updating them using a script to add the suffix. There might be more complex logic needed though, since the Update Set name is limited to 80 characters. Or what if you already have a "_2" Update Set, then you've just created a new finding... And how do you determine which Update Set you want to update?

 

Do apply this to your production instance. When performing a System Clone, the Update Sets are copied over to subproduction.

 

Good to be aware of: the HealthScan definition is about the Update Sets, not the Retrieved Update Sets. In production, when you retrieve, preview, and commit a Retrieved Update Set, automatically a new Update Set is created. You could choose to only rename the Update Set, though if you would fix this in a consistent way then rename the Update Set and the Retrieved Update Set. On the Retrieved Update Set, there's a reference field "Update Set' [update_set].

 

Preventing findings

Now we can identify and resolve the findings… how about actually preventing new occurrences in the first place? A thought that might cross your mind, there's a unique checkbox on fields right? Indeed there is, though that would be a no go. No go like already mentioned "Default" will already be present multiple times in any given instance. Trying to apply the unique checkbox anyway would give you an error upon Save/Update.

 

Update Sets should be named uniquely - 02.jpg

 

A common way that's used on multiple places out-of-the-box to handle duplicate values, is a before insert/update Business Rule that generates an error message followed by an abort action. Not the most pretty way from User Experience point of view, though as mentioned a common way that's used on multiple places out-of-the-box.

 

The Script for such a Business Rule could look something like:

(function executeRule(current, previous /*null when async*/) {

    var qryUpdateSet= new GlideRecord('sys_update_set');
    qryUpdateSet.addEncodedQuery('name=' + current.getValue('name') + '^state!=ignore^is_default=false^sys_id!=' + current.getUniqueValue());
    qryUpdateSet.setLimit(1);
    qryUpdateSet._query();

    if (qryUpdateSet.hasNext()) {
        gs.addErrorMessage(gs.getMessage('Update Set name must be unique'));
        current.setAbortAction(true);
    }

})(current, previous);


Don't forget to add a condition, same as the query mentioned at identifying findings: "Default set is false and State is not ignore" [state!=ignore^is_default=false].

---

 

That's it. Hope this helps you identifying, resolving, and preventing HealthScan findings. If any questions or remarks, let me know!

 

C

If this content helped you, I would appreciate it if you hit bookmark or mark it as helpful.

 

Interested in more Articles, Blogs, Videos, Podcasts, Share projects I shared/participated in?
- Articles, Blogs, Videos, Podcasts, Share projects - Experiences from the field

 

Kind regards,


Mark Roethof

Independent ServiceNow Consultant
10x ServiceNow MVP

---

LinkedIn

Comments
Antoni Zahariev
Tera Guru

Thanks for putting this article, Mark!

 

As part of the preventative configurations, I even created the below onChange Client Script few months ago.

Yet, there is one issue I have detected which I'm still not sure how to resolve:

When an Update Set is retrieved and there is a Local Update Set with same name, when the Commit button is clicked, no error get's generation and it stucks in "Committing".

 

    // Update Set Name uniqueness gets validated when the State is changed to Complete
    if (newValue === 'complete') {
        var gaCheckName = new GlideAjax('CheckUpdateSetName');
        gaCheckName.addParam('sysparm_name', 'checkName');
        gaCheckName.addParam('sysparm_us_name', g_form.getValue('name'));
        gaCheckName.getXMLAnswer(UpdateSetNameIsUnique);
    }

    function UpdateSetNameIsUnique(response) {
		if (response == 'false') {
            g_form.showErrorBox('name', 'There is another Update Set with the same name and they must be unique.');
            g_form.setValue('state', oldValue); // Revert the state field to its previous value
        }
    }

 

Version history
Last update:
2 weeks ago
Updated by:
Contributors