Script include's 'activeAnything' query is not passing through the OOB query BR
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
an hour ago - last edited an hour ago
Hi,
There's an OOB BR which prevents itil users to see disabled user records. To bypass this, we have added a condition in this BR to check if the current query contains 'Active Anything' flag as we just need to bypass this one catalog item's reference qualifier.
This script is not working for itil users and they are still unable to see disabled user records. What am I missing here ?
Here is the BR,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
35m ago - last edited 34m ago
I've done this before (with the same choice of "activeANYTHING"). Don't have access now but can confirm it _should_ work.
Have you logged the value of "query" in your BR to make sure the "activeANYTHING" is making it through ? Also, log the result of query.includes('...') - in case there's something wacky going on there (I can't recall but isn't the inclusion of "includes()" a newer thing - maybe query BRs don't understand that - have you tried seeing if query.indexOf('...') is "-1" ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
26m ago
Also, just try it in list view as a user with the itil role. If they can add the "active is ANYTHNG" filter can they see inactive users there ?
If so then there's something up with your "test" function (probably "b1" being called instead of "a1" - check that too by logging when the functions are entered).
If not then it's the BR.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3m ago
In your Script Include's test function, you are building an encoded query using the ^NQ operator:
queryAllStr = queryActiveStr + '^NQ' + queryInactiveStr;
When a reference qualifier uses ^NQ, ServiceNow splits the execution into two entirely independent database queries.
When the User Query Business Rule runs, it intercepts the execution context. However, current.getEncodedQuery() evaluates only the first branch of the query string (queryActiveStr) unless you iterate through the subqueries. Because activeANYTHING is embedded inside the second branch (queryInactiveStr), your Business Rule reads the first query part, fails to see the keyword, and forcefully injects current.addActiveQuery() across the board. This effectively overrides your second query branch...
Furthermore, I saw another error:
Inside your script include function a1(), you perform a server-side query on the exact same table:
var userGr = new GlideRecord('sys_user');
...
userGr.query();
When userGr.query() triggers, it fires the User Query Business Rule again recursively. During this internal a1() query execution, current.getEncodedQuery() is looking at the query structure of userGr (which does not contain the activeANYTHING string).The Business Rule sees no flag, hits the else block, and appends active=true to your internal lookup.
As a result, userGr returns zero inactive users, rendering userIdArr empty.
Check if this works (this script is generated with AI):
SCRIPT INCLUDE:
a1: function(_lastUpdatedHoursStr) {
var userIdArr = [];
var userGr = new GlideRecord('sys_user');
// CRITICAL: Temporarily disable business rules on this internal lookup
// to prevent the User Query BR from filtering out inactive users here!
userGr.setWorkflow(false);
userGr.addQuery('active', 'false');
userGr.addQuery('user_name', 'NOT LIKE', 'ad%');
userGr.addQuery('user_name', 'NOT LIKE', 'bd%');
userGr.addQuery('name', 'DOES NOT CONTAIN', 'test');
userGr.addQuery('u_checktype_type', 'DOES NOT CONTAIN', 'vvv');
userGr.addNotNullQuery('employee_number');
userGr.addNotNullQuery('u_num');
if (_lastUpdatedHoursStr != undefined) {
var lastUpdatedQueryStr = 'sys_updated_onRELATIVEGT@hour@ago@' + _lastUpdatedHoursStr;
userGr.addEncodedQuery(lastUpdatedQueryStr);
}
userGr.query();
while (userGr.next()) {
userIdArr.push(userGr.getUniqueValue());
}
// Return only the raw sys_ids here
return 'sys_idIN' + userIdArr.join(',');
},
b1: function() {
var userIdArr = [];
var userGr = new GlideRecord('sys_user');
userGr.setWorkflow(false); // Keep workflow disabled for consistency
userGr.addActiveQuery();
userGr.addQuery('user_name', 'NOT LIKE', 'ad%');
userGr.addQuery('user_name', 'NOT LIKE', 'bd%');
userGr.addQuery('name', 'DOES NOT CONTAIN', 'test');
userGr.addQuery('u_checktype_type', 'DOES NOT CONTAIN', 'vvv');
userGr.addNotNullQuery('employee_number');
userGr.addNotNullQuery('u_num');
userGr.query();
while (userGr.next()) {
userIdArr.push(userGr.getUniqueValue());
}
return 'sys_idIN' + userIdArr.join(',');
},
test: function() {
var queryActiveStr = this.b1();
var queryInactiveStr = this.a1('96');
var queryAllStr = '';
if (queryActiveStr && queryInactiveStr) {
// CRITICAL: Put the activeANYTHING flag at the absolute front of the total string
queryAllStr = 'activeANYTHING^' + queryActiveStr + '^NQ' + queryInactiveStr;
} else if (queryActiveStr) {
queryAllStr = 'activeANYTHING^' + queryActiveStr;
} else if (queryInactiveStr) {
queryAllStr = 'activeANYTHING^' + queryInactiveStr;
}
return queryAllStr;
},
BUSINESS RULE:
(function executeRule(current, previous /*null when async*/ ) {
var query = current.getEncodedQuery();
// Check if the interactive session query contains our flag anywhere in the text string
if (gs.getSession().isInteractive() && query.indexOf('activeANYTHING') == -1) {
current.addActiveQuery();
}
})(current, previous);