Monday, December 17, 2018

Parse the CSV file upload in ServiceNow Service Portal


Body HTML template


<div class="text-center m">
      <span class="file-upload-input">
        <input type="file" style="display: none" multiple="true" ng-file-select="attachmentHandler.onFileSelect($files); filePicked($files);" class="sp-attachments-input">
        <button title="Add attachment"
                ng-click="attachmentHandler.openSelector($event)"
                class="btn btn-primary sp-attachment-add"
                aria-label="Add attachment" role="button">${Upload the custim file}
        </button>
      </span>
</div>


Client Controller Code


$scope.filePicked = function (oEvent) {
docArr = [];

// Get The File From The Input
var oFile = oEvent[0];
var sFilename = oFile.name;

// Create A File Reader HTML5
var reader = new FileReader();

// Ready The Event For When A File Gets Selected
reader.onload = function(e) {
try {
setTimeout(function(){
$rootScope.$broadcast('file-attached',null);
},1000);

var data = e.target.result;
var cfb = XLS.CFB.read(data, {type: 'binary'});

var wb = XLS.parse_xlscfb(cfb);

// Loop Over Each Sheet
wb.SheetNames.forEach(function(sheetName) {
// Obtain The Current Row As CSV
var sCSV = XLS.utils.make_csv(wb.Sheets[sheetName]);
var oJS = XLS.utils.sheet_to_row_object_array(wb.Sheets[sheetName]);
var theanswer = sCSV.split(',');
docArr.push(theanswer);

console.log(theanswer.filter(String)[0]);
$scope.data.output = theanswer.filter(String);
$scope.data.doc_date = theanswer.filter(String)[0];
$scope.data.doc_date_val = theanswer.filter(String)[1];
$scope.data.post_date = theanswer.filter(String)[2];
$scope.data.post_date_val = theanswer.filter(String)[3];
}
}
}
}


Establish Communication between two widgets in ServiceNow - Service Portal

Use Case:

Let us say for example we created a widget to just upload a file and other widget to display the files for the current record. As and when the file is uploaded in the first widget, we need to refresh the attachment list in second widget

This can be done by sending a broadcast message from the client controller in first widget and capturing that signal in the second widget

First Widget

setTimeout(function(){
$rootScope.$broadcast('file-attached',null);
},1000);

Second Widget

$rootScope.$on('file-attached', function(event,data) {
console.log('YYYYYYYYYYYYY  event recevied');
$scope.refreshAttachments();
 })

$scope.refreshAttachments =function() {
$scope.attachmentHandler.setParams("u_custom_table", $scope.data.sys_id, 1024 * 1024 *         $scope.data.maxAttachmentSize);
$scope.attachmentHandler.getAttachmentList();
}




Sunday, December 9, 2018

Avoid duplicate attachments in ServiceNow

This can be achieved by creating a before business rule on the sys_attachment table.

If there is a file with same name, same content type and of same size in bytes then the attachment upload is aborted.

The code for the same is as below


(function executeRule(current, previous /*null when async*/) {
var attach = new GlideRecord('sys_attachment');
attach.addQuery('table_sys_id', current.table_sys_id);
attach.addQuery('table_name', current.table_name);
attach.addQuery('file_name', current.file_name);
attach.addQuery('content_type', current.content_type);
attach.addQuery('size_bytes', current.size_bytes);
attach.query();
if(attach.next()){
current.setAbortAction(true);
}
})(current, previous);




Thursday, October 25, 2018

Mark terminated LDAP users as inactive in ServiceNow


We Find inactive LDAP accounts using the last refresh time. In this method, we add a Last Refreshed field to the user record and set the value during the import process. We create a scheduled job that checks for users that have not been refreshed in 30 days, and deactivate them.

 Create a datetime field on the User [sys_user] table. example, u_last_refreshed.

Add the following code in the transform script

target.u_last_refreshed = gs.now();

Create a scheduled job to find and deactivate the user accounts that have not been refreshed in 30 days.


disable_users();

function disable_users() {
    /*
     * query for active users with ldap source and last updated more than 30 days ago
     * disable them
     */
    var gr = new GlideRecord("sys_user");
    gr.addQuery('u_last_refreshed', '<', gs.daysAgoStart(30));
    gr.addQuery('active', true);
    gr.addQuery('source', '!=', '');
    gr.query();
    while (gr.next()) {
        gr.active = false;
        gs.log("Disabled inactive user: " + gr.user_name + " - last updated: " + gr.u_last_refreshed);
        gr.update();
    }
    gs.log("Completed disabling inactive accounts");
}



Tuesday, October 16, 2018

Script include script is not working from Service Portal catalog client script GlideAjax

Change the privacy setting for a single client-callable script include by adding theisPublic() function.

The isPublic() setting takes precedence over the glide.script.ccsi.ispublic property. For example, if the property is set to false making all client-callable script-includes private, and a script sets isPublic() to true, the script is public.

To change the privacy for a single client-callable script include, add the following method to the script include - The highlighted method.

var RITMUtils = Class.create();
RITMUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {
isPublic: function () {
return true;
},
type: 'RITMUtils'
});

