Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 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
901ea70
Delete Server-Side Components/Business Rules/Prevent Retirement of Po…
trimbakeshmadhan-109 Oct 28, 2025
970549f
Create script.js
trimbakeshmadhan-109 Oct 28, 2025
a357cb8
Update script.js
trimbakeshmadhan-109 Oct 28, 2025
28be06b
Create README.md
trimbakeshmadhan-109 Oct 28, 2025
0a82c58
Delete Server-Side Components/Business Rules/GRC Policy Retirement Ga…
trimbakeshmadhan-109 Oct 28, 2025
16b223e
Create README.md
trimbakeshmadhan-109 Oct 28, 2025
c1f3d5b
Delete Server-Side Components/Business Rules/Prevent Deletion of Poli…
trimbakeshmadhan-109 Oct 28, 2025
98b8437
Delete Server-Side Components/Business Rules/Prevent Deletion of Poli…
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,37 @@
GRC Policy Retirement Guard with Control Objective Check
Overview
This Business Rule enhances data integrity and process governance within ServiceNow's GRC module. It prevents a sn_compliance_policy record from being marked with the "Retired" state if it is still associated with any active Control Objectives. The rule enforces a proper decommissioning process, ensuring that all dependent Control Objectives are either made inactive or delinked before the policy itself can be retired.
Details
Script Name: Prevent Retire of Policy with Active Control Objectives
Target Table: sn_compliance_policy
Run Time: before update
Condition: State changes to Retired
Action: Prevents a policy from being retired if it has active, linked Control Objectives. It displays an error message to the user and aborts the update action.
Logic:
Efficient Counting: Uses GlideAggregate for a highly performant query on the many-to-many (m2m) table (sn_compliance_m2m_policy_policy_statement), which links policies to control statements (in this case, acting as Control Objectives).
Query Filtering: The query targets the m2m table and filters records where:
The document field matches the sys_id of the policy being updated.
The related content record (the Control Objective) has its active field set to true.
Aborts Action: If the count of active Control Objectives is greater than zero, the script:
Displays an informative error message to the user.
Aborts the update process using current.setAbortAction(true), preventing the policy from being set to Retired.
Business Rule Configuration
To implement this functionality, configure the following settings in the Business Rule record:
Name: Prevent Retire of Policy with Active Control Objectives
Table: sn_compliance_policy
When to run:
When: before
Update: checked
Condition: [State] [changes to] [Retired]
Advanced: checked


Purpose and Benefits
This Business Rule provides the following benefits to the GRC application:
Process Governance: Enforces a controlled process for policy retirement, ensuring that all dependent Control Objectives are handled appropriately before the policy is decommissioned.
Data Integrity: Prevents the creation of orphaned Control Objectives or inconsistencies in compliance reporting.
Compliance: Ensures that compliance teams maintain an accurate and up-to-date record of active policies and their underlying Control Objectives.
User Feedback: Provides immediate and clear feedback to the user, explaining why the retirement action was denied and outlining the necessary steps to proceed.
Performance: Utilizes the efficient GlideAggregate method, which is best practice for performing counts on large tables.
Usage
This script is a core part of GRC data governance. If a user attempts to set a policy's State to Retired while active Control Objectives are still linked, they will see an error message and the update will be stopped. The user must first either inactivate or delink all related Control Objectives before attempting to retire the 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 Objective.
// This enforces a proper decommissioning process, ensuring that Control Objective 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
// Control Objective 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 Control Objective.
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 Control Objective is greater than zero.
if (activeControlCount > 0) {
// If active Control Objective 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 Objective linked to it. All Control Objective 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);
Loading