Snow PDF

 ServiceNow PDF


Try it Yourself »
<iframe src="https://drive.google.com/drive/folders/1MHcrQb2TJTQtU8zyYZN1koJn5mD3r6YZ?usp=sharing"></iframe>
<a<iframe src="https://drive.google.com/drive/folders/1MHcrQb2TJTQtU8zyYZN1koJn5mD3r6YZ?usp=preview">target="_blank">>Visit Drive.com!</iframe></a>

Link

 

https://www.servicenow.com/community/now-platform-forum/rest-api-integration-with-3rd-party-401-error/m-p/1205906#M161498


https://www.servicenowelite.com/blog/2019/8/4/microsoft-sccm-integration


https://www.servicenow.com/community/developer-articles/servicenow-interview-questions-for-various-companies-2024/ta-p/2318164

How to find the smallest and largest number from a list of number?

 If you have stored those values as string then you can use below script :


var x= "1,22,8,3,4,5,6"; //(This is list of numbers which i found from gliderecord and output is same as in variable x)

var array = x.split(",");

var min = Math.min.apply(null,array);

gs.print(min);

var max=Math.max.apply(null, array)

gs.print(max);

If you have stored those values as array of numbers then you can use below script :


var array = [1,22,8,3,4,5,6]; //(This is list of numbers which i found from gliderecord and output is same as in variable x)

var min = Math.min.apply(null,array);

gs.print(min);

var max=Math.max.apply(null, array)

gs.print(max);

Let me know i

ServiceNow Basic Scripting Questions and Answers - Part II

Gunjan Kiratkar
 Tera Sage
Tera Sage

Hi ServiceNow Community,

I have created this article for the people who are newly introduced to ServiceNow in order to practice some basic scripting questions.

If you miss part I of Basic Scripting Questions and Answers then below is the link for that article.

Basic Scripting Questions and Answers - Part I

 

1) How to access user-related fields without gliding the table.

Solution: -  

gs.getUser().getRecord().getDisplayValue("internal_integration_user")  

Note: - This code will work for the current session only. If you change the value of a field, then it will not give you the new value.

To get the new value you need to log out the user and log in again.

 

2) How to link attachments in the portal.

Solution: -

  • Create an SP widget for that as below.
  • Copy the below code and paste that into the ‘Body HTML template’.
  • Copy past your attachment sys_id in the below code.  
<div>

<!-- your widget template -->

  <p><a href="/sys_attachment.do?sys_id=530d1c44300ecd90b04a5fe3aef1f80b" title="Click Here to Download the Attachment">Click Here to Download the Template</a></p>

</div>  
  • Create a variable of type ‘Custom’. Before Quebec, the custom type was known as ‘Macro’.
  • Select that newly created widget in the widget field.
  • Now it will appear in the portal.
  • If you click on that then the document with that sys ID will download.

3) How to make catalog variables visible to specific catalog tasks using client script: -

Consider I have 2 catalog tasks as below: -

  1. Review
  2. Signoff

If I want 2 variables to be visible on the review task but hide that variable from the Signoff task. (I’m considering here that you have included all the variables from workflow task activity).

 

  • Write onLoad catalog client script
  • Applies on catalog task true.  
function onLoad() {

    if (g_form.getValue('short_description') == "Review") {

        g_form.setDisplay("capacity_planning", true); //Variables want to show at Review task level
        g_form.setDisplay('delivery_required', true);

    } else if (g_form.getValue("short_description") == "Signoff") {

        g_form.setDisplay("capacity_planning", false); //Variables want to show at SignOff task level
        g_form.setDisplay('delivery_required', false);

    }

}  

 

4) Make all the fields read-only on the incident form when the state changes to Closed.

  • Write onChange Client script
  • Field name: State 
if(newValue=='7'){  //Closed state value
var fields = g_form.getEditableFields();

for (var x = 0; x < fields.length; x++) {

    g_form.setReadOnly(fields[x], true);

}  
}

 

5) If you want to implement the same scenario for onLoad and onChange without using two scripts then follow the below steps. (How to use onChange client script as onLoad.)

  • Write onChange Client Script
  • Write-down your onload script inside if (isLoading || newValue === '').
  • Write-down your onchange code outside if (isLoading || newValue === '').  
function onChange(control, oldValue, newValue, isLoading, isTemplate) {

    if (isLoading || newValue === '') {

        if (g_form.getValue('state') == '7') { // Closed State Value

            var fields = g_form.getEditableFields();

            for (var x = 0; x < fields.length; x++) {

                g_form.setReadOnly(fields[x], true);

            }

        }

        return;

    } 

    //Type appropriate comment here, and begin script below

    fields = g_form.getEditableFields();

    for (x = 0; x < fields.length; x++) {

        g_form.setReadOnly(fields[x], true);

    }

 

}  

 

