How to Create a Dynamic Monthly Scheduled Incident Report 21st Previous Month to 20th Current Month

pr8172510
Tera Guru

Hi Community,

I am working on a requirement to create a dynamic monthly scheduled report for Incidents.

Requirement:

  • The report should include incidents created from the 21st of the previous month till the 20th of the current month.
  • Example:
    • Report generated on 21st May → should fetch incidents from 21st April to 20th May.
    • Report generated on 21st June → should fetch incidents from 21st May to 20th June.
  • The report should run automatically every month and send the report through email.

    Current challenge:

    • I am unable to configure an exact dynamic filter for:
      • Previous month 21st
      • Current month 20th
1 ACCEPTED SOLUTION

pr8172510
Tera Guru
Hi Community,

I was able to achieve this requirement using a combination of:

• Scheduled Script Execution
• Event Registry
• Email Notification

Since ServiceNow report filters cannot directly support a dynamic range like:

21st Previous Month → 20th Current Month

I used GlideDateTime in a Scheduled Script to calculate the dates dynamically every month.

Requirement Achieved:

Report generated on 21st May → Fetches incidents from 21st April to 20th May
Report generated on 21st June → Fetches incidents from 21st May to 20th June
Runs automatically every month
Sends the report through email as CSV attachment

Step 1: Create Scheduled Script Execution
Navigation:
System Definition → Scheduled Jobs → New

Configuration:

Run: Monthly
Day: 21
Time: As required
Active: True

Script:

var start = new GlideDateTime();
start.addMonthsUTC(-1);
start.setDayOfMonthUTC(21);
start.setDisplayValue(start.getDate() + " 00:00:00");

var end = new GlideDateTime();
end.setDayOfMonthUTC(20);
end.setDisplayValue(end.getDate() + " 23:59:59");

gs.info("Start Date: " + start);
gs.info("End Date: " + end);

var csv = "Number,Short Description,Priority,State,Created\n";

var gr = new GlideRecord('incident');
gr.addQuery('sys_created_on', '>=', start);
gr.addQuery('sys_created_on', '<=', end);
gr.query();

while(gr.next()) {

    csv +=
        gr.number + "," +
        gr.short_description + "," +
        gr.priority + "," +
        gr.state + "," +
        gr.sys_created_on + "\n";
}

var attachment = new GlideSysAttachment();

var fileName = "Monthly_Incident_Report.csv";

attachment.write(
    current,
    fileName,
    "text/csv",
    csv
);

gs.eventQueue(
    'monthly.incident.report',
    current,
    fileName,
    gs.getUserName()
);

Step 2: Create Event Registry
Navigation:
System Policy → Events → Registry

Create Event:

Event Name:
monthly.incident.report
Table:
Scheduled Script Execution [sysauto_script]

Step 3: Create Email Notification
Navigation:
System Notification → Email → Notifications

Configuration:

Send when: Event is fired
Event name:
monthly.incident.report
Include Attachments: True

 Email Content:
Subject:
Body:
Result:
The solution dynamically works for every month  and year changes without modifying filters manually.

Thanks.

pr8172510_0-1779195676218.png

pr8172510_1-1779195700522.png

 

View solution in original post

5 REPLIES 5

RitheshB
Tera Contributor

Hi,

You can achieve this requirement using a scripted date range instead of standard relative filters because ServiceNow relative conditions cannot directly handle a custom cycle like 21st previous month → 20th current month dynamically.

Recommended approach:

Use a Scheduled Script / Scripted Report and calculate the dates dynamically using GlideDateTime.

Example:

var start = new GlideDateTime();
start.addMonthsUTC(-1);
start.setDayOfMonthUTC(21);
start.setDisplayValue(start.getDate() + " 00:00:00");

var end = new GlideDateTime();
end.setDayOfMonthUTC(20);
end.setDisplayValue(end.getDate() + " 23:59:59");

Then query incidents using:

gr.addQuery('sys_created_on', '>=', start);
gr.addQuery('sys_created_on', '<=', end);

This will dynamically work every month:

  • 21 Apr -> 20 May

  • 21 May -> 20 Jun

  • etc.

You can schedule this script monthly and send the generated report through email automatically.

Thanks.

Hi @RitheshB ,

Thanks for your reply. It really helps.

Tanushree Maiti
Tera Patron

Hi @pr8172510 

 

Try with this:

 

  1. Create the Report and Dynamic Filter

 

  • Navigate to Reports > Create New
  • Set the Source type to Table and select Incident [incident]. 
  • Set the Type (e.g., List or Bar Chart).
  • In the Condition builder, apply the following Created date filters:
    • Created  on or after  Last month  21
    • AND Created  on or before  This month  20 
  • Click Save to store the report

 

  1. Configure Monthly Schedule
  • In the report header, click Share and select Schedule
  • Fill out the scheduling details:
    • Run: Select Monthly.
    • Day: Select 21.
    • Time: Select the exact time you want the report to be emailed. 
  • Under the Email tab, add the users or groups receiving the report. 
  • Set the Subject (e.g., "Incident : Monthly Report: 21st to 20th") and select the format (e.g., PDF). 
  • Click Submit or Save
Please Accept the solution if it assisted you with your question & Mark this response as Helpful.
Regards
Tanushree Maiti
ServiceNow Technical Architect
LinkedIn: https://www.linkedin.com/in/tanushreemaiti

Hi @Tanushree Maiti ,

Thanks for your reply.

I have already tried the same approach you suggested, but the values are behaving like static values instead of dynamic ones.