- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-14-2025 02:53 PM
I am running a script (background script currently, but it will be in an ETL later). My goal is to accept a username in any of the formats:
- username@domain.com
- domain\username
- username
I will convert the second two, to "username@domain.com" and do a query against sys_user, for that value. My problem is that I sometimes the username is something like "domain\rsmith". When I run the script, after adjusting the username value, I am left with "smith@domain.com" because SN is interpreting "\r" as a carriage return character. I have worked around the issue for \r but I could have the same problem with other regular expression characters (e.g. \n) and I don't really want to try to code for every possibility.
Is there an OOB way to make SN ignore "\r" and the like?
Here is the script I have been testing:
var input = 'domain\nsmith';
if (input.indexOf('\\') == -1) {
gs.info('input contains a backslash');
if (input.contains('\r')) {
input = input.replace('domain\r', 'r');
} else {
input = input.replace('domain', '');
}
gs.info('Replaced domain: {0}', input);
var backslashIndex = input.indexOf('\\');
if (backslashIndex !== -1) {
input = input.substring(backslashIndex + 1);
gs.info('removed domain: {0}', input);
} else {
gs.info('domain not in username');
}
if (!input.includes('@domain.com')) {
input += '@domain.com';
gs.info('added mail domain. input is now: {0}', input);
}
var user = new GlideRecord('sys_user');
user.addQuery('user_name', input);
user.addQuery('active', 'true');
user.query();
var count = 0;
var firstSysId;
while (user.next()) {
if (count === 0) {
firstSysId = user.sys_id;
}
count++;
}
gs.info('returning user: {0}', firstSysId);
} else {
gs.info('no slash');
}
Thanks.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-21-2025 11:58 AM
I ended-up using the following script.
(function (batch, output) {
for (var i = 0; i < batch.length; i++) {
var input = batch[i].input;
//var log_source = 'SccmUserLookup';
var downLevelDomain = 'domain';
var fullDomain = 'domain.com';
var domainRegex = new RegExp('^(' + downLevelDomain + '|' + fullDomain + ')(\\\\)?', 'i');
/*Logger = {
message: '',
appendLine: function (s) {
this.message += new Date().toISOString() + ': ' + s + '\n';
},
flush: function (error) {
var f = error ? gs.logError : gs.log;
f(this.message, log_source);
}
};*/
try {
//Logger.appendLine('Beginning SCCM user lookup script.');
if (input.includes(',')) {
var inputArray = input.split(',');
input = inputArray[0];
}
input = '.\administrator'
switch (true) {
case input.includes('\n'):
input = input.replace(/^.*(?=\n)/, '').replace('\n', 'n');
break;
case input.includes('\r'):
input = input.replace(/^.*(?=\r)/, '').replace('\r', 'r');
break;
case input.includes('\t'):
input = input.replace(/^.*(?=\t)/, '').replace('\t', 't');
break;
case input.includes('\T'):
input = input.replace(/\\T/g, 'T');
break;
case input.includes('\f'):
input = input.replace(/^.*(?=\f)/, '').replace('\f', 'f');
break;
case input.includes('\v'):
input = input.replace(/^.*(?=\v)/, '').replace('\v', 'v');
break;
case input.includes('\x08'): // represents \b
input = input.replace(/\x08/g, 'b');
break;
case input.includes('\B'):
input = input.replace(/\\B/g, 'B');
break;
case input.includes('\d'):
input = input.replace(/\\d/g, 'd');
break;
case input.includes('\D'):
input = input.replace(/\\D/g, 'D');
break;
case input.includes('\w'):
input = input.replace(/\\w/g, 'w');
break;
case input.includes('\W'):
input = input.replace(/\\W/g, 'W');
break;
case input.includes('\S'): // Skipped \s because no special handling is needed
input = input.replace(/\\S/g, 'S');
break;
default:
break;
}
input = input.replace(domainRegex, '');
//Logger.appendLine('Current username value: ' + input);
if (!input.includes('@domain.com')) {
input += '@domain.com';
//Logger.appendLine('Appended domain to username. Modified username value: ' + input);
}
var user = new GlideRecord('sys_user');
user.addQuery('user_name', input);
user.addQuery('active', 'true');
user.query();
var count = 0;
var firstSysId = '';
while (user.next()) {
if (count === 0) {
firstSysId = user.sys_id;
}
count++;
}
//Logger.appendLine('Found ' + count + ' user(s), returning user sys_id: ' + firstSysId);
//Logger.flush();
// Set each output element below
output[i] = firstSysId;
} catch (e) {
//Logger.appendLine('Error: ' + e.message);
//Logger.flush(true);
}
}
})(batch, output);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-14-2025 03:30 PM
Hi @Mike Hashemi,
If your would like to completely ignore those characters you can use:
var username = "domain\rsmith";
gs.info(GlideStringUtil.normalizeWhitespace(username)); //Output: domain smith
Or if you would like to keep those characters and treat them as a string:
var username = "domain\rsmith";
gs.info(GlideStringUtil.escapeNonPrintable(username)); //Output: domain\rsmith
If you found this helpful, please hit the thumbs-up button and mark as correct. That helps others find their solutions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-17-2025 07:07 AM - edited ‎03-17-2025 07:09 AM
I updated the script, but it appears that escapeNonPrintable() will not work, but maybe I am missing something.
I have updated the script:
var input = 'domain\rsmith';
var username = GlideStringUtil.escapeNonPrintable(input);
gs.info('initial username: ' + username);
gs.info(typeof username);
if (username.indexOf('\\') == -1) {
gs.info('username contains a backslash');
if (username.contains('\r')) {
username = username.replace('domain\r', 'r');
} else {
gs.info('a');
username = username.replace('domain', '');
}
gs.info('Replaced domain: {0}', username);
var backslashIndex = username.indexOf('\\');
if (backslashIndex !== -1) {
username = username.substring(backslashIndex + 1);
gs.info('removed domain: {0}', username);
} else {
gs.info('domain not in username');
}
if (!username.includes('@domain.com')) {
username += '@domain.com';
gs.info('added maildomain. username is now: {0}', username);
}
var user = new GlideRecord('sys_user');
user.addQuery('user_name', username);
user.addQuery('active', 'true');
user.query();
var count = 0;
var firstSysId;
while (user.next()) {
if (count === 0) {
firstSysId = user.sys_id;
}
count++;
}
gs.info('returning user: {0}', firstSysId);
//output[i] = firstSysId; // Use the first record's sys_id if multiple users are found
} else {
gs.info('no slash');
}
The result was:
initial username: domain\rsmith
object
no slash
Since the variable "username" is a list, I tried stringifying it. Adding "username = JSON.stringify(username);", but then the output was:
initial username: "domain\\rsmith"
string
no slash
To be clear, I am looking for "rsmith", so I can append "@domain.com" and do a sys_user lookup.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-17-2025 08:39 AM
So, I'm new to ServiceNow but not Javascript. And this one weirded me out.
But backslashes are operators, so they can be mind-bending.
Best suggest up front: could you take any version where you have loaded & can still detect the backslashes, and then flipping the backslashes into forward slashes / division signs? replaceAll()? Then work with the slashes, removing maybe multiples depending on how well you can detect the backslashes, and depending, admittedly, on stuff not in the Javascript so far, that I don't know.
FWIW, aside about the backslashes. String-literals in Javascript will swallow the backslashes. So if you set a variable to 'domain\rsmith' in Javascript code then when it's run by Javascript it's converted into 'domain[CR]smith'.
If you're using this with a development table and obviously you got into this mess somehow -- try exporting the table and examining it in Excel / text editor. It's possible the development table data was also created with just this problem: it may've been built with Javascript, and string literals. If so, it may be the table itself has the [CR] included in it when loaded. I'm thinking, could it be it was originally written and populated with a Javascript literal string?
CAVEAT: I don't know how SN is retrieving this data, or if there's an issue there, or for that matter how it got loaded into the table. So there's a lot I don't know! Take it from someone who's solely reading the Javascript and not trying to connect it to SN.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-17-2025 11:06 AM
In the even that you *haven't* run into a problem using the development user table, consider that the first line of this test script should be:
var input = 'domain\\rsmith';
The reason being, the '\r' is automatically interpreted it as [CR], just like later in your code where you did a
username.indexOf('\\')
... the interpreter automatically converted that to a single backslash.
So to load the username domain\rsmith, you'd need to encode 'domain\\rsmith' if you're putting it in a literal string.