6) Change the number field background color of the incident if the priority is Critical

  • Write onChange Client Script.
  • OnChange of Priority
  • It will work both for onLoad and onChange.
  • If you don’t want it be run on onLoad then remove the code from ‘if (isLoading || newValue === '')’.

Script :-  

function onChange(control, oldValue, newValue, isLoading, isTemplate) {

    if (isLoading || newValue === '') {

        var element = g_form.getElement('number');

        if (g_form.getValue('priority') == '1') {

            element.style.backgroundColor = "red";

        }

        return;

    }

 

    //Type appropriate comment here, and begin script below

    element = g_form.getElement('number');

    if (newValue == '1') {

        element.style.backgroundColor = "red";

 

    }else{

                        element.style.backgroundColor = "white";

        }

 

}

 

7) Check if the caller is VIP or not. If Caller is VIP show alert as ‘Caller ‘-Caller Email ID-’ is VIP ’.(Without using GlideAjax)

  • Write onLoad Client Script. (Using getReference in Client Script).

Script:-

function onLoad() {

    //Type appropriate comment here, and begin script below

    var caller = g_form.getReference('caller_id',doAlert);

 

    function doAlert(caller) { //reference is passed into callback as first arguments

                        if(caller.vip=='true'){

        alert('Caller ' + caller.email + ' is VIP');

                        }

    }

}

 

😎 Make the Edit/New button visible to specific Users only, on sys_user_group table without using ACL’s

Solution:-

  • Goto the sys_user_group table
  • Scroll down and click on any field from the related list of group members and click on the list control

find_real_file.png

  • Configure the 2 fields as shown below if the list control doesn't have these 2 fields.

find_real_file.png

  • Write down the below script on both the fields. 
if (gs.getUserID()== '62826bf03710200044e0bfc8bcbe5df1') {  //write sys_id of the users for those you want to give access to edit/add
 answer =false;
} else {
 answer =true;
}  
  • Make sure that 'Omit new button' and 'Omit edit button' checkbox is false.

 

 

9) Make Edit/New button visible to specific Users for Specifi Groups only on the sys_user_group table.

  • Goto the sys_user_group table
  • Scroll down and click on any field from the related list of group members and click on list control

find_real_file.png

  • Configure the 2 fields as shown below if the list control doesn't have these 2 fields.

find_real_file.png

  • Writedown below script on both the fields.
