Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2da9254
script.js
trimbakeshmadhan-109 Oct 27, 2025
c9315ec
README.md
trimbakeshmadhan-109 Oct 27, 2025
5d17de8
Script.js
trimbakeshmadhan-109 Oct 27, 2025
c8c2e06
README.md
trimbakeshmadhan-109 Oct 27, 2025
14244d8
script.js
trimbakeshmadhan-109 Oct 27, 2025
45c645d
README.md
trimbakeshmadhan-109 Oct 27, 2025
3edf0bc
Update README.md
trimbakeshmadhan-109 Oct 27, 2025
fa78c36
script.js
trimbakeshmadhan-109 Oct 27, 2025
a6e23bd
README.md
trimbakeshmadhan-109 Oct 27, 2025
484bcdd
Update script.js
trimbakeshmadhan-109 Oct 27, 2025
12f9ba9
Delete Core ServiceNow APIs/GlideAggregate/Count Inactive Users with …
trimbakeshmadhan-109 Oct 28, 2025
23f8bb3
Delete Core ServiceNow APIs/GlideAggregate/Count Inactive Users with …
trimbakeshmadhan-109 Oct 28, 2025
75d8c0b
Delete Core ServiceNow APIs/GlideAggregate/Find oldest Incident based…
trimbakeshmadhan-109 Oct 28, 2025
4f13513
Delete Core ServiceNow APIs/GlideAggregate/Find oldest Incident based…
trimbakeshmadhan-109 Oct 28, 2025
5328dda
Delete Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Exampl…
trimbakeshmadhan-109 Oct 28, 2025
6750b61
Delete Core ServiceNow APIs/GlideJsonPath/GlideJsonPath Reader Exampl…
trimbakeshmadhan-109 Oct 28, 2025
8f9be4e
Create script.js
trimbakeshmadhan-109 Oct 28, 2025
8083ec9
Create README.md
trimbakeshmadhan-109 Oct 28, 2025
8e92c2f
Delete Core ServiceNow APIs/GlideAggregate/Create Problem based on in…
trimbakeshmadhan-109 Oct 28, 2025
c1a0b3c
Delete Core ServiceNow APIs/GlideAggregate/Create Problem based on in…
trimbakeshmadhan-109 Oct 28, 2025
ed09dac
Update script.js
trimbakeshmadhan-109 Oct 28, 2025
23bf21c
Create Prevent Retirement of Policy with Active Control objectives
trimbakeshmadhan-109 Oct 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
GRC Policy Deletion Guard
Overview
This Business Rule enhances data integrity for ServiceNow's Governance, Risk, and Compliance (GRC) module. It prevents the deletion of a sn_compliance_policy record if it is still associated with any active controls. This ensures that policy changes are managed properly and prevents compliance gaps that could occur if a foundational policy is removed while dependent controls are still active.
Details
Script Name: Prevent Delete of Policy with Active Controls
Target Table: sn_compliance_policy
Run Time: before delete
Action: Prevents a policy from being deleted if it has active, linked controls. Displays an error message to the user and aborts the deletion action.
Logic:
Uses GlideAggregate for an efficient query on the many-to-many (m2m) table (sn_compliance_m2m_policy_policy_statement) that links policies to control statements.
The query filters for records where:
The document field matches the sys_id of the policy being deleted.
The related content record (the control statement) has its active field set to true.
A COUNT aggregate is performed on the filtered records.
If the count is greater than zero, the script adds an error message to the form and aborts the deletion process using current.setAbortAction(true).
Business Rule Configuration
To implement this functionality, configure the following settings in the Business Rule record:
Name: Prevent Delete of Policy with Active Controls
Table: sn_compliance_policy
When to run:
When: before
Delete: checked
Advanced: checked


Purpose and Benefits
This Business Rule provides the following benefits to the GRC application:
Data Integrity: Prevents the accidental or erroneous deletion of policies that are still in active use, thereby preventing broken relationships in your GRC data model.
Controlled Changes: Enforces a process where administrators must first inactivate or re-associate all controls linked to a policy before it can be deleted, ensuring proper change management.
User Feedback: Provides clear and immediate feedback to the user, explaining why the requested action was denied and outlining the necessary steps to proceed.
Performance: Utilizes the efficient GlideAggregate method, which scales well even on large production instances.
Usage
This script is a core part of GRC data governance. If a user attempts to delete a policy with active controls, they will see an error message and the deletion will be stopped. The user must navigate to the related controls and either make them inactive or associate them with a different policy before attempting to delete the original policy again.



Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
(function executeRule(current, previous /*null when async*/ ) {
// This Business Rule runs 'before' a record is updated on the 'sn_compliance_policy' table.
// Its purpose is to prevent a policy from being retired if it is currently linked to any active Control Objectives.
// This enforces a proper decommissioning process, ensuring that Control Objectives are delinked.
// before the policy that governs them, thereby preventing compliance gaps.
// The condition for this rule would be: 'State' changes to 'Retired'.

// Instantiate a GlideAggregate object on the many-to-many (m2m) table
// 'sn_compliance_m2m_policy_policy_statement'. This table links policies (via the 'document' field)
// to control statements (via the 'content' field). Using GlideAggregate is more
// performant than GlideRecord for counting records, as it performs the aggregation
// directly in the database.
var grControlAggregate = new GlideAggregate('sn_compliance_m2m_policy_policy_statement');

// Add a query to filter for records in the m2m table where the 'document' field matches
// the sys_id of the policy record currently being retired.
grControlAggregate.addQuery('document', current.getUniqueValue());

// Add a second query using 'dot-walking' to filter for records where the related
// control statement ('content' field) is currently active. This ensures only active
// controls are considered.
grControlAggregate.addQuery('content.active', true);

// Set the aggregate function to COUNT. This tells the database to return the total
// number of records that match the query conditions.
grControlAggregate.addAggregate('COUNT');

// Execute the database query.
grControlAggregate.query();

// Initialize a variable to store the count of active controls.
var activeControlCount = 0;

// Check if the query returned any results. If it did, retrieve the count.
// Note: GlideAggregate.next() returns a row even if the count is zero.
if (grControlAggregate.next()) {
// Retrieve the aggregated count result and assign it to the variable.
activeControlCount = grControlAggregate.getAggregate('COUNT');
}

// Check if the count of active controls is greater than zero.
if (activeControlCount > 0) {
// If active control objectives were found, add an error message to display to the user.
// The message includes the count for better clarity.
gs.addErrorMessage('Cannot retire this policy because it has ' + activeControlCount + ' active control objectives linked to it. All control objectives must be delinked first.');

// This crucial line aborts the current database transaction (the update operation).
// It prevents the policy record from being marked as 'Retired'.
current.setAbortAction(true);
}

})(current, previous);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Loading