{"revision":"c10276e953456835cdbb1f3a60d58ae1980be353","document":{"id":711,"path":"api-reference/server-api-reference/CMDBDuplicateTaskUtilsAPI.md","title":"CMDBDuplicateTaskUtils - Global","bundle":null,"doc_type":null,"release":"australia","body":"\n# CMDBDuplicateTaskUtils- Global\n\nThe CMDBDuplicateTaskUtils script include provides methods to create a de-duplication task that contains duplicate configuration items \\(CIs\\) that are of independent type.\n\nA de-duplication task can only contain Configuration Management Database \\(CMDB\\) CIs that are not in another de-duplication task.\n\n**Parent Topic:**[Server API reference](https://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/api-reference/server-api-reference/api-server.md)\n\n## CMDBDuplicateTaskUtils - CMDBDuplicateTaskUtils\\(\\)\n\nCreates an instance of the CMDBDuplicateTaskUtils class.\n\n|Name|Type|Description|\n|----|----|-----------|\n|None| | |\n\n```\n/**\n * CMDBDeduplicateTaskUtil().createDeduplicateTask() example\n * \n * OVERVIEW\n * \n * This script will allow you to search the CMDB\n * for records that may be duplicates based on the field\n * and filter definitions of your chosing\n * \n */\n\ntry {\n\n    //SET INITIAL VARIABLES\n\n    //Set the table that you would like to check for duplicates - note this MUST be a CMDB table\n    var cmdbTable = 'cmdb_ci';\n\n    //Add a filter as an encoded query if desired - only objects within this filter will be matched\n    // this query filters items are Apple computers located in New York (NY)\n    var filterQuery = 'sys_class_name=cmdb_ci_computer^sys_class_name=cmdb_ci_computer^manufacturer=b7e9e843c0a80169009a5a485bb2a2b5^sys_class_name=cmdb_ci_computer^manufacturer=b7e9e843c0a80169009a5a485bb2a2b5^locationLIKENY';\n\n    //Which field shall we use to check for duplicates?\n    var matchField = 'name';\n\n    //Do matches need to have the same cmdb_ci class? - This prevents child device types from matching if enabled i.e. Computer, Server\n    var sameClass = true;\n\n    //Should empty values be excluded from match?\n    var excludeEmpty = true;\n\n    //Minimum number of duplicates required to create a de-duplication task - must be at least 2\n    var numberOfMatches = 2;\n\n\n    //USE GLIDE AGGREGATE TO IDENTIFY POSSIBLE DUPLICATES\n\n    var dupeSetAgg = new GlideAggregate(cmdbTable);\n    if (filterQuery) dupeSetAgg.addEncodedQuery(filterQuery);\n    dupeSetAgg.addAggregate('COUNT', matchField);\n    dupeSetAgg.orderByAggregate('COUNT', matchField);\n    dupeSetAgg.groupBy(matchField);\n    if (sameClass) dupeSetAgg.groupBy('sys_class_name');\n    if (excludeEmpty) dupeSetAgg.addNotNullQuery(matchField);\n\n    //Group by domain if domain separation is enabled (prevent matches across domains)\n    if (gs.getProperty('glide.sys.domain.partitioning') == 'true') dupeSetAgg.groupBy('sys_domain');\n\n    //Must have at least 2 CI records that match\n    if (numberOfMatches < 2) numberOfMatches = 2;\n    dupeSetAgg.addHaving('COUNT', matchField, '>=', parseInt(numberOfMatches));\n\n    dupeSetAgg.query();\n\n\n    //LOOP THROUGH EACH SET OF MATCHES\n\n    while (dupeSetAgg.next()) {\n        var dupeRecordCount = dupeSetAgg.getAggregate('COUNT', matchField);\n        var dupeRecordsList = [];\n        var dupeAggQuery = dupeSetAgg.getAggregateEncodedQuery();\n        var dedupeShortDesc = 'Found ' + dupeRecordCount + ' records where ' + matchField + ' = ' + dupeSetAgg.getValue(matchField) + '\\n';\n        var dedupeDescription = '';\n\n        gs.log(dedupeShortDesc, 'Dedupe Task Script');\n\n        //Prepare notes - Header row\n        dedupeDescription += 'NAME | CREATED ON | UPDATED ON'\n\n\n        //GATHER ADDITIONAL DEVICE DETAILS (NEED SYS_IDs)\n\n        var dupeDevices = new GlideRecord(cmdbTable);\n        dupeDevices.addEncodedQuery(dupeAggQuery); //Use the exact query that the aggregate used for this group\n        dupeDevices.query();\n\n        while (dupeDevices.next()) {\n            var devName = dupeDevices.getValue('name');\n            var devCreated = dupeDevices.getDisplayValue('sys_created_on');\n            var devUpdated = dupeDevices.getDisplayValue('sys_updated_on');\n            var devId = dupeDevices.getUniqueValue();\n\n            //Add CI to notes\n            dedupeDescription += '\\n' + devName + ' | ' + devCreated + ' | ' + devUpdated;\n\n            //Add sys_id to list of matched records for this group\n            dupeRecordsList.push(devId);\n        }\n        gs.log(dedupeDescription, 'Dedupe Task Script');\n\n\n        //CREATE DEDUPLICATION TASK\n\n        //Convert array to string - .createDuplicateTask() expects a comma separated string\n        var deviceIdString = dupeRecordsList.join();\n\n        var dedupeUtil = new CMDBDuplicateTaskUtils();\n        var dedupeTaskId = dedupeUtil.createDuplicateTask(deviceIdString);\n\n\n        //UPDATE DEDUPLICATION TASK - ADD DETAILS\n\n        if (dedupeTaskId) {\n\n            var dedupeTask = new GlideRecord('reconcile_duplicate_task');\n            dedupeTask.get(dedupeTaskId);\n            dedupeTask.setValue('short_description', dedupeShortDesc);\n            dedupeTask.work_notes = dedupeDescription;\n            dedupeTask.update();\n\n            gs.log('>>>Created de-duplication task ' + dedupeTask.getValue('number') + ' for ' + devName, 'Dedupe Task Script');\n\n        }\n\n    }\n\n} catch (er) {\n    gs.log(er, 'Dedupe Task Script');\n\n}\n```\n\nOutput \\(unique sys\\_id\\):\n\n```\nDedupe Task Script: Found 2 records where name = MacBook Pro 15\"\n\nDedupe Task Script: NAME | CREATED ON | UPDATED ON\nMacBook Pro 15\" | 2012-02-18 00:14:21 | 2021-12-17 04:28:17\nMacBook Pro 15\" | 2012-02-18 00:14:37 | 2021-12-17 04:28:21\nMacBook Pro 15\" | 2012-02-18 00:14:29 | 2021-12-17 04:28:31\n...\nMacBook Pro 15\" | 2012-02-18 00:14:36 | 2021-12-17 04:30:17\nMacBook Pro 15\" | 2012-02-18 00:14:32 | 2021-12-17 04:30:14\nMacBook Pro 15\" | 2012-02-18 00:14:19 | 2021-12-17 04:30:14\nDedupe Task Script: >>>Created de-duplication task DUP0001002 for MacBook Pro 15\"\n```\n\n## CMDBDuplicateTaskUtils - createDuplicateTask\\(String sysIDs\\)\n\nCreate a de-duplication task in which the sys\\_ids of duplicate CIs are specified.\n\n|Name|Type|Description|\n|----|----|-----------|\n|sysIDs|String|A comma-separated list of sys\\_ids for which to create a de-duplication task.|\n\n<table id=\"table_jkd_gt3_2db\" class=\"returns\"><thead><tr><th>\n\nType\n\n</th><th>\n\nDescription\n\n</th></tr></thead><tbody><tr><td>\n\nString\n\n</td><td>\n\nThe sys\\_id of the created de-duplication task. Returns null if:\n\n-   The input string is empty.\n-   The input parameter contains a sys\\_id that is not in the cmdb\\_ci table.\n-   The input parameter contains a sys\\_id that is in an open de-duplication task\n\n</td></tr></tbody>\n</table>```\n// where <sys-id1> and <sys-id2> are sys_IDs of CIs in the cmdb_ci table\nvar sysIDs = '<sys-id1>,<sys-id2>';\nvar dupTaskUtil = new CMDBDuplicateTaskUtils();\nvar deDupTaskID = dupTaskUtil.createDuplicateTask(sysIDs);\ngs.info(deDupTaskID);\n```\n\nOutput \\(unique sys\\_id\\):\n\n```\n04c53e2c1bac411079e52131604bcba9\n```\n\n"}}