Tuesday, October 9, 2018

Call a servicenow workflow thorough business rule script

var vars = {};
var w = new Workflow();
var context = w.startFlow('sys_id_of_the_workflow', current, current.operation(), vars);

Sys id of the workflow can be obtained by looking at the wf_workflow table

Execute powershell script from ServiceNow workflow run script activity

var pScript = "Script that needs to be executed";
var powershell = new PowershellProbe('MID_SERVER_NAME', gs.getProperty('mid.server.ip'));
powershell.setScript(pScript);
var resp = powershell.execute(true);
workflow.scratchpad.error = resp.error;
workflow.scratchpad.output = resp.output;
if(!resp.output.nil() && resp.output ! = 'null')
   current.work_notes = resp.output;
else if(!resp.error.nil()) {
current.work_notes = 'Error in script:  ' + resp.error;
}
gs.log('Response Output ' + resp.output);
gs.log('Response Error ' + resp.error);

Friday, October 5, 2018

Script to check if the current user is impersonating or not in SNOW

var CheckImpersonation = Class.create();
CheckImpersonation.prototype = {
    IsImpersonating: function() {
var gi=new GlideImpersonate().isImpersonating();
return gi;
    },

    type: 'CheckImpersonation'
};

Monday, October 1, 2018

Script to add variables to catalog item created through run script in workflow


var reqvar = new GlideRecord('sc_item_option_mtom');
reqvar.addQuery('request_item',current.sys_id);
reqvar.query();

while (reqvar.next()) {
var variablereference = new GlideRecord('sc_item_option');

if (variablereference.get(reqvar.sc_item_option)) {
var add_task_var = new GlideRecord('sc_item_variables_task');
add_task_var.task = tsk_sys_id;
add_task_var.variable = variablereference.item_option_new;
add_task_var.insert();

}
}

Thursday, September 27, 2018

ServiceNow cart API to request catalog item through script

var cart = new Cart();
var item = cart.addItem('12345678123456781234567812345678'); // sys id of the Catalog item
cart.setVariable(item, "employee", current.u_employee_name);
cart.setVariable(item, "employee_email", current.u_employee_email);
cart.setVariable(item, "employee_number", current.u_employee_number);
cart.setVariable(item, "termination_date", current.u_termination_date);
var rc = cart.placeOrder();

ServiceNow script to remove inactive user from all the groups and roles

function removeTheGroupsOfInactiveUser() {
        var groupGR = new GlideRecord('sys_user_grmember');
        groupGR.addQuery('user', current.u_employee_name);
        groupGR.query();
        while (groupGR.next()) {
                groupGR.deleteRecord();
        }
}


function removeTheRolesOfInactiveUser() {
        var roleGR = new GlideRecord('sys_user_has_role');
        roleGR.addQuery('user', current.u_employee_name);
        roleGR.query();
        while (roleGR.next()) {
                roleGR.deleteRecord();
        }
}