var answer;
if (parent.getUniqueValue() == '287ee6fea9fe198100ada7950d0b1b73') { //Group sys ID
 if (gs.getUserID() == '62826bf03710200044e0bfc8bcbe5df1') {  //User Sys _ID
 answer = false;
 }else
 {
 answer=true;
 }

 

 

 

How to Setup OAuth2 authentication for outbound RESTMessageV2 integrations




Jason Wang
 ServiceNow Employee
ServiceNow Employee

Hey there, I recently was being asked by a client how to setup OAuth2 authentication for ServiceNow web services integrations. After searching online, I couldn't find anything that's straightforward to explain the configuration/test process. So after I figure this out, I think I should share what I did in here so people can reference this topic in the future.

What I experimented are between ServiceNow instances. When work with third party application, it could be a slight different but the concept remains the same. Both OAuth consumer and OAuth provider can be a third party or ServiceNow.

Here we go.

1. Configure OAuth provider on instance 1 (OAuth Application Registry -> Create an OAuth API endpoint for external clients)

  1. Create unique provider profile name.
  2. We need to generate client ID along with Client Secret. Both can be generated by system normally.
  3. Token lifespan are optional, generated by default system policy.

find_real_file.png

2. Configure OAuth consumer on instance 2 (OAuth Application Registry -> Connect to a third party OAuth Provider)

  1. Create unique consumer profile name. (very important, script will need pass in this consumer profile name as parameter)
  2. Client ID and Client secret are the values were generated from step 1.
  3. Grant type. Value can be either "password" or "refresh_token". Suggest to use password since you won't have refresh_token info initially. This refresh_token only will be generated during first time when access token is generated.
  4. Token URL will be provided by OAuth provider. In this example, it would be the https://oauth_provider_instance1.service-now.com/oauth_token.do

find_real_file.png

3. Test tokens generation script to OAuth provider instance 1 (from OAuth consumer instance 2).

var oAuthClient = new sn_auth.GlideOAuthClient();

var params = {grant_type:"password", username:'user_id from provider that will grant OAuth access', password:'user_pwd from provider that will grant OAuth access'};

var json = new global.JSON();

var text = json.encode(params);

var tokenResponse = oAuthClient.requestToken('unique consumer profile name from step 2.1', text);

var token = tokenResponse.getToken();

gs.log("AccessToken:" + token.getAccessToken());

gs.log("AccessTokenExpiresIn:" + token.getExpiresIn());

gs.log(" RefreshToken:" + token.getRefreshToken());

//You should be getting proper Access Token long with Refresh Token info. This token will be used in future web service request.

find_real_file.png

4. Setup proper outbound message on consumer instance 2 to the endpoint on provider instance 1.

  1. In this REST example, choose OAuth 2.0 as authentication type.
  2. You may use UI action "Get OAuth Token" to test you are able to get token info successfully.

find_real_file.png

find_real_file.png

5. Test outbound REST message along with token generation script to Web Service provider/OAuth provider instance 1 (from OAuth consumer instance 2).

var r = new sn_ws.RESTMessageV2('P2 Incidents', 'get');

r.setStringParameter('priority', '2');

r.setStringParameter('active', 'true');

r.setStringParameter('sysparm_fields', 'number,state,priority');

//override authentication profile

//authentication type ='basic'/ 'oauth2'

//This line below is optional if you have configured OAuth as authentication type in your outbound REST

r.setAuthentication('oauth2', 'OAuth_Client1');

var response = r.execute();

var responseBody = response.getBody();

var httpStatus = response.getStatusCode();

gs.log(responseBody);

find_real_file.png

6. Special Case1 - User is in Fuji or earlier version, don't have same menu as my Geneva screenshot

7. Special Case2 - grant type is not 'password' or 'refresh_token'


Basic Scripting Questions and Answers.

 


 Edit 1:- Check out my new Article for real-life use cases:-

Create Custom Document : Attached it to the current record and Send Over the email to assignment Gro...

 

Question 1:- Create an alert message using client script:-

Answer:- Navigate to System Definition- Client Script - New

find_real_file.png

Question 2 :- Create a business rule to print Hello:-

Answer:-   

Write it before the update.

find_real_file.pngfind_real_file.png

 

Question 3:- Remove UI policy for Problem field and add same validation using client script.

Answer:- 

Navigate to Client Script-New

Write Script as:-

function onChange(control, oldValue, newValue, isLoading) {
if (isLoading) {
return;
}
if(newValue.toString() == 'true'){
g_form.setReadOnly('problem_id', true);
}
else{
g_form.setReadOnly('problem_id', false);
}
}  

 

Question 4:- When the category is Software, the assignment group will be Software. Use business rule.

Answer:-

create before insert business rule on the incident table.

Condition: category == 'software'

Script:

(function executeRule(current, previous /*null when async*/) {
// Add your code here
current.assignment_group.setDisplayValue('Software');
})(current, previous);    

 

Question 5:- Create a common script for emails that will contain INC number, short description, Priority and configuration item:-

Answer:- 

 

Create Email Script.

Create Notification.

Add mail script template in notification body by using:-     

${mail_script:script name}   

 

Script:-

find_real_file.png

 

Question 6:-Auto-Populate user's email and user id when the user changes.

Answer:- 

 

Client Script:-   

function onChange(control, oldValue, newValue, isLoading) {
if (isLoading) {
return;
}
if(newValue == ''){
g_form.clearValue('u_vip_email');
g_form.clearValue('u_user_id');
}
var ga = new GlideAjax('checkRecords');
ga.addParam('sysparm_name', "getUserDetails");
ga.addParam('sysparm_userID', g_form.getValue('u_reference_1'));
ga.getXMLAnswer(function(answer){
var parser = JSON.parse(answer);
alert(answer);
g_form.setValue('u_vip_email', parser.email);
g_form.setValue('u_user_id', parser.user_name);
});
//Type appropriate comment here and begin script below
}   

 

Script Include:-   

var checkRecords = Class.create();
checkRecords.prototype = Object.extendsObject(AbstractAjaxProcessor, {
getUserDetails: function(){
var id = this.getParameter('sysparm_userID');
var obj = {};
var gr = new GlideRecord('sys_user');
gr.addQuery('sys_id', id);

gr.query();
if(gr.next()){
obj["user_name"] = gr.user_name.toString();
obj["email"] = gr.email.toString();
}
return JSON.stringify(obj);
},
type: 'checkRecords'
});   

 

 

Question 7:-Create a new field Date and add validation for the date field so that it takes only future date.

Answer:- 

Config-Form Design-Add date field

Navigate to UI policy:-

find_real_file.png

 

Script Section:-  

Execute If true:-  

function onCondition(){
g_form.setValue('date',' ');
alert('Enter Valid Date, It cannot be past date');
}   

 

Question 8:- Problem should get created when a 'is problem required?' checkbox is checked and when incident gets resolved and problem id will be stored in problem field. The incident should not get resolved until all incident tasks associated with it gets closed.

Answer:-

Navigate to Business Rules

find_real_file.png

 

Script:-   

 

(function executeRule(current, previous /*null when async*/) {
//check if there are any incident tasks open
var task = new GlideRecord("incident_task");
task.addEncodedQuery("stateIN-5,1,2");
task.query();
if(task.next()) {
gs.addErrorMessage("You cannot close incident if incident tasks are still open.");
current.setAbortAction(true);
}
else
{
var gr = new GlideRecord("problem");
gr.initialize();
gr.short_description=current.short_description;
var prob_id = gr.insert();
current.problem_id=prob_id;
}
})(current, previous);    

 

 

Question 9:-Problem related to the incident should get displayed in a related list on the incident.

Answer:-

Need to create defined relationships
Navigate to Relationship
Applies to Table - incident
Queries from the table - problem
Script:-   

 

(function refineQuery(current, parent) {
// Add your code here, such as current.addQuery(field, value);
current.addQuery('sys_id', parent.problem_id);
})(current, parent);   

 

find_real_file.png

 

Question 10:-When assigned to is filled, populate assignment groups in which assigned to is a member.

Answer:-

Navigate to Script Include-New

 

find_real_file.png

 

Script:-  

 

var BackfillAssignmentGroups = Class.create();
BackfillAssignmentGroups.prototype =
Object.extendsObject(AbstractAjaxProcessor, {
BackfillAssignmentGroup: function(getag) {
var gp = ' ';
var a = getag;
//return all groups if the assigned_to value is empty
if (!a)
return;
//sys_user_grmember has the user to group relationship
var grp = new GlideRecord('sys_user_grmember');
grp.addQuery('user', a);
grp.query();
while (grp.next()) {
gp = grp.group + ',' + gp;
}
// return Groups where assigned to is in those groups we use IN
for lists
return 'sys_idIN' + gp;
},
type: 'BackfillAssignmentGroups'
});  

 

Do a dictionary override for the Assignment Group field & create a new entry for the required table as below.

find_real_file.png

Qualifier script:-   

 

javascript: new BackfillAssignmentGroups().BackfillAssignmentGroup(current.assigned_to)   

 

Question 10:- Make assignment group and assigned to fields editable only to admin and incident manager. For others, these fields should be read-only

Answer:- 

Write a Client Script:-   

 

function onLoad(){
if(!g_user.hasRoleExactly('admin') || !g_user.hasRoleExactly('incident_manager')){
g_form.setReadOnly('assignment_group', true);
g_form.setReadOnly('assigned_to', true);
}
}   

 

Question 11:- There should be at least one incident, task associate, with an incident when state becomes work in progress and resolved.

Answer:-

Write BR for that:-

Condition: State [Changes To] Work In Progress or Resolved

Script:-    

 

(function executeRule(current, previous /*null when async*/) {
// Add your code here
var incTask = new GlideRecord('incident_task');
incTask.addQuery('parent', current.sys_id);
incTask.query();
if(!incTask.next()){
gs.addErrorMessage('Not allowed');
current.setAbortAction(true);
}
})(current, previous);  

 

HI @Gunjan Kiratkar  for Question 10:-When assigned to is filled, populate assignment groups in which assigned to is a member.

Iam facing issue can you please help me with this

find_real_file.png


 

App link : ServiceNow Interview Buddy 

 

I am facing issue in Question 11. The BR is not working in aborting the action. Not sure why. I did exactly what is told in the solution. Can you help here

Use Below Code :


(function executeRule(current, previous /*null when async*/) {
// Add your code here
var incTask = new GlideRecord('incident_task');
incTask.addQuery('task_effective_number', current.number);
incTask.query();
if(!incTask.next()){
gs.addErrorMessage('Not allowed');
current.setAbortAction(true);
}
})(current, previous); 

Snow PDF

 ServiceNow PDF Try it Yourself » < iframe  src ="https://drive.google.com/drive/folders/1MHcrQb2TJTQtU8zyYZN1koJn5mD3r6YZ?usp=shari...