Skip to content
Closed
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//UI Action for Create De-duplicate Tasks
//Onclick showConfirmationDialog

function showConfirmationDialog() {
var entries = g_list.getChecked();
var sysIDs = entries.split(',');

var con1 = confirm('Total number of Selected CIs ' + sysIDs.length + '. Click OK to create De-duplicate task');

if (con1) {
alert(sysIDs);
var ga = new GlideAjax('createDuplicateCITask');
ga.addParam('sysparm_name', 'createDeDupTask');
ga.addParam('sysparm_entry_ids', entries);
ga.getXML(getDupTasks);
}

function getDupTasks(response) {

var answer = response.responseXML.documentElement.getAttribute("answer");
if (answer == null) {
alert('Failed to create Remediate Duplicate Task. Selected CIs are already part of an open Remediate Duplicate Task');
} else {
var url1 = 'reconcile_duplicate_task.do?sys_id=' + answer;
var con = confirm('The De-duplicate task is created. Click OK to redirect to De-duplicate task record');
if (con) {
location.href = url1;
}
}
}
}

//Script Include

var createDuplicateCITask = Class.create();
createDuplicateCITask.prototype = Object.extendsObject(AbstractAjaxProcessor, {
createDeDupTask: function() {
var entries = this.getParameter('sysparm_entry_ids');

var dupTaskUtil = new CMDBDuplicateTaskUtils();
var deDupTaskID = dupTaskUtil.createDuplicateTask(entries);

return deDupTaskID;

},

type: 'createDuplicateCITask'
});


This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,47 +1,22 @@
# CI Deduplication Task Generator

This script rechecks the cmdb_ci_hardware table for duplicates by serial number and creates a De-Duplication Task if needed (for records that didn't run through the IRE).
This repository contains a ServiceNow customization that enables users to create De-Duplicate Tasks for selected Configuration Items (CIs) directly from a list view using a UI Action.

### How It Works

1. Finds all serial numbers that are used on more than one hardware CI.
When executed, the UI Action confirms the number of selected CIs, calls a Script Include via GlideAjax, and creates a Remediate Duplicate Task using CMDBDuplicateTaskUtils

2. For each group of duplicates, it checks if any of the CIs are already part of an open de-duplication task.
### How It Works

3. If no open task exists, it creates a new one linking all CIs in the group.
* Allows users to select multiple CIs and trigger de-duplication in one click
* Automatically creates a De-Duplicate Task record using backend logic
* Displays confirmation dialogs for task creation and redirection
* Prevents duplicate task creation for CIs already linked to an open task
* Redirects to the created De-Duplicate Task record for quick review

4. Logs a summary of actions taken (tasks created, groups skipped).

### Dependencies

This script requires the `global.CMDBDuplicateTaskUtils` Script Include to be active in your instance.

### Configuration & Use

This script is meant to be run as a **Scheduled Job** or as a **Background Script**.

Before you run it, you must set the target table.

```
// Change this line in the script!
var ciTable = "cmdb_ci_hardware"


```

Change `"cmdb_ci_hardware"` to the table you want to run the script against.

### Example Log Output

```
Starting check for duplicate CIs by serial number...
==> Successfully created task RITM0010123 for Serial Number "VMW-50-81-7A-C9-23-44".
--> Skipping Serial Number "SGH814X025". It is already part of an open task.
--- Re-check Complete ---
Total Duplicate Groups Found: 2
New Remediation Tasks Created: 1
Groups Skipped (Already in an open task): 1
--------------------------


```
Creation of UI Action and asking confirmation of selected Records from List View by using GlideAjax
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# ServiceNow Discovery Pre Sensor Script: IP Router Association

This script is a **ServiceNow Discovery Pre Sensor Script** designed to enrich discovery payload data before it reaches the **Identification and Reconciliation Engine (IRE)**.

It focuses on linking **Interface Cards (`cmdb_ci_interface_card`)** to their parent **IP Routers (`cmdb_ci_ip_router`)** by resolving the router name to its corresponding `sys_id` in the CMDB.


## Overview

When ServiceNow Discovery runs a pattern that identifies multiple components (e.g., routers and their interface cards), some payload items may contain **router names instead of sys_ids**.
The IRE requires sys_ids for accurate relationship building.

This script ensures that:
- The `u_configuration_item` field on interface cards is replaced with the actual `sys_id` of the corresponding router.
- The router’s `managed_by_group` field is also copied to the interface card record.
- Payload is properly formatted and ready for IRE ingestion.

## Script Logic

### Step-by-step Flow
1. **Parse Payload:**
Converts the input payload JSON string into an object for processing.

2. **Iterate Items:**
Loops through each payload item and filters those with `className = cmdb_ci_interface_card`.

3. **Router Resolution:**
For each interface card:
- Reads the router name from `u_configuration_item`.
- Searches for a matching router record in `cmdb_ci_ip_router`.
- If found:
- Replaces the router name with its `sys_id`.
- Copies the router’s `managed_by_group` value.

4. **Return Updated Payload:**
Returns the modified payload back to Discovery for further processing by the IRE.

---

## Example Behavior

### **Before Script Execution**
```json
{
"items": [
{
"className": "cmdb_ci_interface_card",
"values": {
"name": "Router-1/Gigabit0/1",
"u_configuration_item": "Router-1"
}
}
]
}

### **After Script Execution**
{
"items": [
{
"className": "cmdb_ci_interface_card",
"values": {
"name": "Router-1/Gigabit0/1",
"u_configuration_item": "1b23cdef6f3123006a12ff3b8b3ee490",
"managed_by_group": "287ebd7da9fe198100f92cc8d1d2154e"
}
}
]
}

70 changes: 70 additions & 0 deletions Specialized Areas/ITOM/Discovery/PrePost Processing Script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Pre sensor: You can change payload before it will be proccesed by Identification Engine.
* Use IEJsonUtility in order to add relevant information to the payload
* Input parameters in Pre sensor mode: payload, patternIds
*/


var rtrn = {};

// parsing the json string to a json object
var payloadObj = JSON.parse(payload);

// Clearing payload string to save memory
payload = null;

// Put your business logic here
var handlegrIpRouterdata = function() {

gs.info('PD: handlegrIpRouter');

var ipRouterName = '';

var payloadItems = payloadObj.items;

for (var i = 0; i < payloadItems.length; i++) {

if (payloadItems[i].className === 'cmdb_ci_interface_card') { //Get Child class data

var currentItem = payloadItems[i];

ipRouterName = currentItem.values.u_configuration_item;



if (ipRouterName && ipRouterName.length) {

var grIpRouter = new GlideRecord('cmdb_ci_ip_router');

if (grIpRouter.get('name', ipRouterName)) {



currentItem.values.u_configuration_item = grIpRouter.sys_id + '';
currentItem.values.managed_by_group = grIpRouter.managed_by_group + '';

}



}

}

}

};
handlegrIpRouterdata();
// For node logger, please use: prePostNodeLogger.info\warn\error\debug(prePostLogPrefix + '<YOUR_LOG_STATEMENT>')

// You can return a message and a status, on top of the input variables that you MUST return.
// Returning the payload as a Json String is mandatory in case of a pre sensor script, and optional in case of post sensor script.
// If you want to terminate the payload processing due to your business logic - you can set isSuccess to false.
rtrn = {
'status': {
'message': 'Enter your message here',
'isSuccess' :true
},
'patternId': patternId,
'payload': JSON.stringify(payloadObj)
};
Loading