ServiceNow workflow run script to check if all the catalog tasks are closed for the current RITM

var tsk = new GlideRecord('sc_task');
tsk.addQuery('request_item', current.sys_id);
tsk.addActiveQuery();
tsk.query();

if(tsk.next()){
answer = false;
}
else{
answer = true;
}

Sunday, September 16, 2018

Add show workflow UI Action in ServiceNow for Global and scoped applications

For Global Application use the following script

onclik: showWorkflowContext()

condition: !current.isNewRecord() && (new Workflow().hasWorkflow(current))

function showWorkflowContext() {
   var id = g_form.getUniqueValue().toString();
   var url = new GlideURL('context_workflow.do');
   url.addParam('sysparm_stack', 'no');
   url.addParam('sysparm_table', g_form.getTableName());
   url.addParam('sysparm_document', id);
   g_navigation.open(url.getURL(), "_blank")
}

For Scoped Application use the following script

onclik: showWorkflowContext()

condition: !current.isNewRecord() && (new global.Workflow().hasWorkflow(current))
Script: Same as above

Monday, August 27, 2018

Remove back button on ServiceNow form view


Remove the back button on the any form view in ServiceNow                                                       






Please use the below client script for that particular form load

function onLoad() { document.getElementsByClassName("btn btn-default icon-chevron-left navbar-btn")[0].style.display="none"; }

Monday, July 30, 2018

Convert the timezone to GMT timezone in ServiceNow

// start and end dates are in the client's timezone
var start = current.u_change_start_date.getGlideObject().getNumericValue();
var end = current.u_change_end_date.getGlideObject().getNumericValue();

var gdt = new GlideDateTime(gs.nowDateTime());
var timeZoneOffSet = gdt.getTZOffset();


// start and end times are in the current timezone
// current date time is in the GMT timezone
// converting start and end times to GMT timezone

start += timeZoneOffSet;
end += timeZoneOffSet;

Tuesday, July 17, 2018

ServiceNow IT Asset Management - Part2


What is IT Asset Management lifecycle?


The asset management lifecycle covers the period from initial request for an item through procurement, delivery, stocking, deployment, monitoring, support, installation (as well as all moves, adds, or changes in location), upgrades, reuse, termination, disposal, and replacement.
The wide-ranging factors under asset management have been classified using a simple, three-stage format. This is to help you understand and manage with ease the best practice methodology in asset management. The critical aspects of the cycle, from a data accuracy perspective, include request and procurement at the front end of the cycle and disposal at the back end. The asset changes that take place fall in between.




Standard process for maintaining the life cycle of an asset



ServiceNow IT Asset Management - Part1


What is IT Asset Management?


IT asset management (ITAM) is a set of business practices that join financial, contractual, and inventory functions to support life cycle management and strategic decision making for the IT environment. Managing IT assets allows you to get maximum value from the use of the assets, right-size IT inventory, and optimize inventory purchase decisions and strategies.

Hardware Asset Management

Hardware asset management is the process of tracking and managing the physical components of computers and computer networks, from acquisition through disposal. The goals of hardware asset management are to account for all hardware assets on the IT infrastructure to provide comprehensive inventory visibility. Further, to help with vendor contract and lease management, and to assist in making budgetary forecasts based on the stock of assets and business requirement.


Software Asset Management

Software asset management is similar to hardware asset management, but focuses on software assets, including licenses, versions, and installed endpoints. ITIL states that the goals of software asset management are to reduce IT costs and limit business, legal and security risks related to the ownership and use of computer software, while maximizing IT responsiveness and end-user productivity

IT Asset Management Methodology

The major goal of ITAM is to establish a centralized asset repository that accounts for the presence and purchase of all your hardware and software inventory. 

To achieve this, ITAM methodology comprises the following steps:

·         Asset discovery, data capture and storage – Discovering all hardware and software components of IT inventory on the IT infrastructure and capturing their details, such as the type of asset, make, specification, etc., and storing it in an asset repository

