Markus Nilsson
Tera Guru
Tera Guru

Recently a lot of my clients have asked for anonymizing HR Cases due to GDPR. So far I haven't seen a standard way from ServiceNow to this.  

The most recent use case I stumbled upon was a customer that wanted to save all HR Cases for 18 months then GDPR clean / anonymous them from any personal data and then move the cleaned HR Cases to the Archive.

A college of mine had build a scheduled job for a similar use case and I ended up moving parts of his scheduled job in to a script include so I didn't had to do a lot of scope accesses. Below are the scheduled job and script include used to remove personal data from the case form and also remove the activity log and corresponding emails belonging to the case.

 

Scheduled job

Name: Clean HR Case

Application: Human Resources Core

Run: Daily

unidentifyCases(); // Run function script

function unidentifyCases() {
    // Query for cases that haven't been updated
    var cas = new GlideRecord('sn_hr_core_case');
    var count = 0; // count cases
    cs.addEncodedQuery(''); // Insert your query
    cs.query();

    // Loop through each case
    while (cs.next()) {
        var sysid = cs.sys_id;
        count += 1;

        // Replace consumer info (DOESN'T delete cases.)Add all your necessary fields
        cs.subject_person = ''; // Blank Subject person
        cs.opened_for = ''; // Blank Opened for
        cs.short_description = 'Removed according to GDPR retention policy';
        cs.description = 'Removed according to GDPR retention policy';
        cs.rich_description = 'Removed according to GDPR retention policy';
	cs.autoSysFields(false);

        // Script include CleanHRCase
        var util = new global.CleanHrCase().cleanRecords(sysid);

        // Update case
        cs.update();
    }

    gs.info('GDPR - Unidentify cases before moving to Archive script ran through ' + count + 'cases');

 

Script include 

Name: CleanHRCase

API Name: global.CleanHRCase

Application: Global

Accessible from: All application scopes

var CleanHrCase = Class.create();
CleanHrCase.prototype = {
    initialize: function() {

    },
    cleanRecords: function(sysid) {
        // Query for and delete the case Journal Entries records
        var je = new GlideRecord('sys_journal_field');
        // var journal = new GlideRecord('sys_journal_field');
        je.addQuery('element_id', sysid);
        je.query();
        je.deleteMultiple();


        // Query for and delete the case 'sys_audit' records
        var aud = new GlideRecord('sys_audit');
        aud.addQuery('documentkey', sysid);
        aud.query();
        aud.deleteMultiple();

        // Query for and delete the case Record History records
        var hs = new GlideRecord('sys_history_set');
        hs.addQuery('id', sysid);
        hs.query();
        while (hs.next()) {
			// Query for and delete the case History records
            var hl = new GlideRecord('sys_history_line');
            hl.addQuery('set', hs.sys_id);
            hl.query();
            hl.deleteMultiple();
        }
        hs.deleteMultiple();

        // Query for and delete the Email log
        var em = new GlideRecord('sys_email');
        em.addQuery('instance', sysid);
        em.query();
        em.deleteMultiple();
    },
    type: 'CleanHrCase'
};

 

/Markus

Comments
Susan Britt
Mega Sage
Mega Sage

Hi Markus,

There isn't an OOB way to do this, but accomplishing through script similar to how you have is the "normal" way I am aware of also.  I must ask, if all data associated with the HR Case is being wiped, what is the purpose of keeping the archived record.  Why not archive and delete it instead?

Markus Nilsson
Tera Guru
Tera Guru

Hi @sbritt,

I get your point, however not all data needs to be wiped. I'm not a GDPR expert so I will leave that discussion to others :). But my experience for customers within EU are that companies need to have a process to clean data (but could still be interested in saving some not connected to a person). 

So for the use case described in the article the cleaned cases moved to the archive would be used to run statistics on e.g what types of cases are created and could be used to run comparisons month by month or year by year.

 

/Markus 

Susan Britt
Mega Sage
Mega Sage

Understood...  So far with the industries I've worked with, I haven't run into this specific requirement yet, but I can see it being necessary.  I have encountered the need to remove data from cases once cloned to lower/sub-prod instances, extra field level and HR Case security, and the normal archive and destroy rules.  Thanks for the scripts.

peter_repan
Tera Guru

Thank you for sharing this @Markus Nilsson 

 

One small point, technically you don't need to do both .query() and .deleteMultiple(), should be enough to call directly .deleteMultiple() function.

Alex87
Tera Contributor

Hi, i was wondering if ServiceNow already have some more options in the Utah/Vancouver release to support Europe GDPR regulations.  thank you for reply

Markus Nilsson
Tera Guru
Tera Guru

Hi @Alex87

Not to my knowledge. Maybe it’s something to put in the idea bank. 
/Markus

Sandeep Rajput
Tera Patron
Tera Patron

@Markus Nilsson Apart from anonymising the HR Case data, have you also deleted/anonymise the PII from HR profile table for those users who already left the organisation? 

Markus Nilsson
Tera Guru
Tera Guru

@Sandeep Rajput Most organisations I have came a cross handle that in the lifecycle of the user, removing the inactive user record and HR profile record after X days/month as inactive.

Version history
Last update:
‎06-30-2021 07:48 AM
Updated by: