Issue ingesting multiple affected users using Azure Sentinel Incident Ingestion Integration

guythompson
Tera Contributor
Hi
We're having a bit of trouble adding multiple affected users into SIR tickets using the Azure Sentinel Incident Ingestion Integration. We are able to ingest Sentinel Account entities (${Account: properties(displayName)}$) using a simple glide get query to find the username of the email address ingested but when we create a script using a for loop to make multiple queries no outputs in the destinationValue field are found. The script has been tested elsewhere in ServiceNow and works but doesn't seem to work in the integrations field translations. See current query below:
 
var usernamearray = [];
var affectedUser = "";
if(sourceValue != ""){
    splitvalues = sourceValue.split(", ");
    for (i in splitvalues){
    var gr = new GlideRecord('sys_user');
    gr.get('user_name', splitvalues[i]);
    usernamearray[i] = gr.sys_id;
    }
    affectedUser = usernamearray.join(", ");
}
destinationValue = affectedUser;
 
 
Any help would be appreciated.
13 REPLIES 13

andy_ojha
ServiceNow Employee
ServiceNow Employee

Hey there,

 

It sounds like you already have explored the SecOps Field Translation for Azure Sentinel and SIR.

One observation here, if there is only one User value from the alert, you can certainly lookup the user record and set the singular [Affected User] field on the target SIR record.


However, when there are multiple users -> the SIR.[Affected User] field is a reference field, meaning it can only reference a single user.

There is a table that stores the relationship, between the SIR record and the "Affected Users" -> you can view this on the related lists, on Security Incidents.

 

In your Field Translation, you would have to continue with the logic you have above, but your end goal is to insert a record on the [sn_si_m2m_task_affected_user] table.   

  • In this table, each record has both, a reference to the Security Incident (sn_si_incident) and the User (sys_user) tables
  • Your end goal, is to insert a record here, for the SIR and for each User that you have 
  • Then, when you view a Security Incident > scroll to related lists > you will see all the related/affected users

Depending on your ServiceNow admin skills - you might approach this by creating a new Script Include to store all of your Azure Sentinel lookup logic, in different functions. 

  • This way, you have one central spot to store your functions for things like looking up CMDB CI values, stripping off data from certain string fields to clean them up and begin your lookups, looking up Users in the [sys_user] table, checking if Multiple Users are coming in the upstream alerts, and setting the values on the M2M table for that Security Incident, etc.
  • Your Field Translation, would call the relevant function in your Script Include 
  • Your Script Include could then either return a value (e.g. such as setting the SIR Affected User) or take care of inserting/updating records, such as in the M2M (many-to-many) case for handling multiple Users on a Security Incident 
NOTE: This code is just a sample for ideation.   Please use as a reference to build and test your own code.

 

The function below, takes an array of user values, and the target SIR record Sys_ID as an input.

  • It calls another function to some massaging/parsing (e.g. checking by email if the alert has email, user ID if the alert has ID, etc) - that function returns the sys_id, of the User record in ServiceNow
  • It performs an initial check to ensure the user is not already associated to the SIR, and if they are not, it creates an entry in the [sn_si_m2m_task_affected_user] table
  • This is just to help ideate how you can approach this similarly in your Field Translation

 

 //Handle mapping users in various formatting 
 mapMultiUser: function(userArr, targetRecord) {
    for (var i = 0; i < userArr.length; i++) {
        // Check if object is valid and not empty due to string cutoff with comma at end
        if (userArr[i]) {
            var userSysID = this._locateUser(userArr[i]);
            // Check if found user already linked to SIR record, if not then add association
            if (userSysID) {
                var grTaskUser = new GlideRecord('sn_si_m2m_task_affected_user');
                grTaskUser.addQuery('user', userSysID);
                grTaskUser.addQuery('task', targetRecord.sys_id);
                grTaskUser.setLimit(1);
                grTaskUser.query();
                if (!grTaskUser.next()) {
                    var grInsertTaskUser = new GlideRecord('sn_si_m2m_task_affected_user');
                    grInsertTaskUser.initialize();
                    grInsertTaskUser.setValue('user', userSysID);
                    grInsertTaskUser.setValue('task', targetRecord.sys_id);
                    grInsertTaskUser.insert();
                }
            }
        }
    }
},

 

 

 

 

 

 

Hi! 

Thank you for your response. 

Using Script Includes makes a lot of sense and is something I will look into. The question I have is would the field translation require a returned into it before an SIR ticket is created. Therefore if we wanted to call the script from the field translation we couldn't pass a target SIR record into it if we wanted to add multiple affected users. 

 

Many thanks for your help,

Guy

AJ_UK
Tera Contributor

Hi Guy,
I'm not sure if you now have this now working or not - much will depend on the User data points you can get from Sentinel/AD vs what is used as the UserID in ServiceNow.
I have mapped the ${Account: properties(additionalData(accountName))}$ to Affected User, which has a User ID value that matches into ServiceNow. I also have it marked for update with the checkbox.

Then I am using a Translation script which executes a gr to sys_user table to retrieve the sys_id of the User with comma space delimiter. (but without a 'split')

var sysIds = [];

var gr = new GlideRecord('sys_user');

gr.addQuery('u_user_idIN' +sourceValue); //this is the field that matches for our use case

gr.query();

while (gr.next()){

sysIds.push(gr.getUniqueValue());

}

destinationValue = SysIds.join(', ');

From memory each Account Entity is passed in and processed separately, so each one will get added to the related table of affected user separately, so by default multiple affected users are handled (assuming each one is an Entity in Sentinel)

prit123
Tera Contributor

@AJ_UK @guythompson 

The script given, shows affected user blank when used in field translation script though when run it actually gives the sysid of user but not when the script is used in field translation. Also any way we can put logs in field translation script. Neither info, debug , logs shows up.