·         Asset tracking – Being able to identify and track change in the location of assets, increase or decrease the number of assets, track assignment status and user information

·         Asset life cycle management – Being able to capture the asset life cycle data right from requisitioning, purchase and assignment, to expiry and decommissioning

·         Asset reporting and alerting – Being able to generate asset inventory reporting, and receive alerts on asset warranty and lease expiration

Friday, July 13, 2018

Get URL Parameters in a ServiceNow Client Script & Catalog Client Script

Create a onload client script



function onLoad() {
    var emp_sys_id = getParmVal('sysparm_emp_sys_id');
}


function getParmVal(name) {
    // get the current URL
    var url = document.URL.parseQuery();

    // decode the URL
    if (url[name]) {
        return decodeURI(url[name]);
    } else {
        return;
    }
}

Tuesday, June 26, 2018

Convert LDAP attribute objectGUID from base64 to string in ServiceNow LDAP integration - Transform script

answer = (function transformEntry(source) {

function toHex(d) {
    return ("0" + Number(d).toString(16)).slice(-2).toUpperCase();
}

function a2b(a) {
 var b, c, d, e = {},
 f = 0,
 g = 0,
 h = "",
 i = String.fromCharCode,
 j = a.length;
 for (b = 0; 64 > b; b++) e["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(b)] = b;
 for (c = 0; j > c; c++)
  for (b = e[a.charAt(c)], f = (f << 6) + b, g += 6; g >= 8;)((d = 255 & f >>> (g -= 8)) || j - 2 > c) && (h += i(d));
 return h;

}

function arrayToGuid(arr) {
      return arr.slice(0, 4).reverse().join('').toLowerCase() + '-' + arr.slice(4, 6).reverse().join('').toLowerCase() + '-' + arr.slice(6, 8).reverse().join('').toLowerCase() + '-' + arr.slice(8, 10).join('').toLowerCase() + '-' + arr.slice(10, 16).join('').toLowerCase();
}

function base64StringToGuid(base64string) {
    var charArray = GlideStringUtil.base64Decode(base64string).split('').map(function(el) {
      return el.charCodeAt(0);
    }).map(function(el) {
      return toHex(el);
    });
    return arrayToGuid(charArray);
}

return base64StringToGuid(source.u_objectguid); // return the value to be put into the target field

})(source);

Friday, May 25, 2018

Backend script to logout a user from ServiceNow - SNOW user logout script

var sessions = GlideSessions.get().getLoggedInSessionList();
var it = sessions.iterator();
while(it.hasNext()) {
var session = it.next();
if (session.getUser() == gs.getUserName()) {
var httpSession = session.getHS();
httpSession.setAttribute("locked_out", "true");
}
}

Monday, April 16, 2018

Custom Glyph in ServiceNow portal - Icon Link widget



Step1: You have to upload the image to image to the table db_image
Step2: Clone the widget Icon Link
Step3: Html code is as below

<div>
   <!--// Top Icon -->
   <a ng-if="::(options.link_template == 'Glyph Icon' || !options.link_template)" ng-href="{{::data.href}}" class="glyph_icon {{::options.class_name}}" target="{{::data.target}}">
       <div class="m-b fa fa-{{::options.glyph}} fa-4x {{::options.class_name}} text-{{::options.color}}" align="center" style="margin-right: auto; margin-left: auto; display: block;"></div>
       <h4 style="text-align: center;">{{::options.title}}</h4>
       <span class="text-muted">{{::options.short_description}}</span>
       <p>  </p>
   </a>


   <!--// Image Icon -->
   <a ng-if="::(options.link_template == 'Image Icon')" ng-href="{{::data.href}}" class="image_icon {{::options.class_name}} text-{{::options.color}}" target="{{::data.target}}">
       <div><img   src="{{data.image}}" alt="" align="left" style="margin-right: 7px; margin-left: auto; display: block;"/>
           <h3 style="font-weight: 300; margin-top: 22px">{{::options.title}}</h3>
       <span class="text-muted">{{::options.short_description}}</span></div>
       <p>  </p>
   </a>

</div>


Step4: Server side coding


(function(){
var gr = $sp.getInstanceRecord();
data.href = $sp.getMenuHREF(gr);
data.target = options.target || "";


var img = new GlideRecord('db_image');
img.addQuery('name', 'custom_icon.png');
img.query();
if (img.next()){
data.image = img.getValue('name');
}
})();


Thursday, April 12, 2018

What is the difference between setVisible() and setDisplay() on g_form?


setDisplay() -  It will reclaim the space if the field is hidden on the form
If the field is hidden, the space is used to display other items. that means below field like, if sub status of the incident is not displaying then assignment group will display on that blank space.
setVisible()
If the field is hidden, the space is left blank.you can see the change on the form clearly.

Wednesday, April 4, 2018

LDAP integration vs. SSO ServiceNow what is the difference?


LDAP integration means that your Service-Now instance will pick up newly created Users from the Active Directory, either through Listener ports or through Scheduled Uploads, and when you authenticate yourself while Logging onto Service-Now, this authentication is happening from the AD.


SSO implemented means that you do not have to re-authenticate yourself when trying to access ServiceNow, once you log into an Environment while accessing different Applications for whom SSO is enabled

Wednesday, March 28, 2018

Make all form fields read only - ServiceNow Client Script

var fields = g_form.getEditableFields();
for (var x = 0; x < fields.length; x++) {
    g_form.setReadOnly(fields[x], true);
}

Thursday, March 22, 2018

ServiceNow group approval through workflow script


var approval_gr = new GlideRecord('sysapproval_group');

approval_gr.initialize();
approval_gr.approval = 'requested';
approval_gr.parent = current.sys_id;
approval_gr.assignment_group = current.assignment_group;
approval_gr.short_description = 'Change Management Approval';
approval_gr.wait_for = 'any';
approval_gr.insert();

Sunday, March 11, 2018

SSO - ServiceNow integration with Microsoft Azure AD

https://docs.microsoft.com/en-us/azure/active-directory/active-directory-saas-servicenow-tutorial

Wednesday, February 14, 2018

Create a user approval through script in ServiceNow workflow


var approval_gr = new GlideRecord('sysapproval_approver');
approval_gr.initialize();
approval_gr.state = 'requested';
approval_gr.approver = gs.getUserID();
approval_gr.sysapproval = current.sys_id;
approval_gr.insert();

The approver and sysapproval columns should be replaced according to your required values.

Monday, February 12, 2018

Make attachment mandatory for catalog item submission

We can use the following catalog client script onSubmit


var gr = new GlideRecord("sys_attachment");
gr.addQuery("table_name", "sc_cart_item");
gr.addQuery("table_sys_id", g_form.getUniqueValue());
gr.query();

if (!gr.next()) {
alert("Attachment mandatory.");
return false;
}

Friday, February 9, 2018

Cancel a workflow using a script when any one of RITM approvals are rejected | ServiceNow

Use the following script in the run script activity of the current workflow



answer = true;
var sag = new GlideRecord('sysapproval_group');
sag.addQuery('parent', current.sys_id);
sag.query();
while(sag.next()) {
if(sag.approval == 'rejected') {
current.state = '4';

var w = new Workflow();
var gr = new GlideRecord('wf_context');

if (gr.get(current.context))
w.cancelContext(gr);
}
}

Monday, January 29, 2018

Sample code to get the catalog variables in the ServiceNow workflow

var gr  = current ;
var firstName  = gr.variables['first_name'] ;
var lastName  = gr.variables['last_name'] ;

var fullName  = lastName.getGlideObject().getValue() + " " + firstName.getGlideObject().getValue() ; 

Sample code to restart servicenow workflow

var gr = new GlideRecord('sc_req_item');
gr.addQuery('number', 'RITM0106387');
gr.query();
if(gr.next()) {
var w = new Workflow();
         var context = w.startFlow('67755686db2c4b004620d2c75e96191e', gr, 'insert', '');
}