diff --git a/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/README.md b/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/README.md new file mode 100644 index 0000000000..a51d9e2ead --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/README.md @@ -0,0 +1,46 @@ +Count Active Incidents Assigned to Inactive Users +This script uses GlideAggregate to efficiently count the number of active incidents assigned to inactive users. This is a crucial task for maintaining data hygiene and preventing incidents from being stalled due to inactive assignees. +Overview +The script performs the following actions: +Initializes GlideAggregate: Creates an aggregate query on the incident table. +Filters Records: Uses addQuery() to restrict the search to incidents that are both active (true) and assigned to a user whose active status is false. This filter uses a "dot-walk" on the assigned_to field to check the user's active status directly within the query. +Aggregates by Count: Uses addAggregate() to count the number of incidents, grouping the results by assigned_to user. +Executes and Logs: Runs the query, then loops through the results. For each inactive user found, it logs their name and the number of active incidents assigned to them. +Use case +This script is essential for regular cleanup and maintenance. It can be used in: +Scheduled Job: Automatically run the script daily or weekly to monitor for and report on incidents assigned to inactive users. +Fix Script: Perform a one-off run to identify and log all current incidents that need reassignment. +Reporting: The output from this script can be used to build a report for managers to track and reassign incidents promptly. +Script +javascript +var ga = new GlideAggregate('incident'); +ga.addQuery('active', true); +ga.addQuery('assigned_to.active', false); +ga.addAggregate('COUNT', 'assigned_to'); +ga.query(); + +while (ga.next()) { + var inactiveUser = ga.assigned_to.getDisplayValue(); + var taskCount = ga.getAggregate('COUNT', 'assigned_to'); + gs.info("Inactive user " + inactiveUser + " has " + taskCount + " active incidents."); +} +Use code with caution. + +Installation +As a Scheduled Job +Navigate to System Definition > Scheduled Jobs. +Click New and select Automatically run a script of your choosing. +Name the job (e.g., Find Incidents Assigned to Inactive Users). +Set your desired frequency and time. +Paste the script into the Run this script field. +Save and activate the job. +As a Fix Script +Navigate to System Definition > Fix Scripts. +Click New. +Name it (e.g., Find Active Incidents with Inactive Assignee). +Paste the script into the Script field. +Run the script to see the results in the System Log. +Customization +Targeted tables: Change the table name from incident to task or any other table with an assigned_to field to check for active records assigned to inactive users. +Automated reassignment: Extend the script to automatically reassign the incidents to a group or another user. This is a common practice to ensure that tickets do not get stuck in the queue. +Email notification: Instead of logging the information, modify the script to send an email notification to the group manager or another stakeholder with the list of incidents needing attention. diff --git a/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/script.js b/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/script.js new file mode 100644 index 0000000000..3699d502ce --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/Count Inactive Users with Active incidents/script.js @@ -0,0 +1,11 @@ +var ga = new GlideAggregate('incident'); + ga.addQuery('active', true); + ga.addQuery('assigned_to.active', false); + ga.addAggregate('COUNT', 'assigned_to'); + ga.query(); + + while (ga.next()) { + var inactiveUser = ga.assigned_to.getDisplayValue(); + var taskCount = ga.getAggregate('COUNT', 'assigned_to'); + gs.info("Inactive user " + inactiveUser + " has " + IncidentCount + " active tasks."); + } diff --git a/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/README.md b/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/README.md new file mode 100644 index 0000000000..6f7afc5eac --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/README.md @@ -0,0 +1,37 @@ +Key features +Automatic problem creation: The script uses a GlideAggregate query to count the number of incidents opened for a specific CI. +Time-based threshold: Problems are only created if more than five incidents are opened within a 60-minute window. +Targeted incidents: The script focuses on incidents related to the same CI, making it effective for identifying recurring infrastructure issues. +Customizable conditions: The number of incidents and the time frame are easily configurable within the script. +Efficient performance: The use of GlideAggregate ensures the database is queried efficiently, minimizing performance impact. + +How it works +The script is designed to be executed as a server-side script, typically within a Business Rule. When an incident is inserted or updated, the script performs the following actions: +Queries incidents: It executes a GlideAggregate query on the incident table. +Sets conditions: The query is filtered to count all incidents that meet the following conditions: +Same CI: The incident's cmdb_ci matches the cmdb_ci of the current record. +Within the last hour: The opened_at time is within the last 60 minutes. +Evaluates count: After the query is run, the script checks if the count of matching incidents exceeds the threshold (in this case, 5). +Creates problem: If the threshold is exceeded, a new problem record is initialized. +The short_description is automatically populated with a descriptive message. +The cmdb_ci is linked to the new problem record. +The new record is then inserted into the database. +Implementation steps +Create a Business Rule: +Navigate to System Definition > Business Rules. +Click New. +Configure the Business Rule: +Name: Auto Create Problem from Multiple Incidents +Table: Incident [incident] +Advanced: true +When to run: Select after and check the Insert and Update checkboxes. This ensures the script runs after an incident has been saved. +Filter conditions: Optionally, you can add conditions to limit when the script runs (e.g., cmdb_ci is not empty). +Add the script: +Navigate to the Advanced tab. +Copy and paste the script into the Script field. +Customize (optional): +Number of incidents: Change the > 5 value to adjust the threshold. +Time frame: Adjust the gs.minutesAgoStart(60) value to change the time window. +Other conditions: If you need to check for specific incident statuses or categories, add more addQuery lines to the GlideAggregate call. +Save the Business Rule. +Customization examples diff --git a/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/script.js b/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/script.js new file mode 100644 index 0000000000..dcec063918 --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/Create Problem based on incident volume/script.js @@ -0,0 +1,13 @@ +var incidentCheck = new GlideAggregate('incident'); + incidentCheck.addQuery('cmdb_ci', current.cmdb_ci); // Or any specific CI + incidentCheck.addQuery('opened_at', '>', 'javascript:gs.minutesAgoStart(60)'); + incidentCheck.addAggregate('COUNT'); + incidentCheck.query(); + + if (incidentCheck.next() && parseInt(incidentCheck.getAggregate('COUNT')) > 5) { + var problem = new GlideRecord('problem'); + problem.initialize(); + problem.short_description = 'Multiple incidents reported for CI: ' + current.cmdb_ci.getDisplayValue(); + problem.cmdb_ci = current.cmdb_ci; + problem.insert(); + } diff --git a/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/README.md b/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/README.md new file mode 100644 index 0000000000..722a45ac02 --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/README.md @@ -0,0 +1,92 @@ +ServiceNow Script: Find Oldest Open Incidents per Group +This script leverages GlideAggregate to efficiently find the oldest active incident for each assignment group. This is a powerful tool for monitoring and reporting on potential service level agreement (SLA) risks and improving incident management processes. +Overview +The script performs the following actions: +Initializes GlideAggregate: Creates an aggregate query on the incident table. +Filters Active Incidents: Uses addActiveQuery() to restrict the search to only open (active) incidents. +Aggregates by Minimum Date: Finds the minimum (MIN) opened_at date, which represents the oldest record. +Groups by Assignment Group: Groups the results by the assignment_group to get a separate result for each team. +Iterates and Logs: Loops through the query results and logs the assignment group and the opening date of its oldest open incident. +How to use +This script is intended to be used in a server-side context within a ServiceNow instance. Common use cases include: +Scheduled Job: Run this script on a regular schedule (e.g., daily) to generate a report on aging incidents. +Script Include: Incorporate the logic into a reusable function within a Script Include, allowing other scripts to call it. +Fix Script: Execute the script as a one-off task to perform an analysis. +Script +javascript +(function findOldestIncidents() { + var ga = new GlideAggregate('incident'); + ga.addActiveQuery(); + ga.addAggregate('MIN', 'opened_at'); + ga.groupBy('assignment_group'); + ga.query(); + + while (ga.next()) { + var group = ga.assignment_group.getDisplayValue(); + var oldestIncidentDate = ga.getAggregate('MIN', 'opened_at'); + gs.info("Oldest open incident for " + group + " was created on: " + oldestIncidentDate); + } +})(); +Use code with caution. + +Installation +As a Scheduled Job +Navigate to System Definition > Scheduled Jobs. +Click New and select Automatically run a script of your choosing. +Name the job (e.g., Find Oldest Open Incidents). +Set your desired frequency and time. +Paste the script into the Run this script field. +Save and activate the job. +As a Script Include +Navigate to System Definition > Script Includes. +Click New. +Name it (e.g., IncidentHelper). +API Name: global.IncidentHelper +Script: +javascript +var IncidentHelper = Class.create(); +IncidentHelper.prototype = { + initialize: function() { + }, + + findOldestIncidents: function() { + var ga = new GlideAggregate('incident'); + ga.addActiveQuery(); + ga.addAggregate('MIN', 'opened_at'); + ga.groupBy('assignment_group'); + ga.query(); + + var results = []; + while (ga.next()) { + var group = ga.assignment_group.getDisplayValue(); + var oldestIncidentDate = ga.getAggregate('MIN', 'opened_at'); + results.push({ + group: group, + oldestIncidentDate: oldestIncidentDate + }); + } + return results; + }, + + type: 'IncidentHelper' +}; +Use code with caution. + +You can then call this function from other scripts. For example: +javascript +var helper = new IncidentHelper(); +var incidents = helper.findOldestIncidents(); +for (var i = 0; i < incidents.length; i++) { + gs.info("Oldest open incident for " + incidents[i].group + " was created on: " + incidents[i].oldestIncidentDate); +} +Use code with caution. + +Customization +Change the output: Modify the gs.info() line to instead write to a custom log, send an email, or create a report. +Refine the query: Add more addQuery() statements to filter incidents by other criteria, such as priority or category. +Change the aggregate: Use MAX instead of MIN to find the newest incident in each group. +Get incident details: To get the actual incident record (e.g., its number), you would need to perform a secondary GlideRecord query based on the aggregated data. +Dependencies +This script uses standard ServiceNow APIs (GlideAggregate, gs). No external libraries are required. +Support +For any questions or issues, please open an issue in this repository. diff --git a/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/script.js b/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/script.js new file mode 100644 index 0000000000..4aabd461b1 --- /dev/null +++ b/Core ServiceNow APIs/GlideAggregate/Find oldest Incident based Assignment Groups/script.js @@ -0,0 +1,11 @@ +var ga = new GlideAggregate('incident'); + ga.addActiveQuery(); + ga.addAggregate('MIN', 'opened_at'); + ga.groupBy('assignment_group'); + ga.query(); + + while (ga.next()) { + var group = ga.assignment_group.getDisplayValue(); + var oldestIncidentDate = ga.getAggregate('MIN', 'opened_at'); + gs.info("Oldest open incident for " + group + " was created on: " + oldestIncidentDate); + } diff --git a/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md b/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md new file mode 100644 index 0000000000..8106a2c022 --- /dev/null +++ b/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/README.md @@ -0,0 +1,43 @@ +Parse JSON with GlideJsonPath +This script demonstrates how to use the GlideJsonPath API in ServiceNow to parse a complex JSON string and extract specific data. In this example, it efficiently retrieves an array of player names from a nested JSON structure representing cricket team information. + +Overview +The script performs the following actions: +Initializes GlideJsonPath: A new instance of GlideJsonPath is created, passing the target JSON string as a parameter. +Reads data with JSONPath: The read() method is called with a JSONPath expression to extract the desired data. The expression "$['lib']['jsonpath']['cricket']['players'][*]" navigates to the array of players: +$ represents the root of the JSON object. +['lib'], ['jsonpath'], and ['cricket'] use bracket notation to traverse the nested object structure. +['players'] accesses the array of player names. +[*] is a wildcard that returns all elements in the players array. +Stores the result: The extracted array of player names is stored in the l variable. +Use case +This script is useful in scenarios where you need to parse JSON data returned from a REST API call or an integration. By using GlideJsonPath, you can quickly and efficiently extract specific pieces of information without writing complex code to traverse the entire JSON object manually. +How to use +This script is intended for use in a server-side context within ServiceNow, such as a Script Include or Business Rule. +Example: Script Include +javascript +var CricketJsonParser = Class.create(); +CricketJsonParser.prototype = { + initialize: function() { + }, + + getPlayers: function() { + var jsonString = '{"lib":{"jsonpath":{"cricket":{"name":"India","players":["Rohit","Dhoni","Kholi"]}}}}'; + var v = new GlideJsonPath(jsonString); + var playerNames = v.read("$['lib']['jsonpath']['cricket']['players'][*]"); + + // At this point, `playerNames` is a JavaObject array. + // You can log it or process it further. + gs.info("Extracted players: " + JSON.stringify(playerNames)); + + return playerNames; + }, + + type: 'CricketJsonParser' +}; +Use code with caution. + +Customization +JSON Data: Replace the hardcoded jsonString with the variable that holds your JSON data (e.g., the body of a REST response). +JSONPath Expression: Modify the JSONPath expression in the read() method to extract different data from your JSON structure. +Result Handling: The read() function returns a JavaObject array, not a standard JavaScript array. If you need to use JavaScript array methods (like forEach), you may need to convert it. diff --git a/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js b/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js new file mode 100644 index 0000000000..063812aad7 --- /dev/null +++ b/Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Example/script.js @@ -0,0 +1,3 @@ +var v = new GlideJsonPath('{"lib":{"jsonpath":{"cricket":{"name":"India","players":["Rohit","Dhoni","Kholi"]}}}}'); +var l = v.read("$['lib']['jsonpath']['cricket']['players'][*]"); +