Extracting items (over x days) where an AIP label has changed from one value to another...

%3CLINGO-SUB%20id%3D%22lingo-sub-2926609%22%20slang%3D%22en-US%22%3EExtracting%20items%20(over%20x%20days)%20where%20an%20AIP%20label%20has%20changed%20from%20one%20value%20to%20another...%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2926609%22%20slang%3D%22en-US%22%3E%3CP%3EHello%20to%20all%2C%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3ESo%20what%20I%20am%20trying%20to%20do%20is%2C%20is%20to%20extract%20extract%20any%20items%20(over%20x%20days)%20where%20an%20AIP%20label%20has%20changed%20from%20Confidential%20to%20another%20value.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThe%20KEY%20part%20though%20is%2C%20that%20I%20am%20also%20trying%20to%20find%20out%20IF%20any%20of%20these%20item%20have%20been%20emailed%20by%20ANYONE%20after%20the%20the%20AIP%20label%20change%20has%20been%20made...%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI%20STILL%20cannot%20find%20a%20way%20to%20make%20a%20'complete'%20match%20with%20the%20'Item'%20associated%20to%20an%20email...%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI%20have%20the%20following%20query%2C%20which%20'maps'%20against%20the%20InformationProtectionEvents%2C%26nbsp%3BEmailEvents%20and%26nbsp%3BEmailAttachmentInfo%20logs%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3Elet%20LabelChange%20%3D%20InformationProtectionEvents%3CBR%20%2F%3E%7C%20where%20Time%20%26gt%3B%20ago(4d)%3CBR%20%2F%3E%7C%20where%20Activity%20%3D%3D%20%22DowngradeLabel%22%3CBR%20%2F%3E%7C%20where%20LabelNameBefore%20contains%20%22Confidential%22%20and%20LabelName%20!contains%20%22Confidential%22%3CBR%20%2F%3E%7C%20where%20ItemPath%20contains%20%22http%22%3CBR%20%2F%3E%7C%20extend%20SenderMailFromAddress%20%3D%20User%3B%3CBR%20%2F%3Elet%20EmailItem%20%3D%20EmailEvents%3CBR%20%2F%3E%7C%20join%20kind%3Dinner%20LabelChange%20on%20SenderMailFromAddress%3CBR%20%2F%3E%7C%20summarize%20arg_max(TimeGenerated%2C%20*)%20by%20SenderMailFromAddress%3B%3CBR%20%2F%3Elet%20EmailAttachment%20%3D%20EmailAttachmentInfo%3CBR%20%2F%3E%7C%20join%20kind%3Dinner%20EmailItem%20on%20SenderObjectId%3CBR%20%2F%3E%7C%20summarize%20arg_max(TimeGenerated%2C%20*)%20by%20SenderObjectId%3B%3CBR%20%2F%3EEmailAttachment%3CBR%20%2F%3E%7C%20project%20ItemName%2C%20ItemPath%2C%20LabelName%2C%20LabelNameBefore%2C%20User%2C%3CBR%20%2F%3ESenderMailFromAddress%2C%20NetworkMessageId%2C%3CBR%20%2F%3EFileName%2C%20FileType%2C%20SenderObjectId%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EIt%20does%20NOT%20performing%20the%20'matching'%20I%20require%20I%20would%20be%20really%20open%20to%20some%20suggestions.%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2927026%22%20slang%3D%22en-US%22%3ERe%3A%20Extracting%20items%20(over%20x%20days)%20where%20an%20AIP%20label%20has%20changed%20from%20one%20value%20to%20another...%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2927026%22%20slang%3D%22en-US%22%3EIf%20you%20have%20the%20time%20stamp%2C%20then%20you%20can%20probably%20test%20if%20an%20email%20has%20been%20sent%20between%20that%20time%20and%20now%20%3CBR%20%2F%3E%3CBR%20%2F%3E...%3CBR%20%2F%3E%7C%20where%20TimeGenerated%20between%20(TimeofLastChange_%20..%20now())%3CBR%20%2F%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2930818%22%20slang%3D%22en-US%22%3ERe%3A%20Extracting%20items%20(over%20x%20days)%20where%20an%20AIP%20label%20has%20changed%20from%20one%20value%20to%20another...%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2930818%22%20slang%3D%22en-US%22%3EThank%20you%20for%20the%20response%20%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F239477%22%20target%3D%22_blank%22%3E%40Clive%20Watson%3C%2FA%3E.%20Very%20much%20appreciated.%3CBR%20%2F%3E%3CBR%20%2F%3EI%20have%20realised%20my%20query%20is%20not%20structurally%20correct%20even%20in%20its%20current%20format.%3CBR%20%2F%3E%3CBR%20%2F%3EThe%20following%20element%20is%20correct%3A%3CBR%20%2F%3E%3CBR%20%2F%3Elet%20endtime%20%3D%204d%3CBR%20%2F%3Elet%20LabelChange%20%3D%20InformationProtectionEvents%3CBR%20%2F%3E%7C%20where%20Time%20%26gt%3B%20ago(endtime)%3CBR%20%2F%3E%7C%20where%20Activity%20%3D%3D%20%22DowngradeLabel%22%3CBR%20%2F%3E%7C%20where%20LabelNameBefore%20contains%20%22Confidential%22%20and%20LabelName%20!contains%20%22Confidential%22%3CBR%20%2F%3E%7C%20where%20ItemPath%20contains%20%22http%22%3B%3CBR%20%2F%3E%3CBR%20%2F%3EOut%20of%20the%20above%2C%20I%20can%20extract%20the%20ItemName%20attribute%20which%20represents%20the%20file%20name%20where%20the%20AIP%20label%20has%20changed.%3CBR%20%2F%3E%3CBR%20%2F%3E...the%20part%20of%20trying%20to%20find%20out%20IF%20any%20of%20these%20items%20have%20been%20emailed%20by%20ANYONE%20after%20the%20AIP%20label%20has%20changed%2C%20CANNOT%20be%20matched%20against%20the%20'User'%20attribute%20ONLY.%3CBR%20%2F%3E%3CBR%20%2F%3EClive%20you%20mention%20the%20time%20stamp%3B%20do%20you%20mean%20matching%20within%20the%20EmailEvents%20log%3F%3CBR%20%2F%3E%3CBR%20%2F%3ESo%20you%20mean%20something%20like%3A%3CBR%20%2F%3E%3CBR%20%2F%3Elet%20EmailItems%20%3D%20EmailEvents%3CBR%20%2F%3E%7C%20where%20TimeGenerated%20between%20(endtime%20..%20now())%3CBR%20%2F%3E%7C%20summarize%20arg_max(TimeGenerated%2C%20*)%20by%20SenderMailFromAddress%3B%3CBR%20%2F%3Elet%20EmailAttachments%20%3D%20EmailAttachmentInfo%3CBR%20%2F%3E%7C%20join%20kind%3Dinner%20EmailItems%20on%20SenderObjectId%3CBR%20%2F%3E%7C%20summarize%20arg_max(TimeGenerated%2C%20*)%20by%20SenderObjectId%3B%3CBR%20%2F%3E%3CBR%20%2F%3EThe%20above%20is%20assuming%20the%20file%20changed%20SHOULD%20be%20attachment.%20So%20I%20am%20still%20struggling%20how%20to%20work%20out%20a%20way%20to%20'combine'%20the%20'let'%20statements%20of%20'LabelChange'%20and%20'EmailAttachments'.%3CBR%20%2F%3E%3CBR%20%2F%3EAgain%2C%20any%20suggestions%20much%20appreciated.%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2930964%22%20slang%3D%22en-US%22%3ERe%3A%20Extracting%20items%20(over%20x%20days)%20where%20an%20AIP%20label%20has%20changed%20from%20one%20value%20to%20another...%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2930964%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F604547%22%20target%3D%22_blank%22%3E%40JMSHW0420%3C%2FA%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ESorry%20I%20don't%20have%20an%20example%20data%20so%20this%20is%20fake%20code%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-cpp%22%3E%3CCODE%3EEmailEvents%0A%7C%20where%20AttachmentCount%20%26gt%3B%200%0A%2F%2F%20this%20detects%20the%20file%20and%20its%20last%20timestamp%0A%7C%20summarize%20arg_max(TimeGenerated%2C%20*)%20by%20SenderMailFromAddress%0A%2F%2F%20add%20one%20ms%20to%20make%20the%20new%20time%20*after*%20the%20record%20was%20found%20%0A%7C%20extend%20endtime%20%3D%20TimeGenerated%20%2B%201ms%20%20%0A%2F%2F%0A%2F%2F%20now%20see%20if%20the%20item%20is%20in%20EmailItems%20within%20the%20new%20time%20period%20%0A%2F%2F%20join%20to%20EmailItems%20...%20by%20....%0A%2F%2F%20is%20the%20email%20item%20seen%20in%20this%20new%20time%20window%3F%0A%7C%20where%20TimeGenerated%20between%20(endtime%20..%20now())%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EWe%20could%20also%20use%20a%20%3CSTRONG%3Edatatable%3C%2FSTRONG%3E%20to%20fake%20the%20tables%20you%20are%20using%2C%20this%20is%20what%20I%20think%20EmailEvents%20may%20look%20like%20(or%20the%20key%20columns%20at%20least)%26nbsp%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-cpp%22%3E%3CCODE%3Elet%20EmailEvents%20%3D%20datatable(AttachmentCount%3Aint%2C%20TimeGenerated%3Adatetime%2C%20SenderMailFromAddress%3Astring)%0A%5B%0A%220%22%2C%20datetime(2021-11-04T11%3A36%3A42.6616095Z)%2C%22clive%40fake.com%22%2C%0A%221%22%2C%20datetime(2021-11-03T12%3A30%3A53.4764186Z)%2C%22clive%40morefake.com%22%2C%0A%222%22%2C%20datetime(2021-11-02T12%3A30%3A53.4764186Z)%2C%22clive%40morefake.com%22%0A%5D%3B%0AEmailEvents%0A%7C%20where%20AttachmentCount%20%26gt%3B%200%0A%7C%20summarize%20arg_max(TimeGenerated%2C%20*)%20by%20SenderMailFromAddress%0A%7C%20extend%20endtime%20%3D%20TimeGenerated%20%2B%201ms%20%20%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%3CBR%20%2F%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E
Occasional Contributor

Hello to all,

 

So what I am trying to do is, is to extract extract any items (over x days) where an AIP label has changed from Confidential to another value.

 

The KEY part though is, that I am also trying to find out IF any of these item have been emailed by ANYONE after the the AIP label change has been made...

 

I STILL cannot find a way to make a 'complete' match with the 'Item' associated to an email...

 

I have the following query, which 'maps' against the InformationProtectionEvents, EmailEvents and EmailAttachmentInfo logs:

 

let LabelChange = InformationProtectionEvents
| where Time > ago(4d)
| where Activity == "DowngradeLabel"
| where LabelNameBefore contains "Confidential" and LabelName !contains "Confidential"
| where ItemPath contains "http"
| extend SenderMailFromAddress = User;
let EmailItem = EmailEvents
| join kind=inner LabelChange on SenderMailFromAddress
| summarize arg_max(TimeGenerated, *) by SenderMailFromAddress;
let EmailAttachment = EmailAttachmentInfo
| join kind=inner EmailItem on SenderObjectId
| summarize arg_max(TimeGenerated, *) by SenderObjectId;
EmailAttachment
| project ItemName, ItemPath, LabelName, LabelNameBefore, User,
SenderMailFromAddress, NetworkMessageId,
FileName, FileType, SenderObjectId

 

It does NOT perform the 'matching' I require and I would be really open to some suggestions.

 

Reach out to: @rodtrent@Gary Bushey@Ofer_Shezaf 

4 Replies
If you have the time stamp, then you can probably test if an email has been sent between that time and now

...
| where TimeGenerated between (TimeofLastChange_ .. now())
Thank you for the response @CliveWatson. Very much appreciated.

I have realised my query is not structurally correct even in its current format.

The following element is correct:

let endtime = 4d
let LabelChange = InformationProtectionEvents
| where Time > ago(endtime)
| where Activity == "DowngradeLabel"
| where LabelNameBefore contains "Confidential" and LabelName !contains "Confidential"
| where ItemPath contains "http";

Out of the above, I can extract the ItemName attribute which represents the file name where the AIP label has changed.

...the part of trying to find out IF any of these items have been emailed by ANYONE after the AIP label has changed, CANNOT be matched against the 'User' attribute ONLY.

Clive you mention the time stamp; do you mean matching within the EmailEvents log?

So you mean something like:

let EmailItems = EmailEvents
| where TimeGenerated between (endtime .. now())
| summarize arg_max(TimeGenerated, *) by SenderMailFromAddress;
let EmailAttachments = EmailAttachmentInfo
| join kind=inner EmailItems on SenderObjectId
| summarize arg_max(TimeGenerated, *) by SenderObjectId;

The above is assuming the file changed SHOULD be attachment. So I am still struggling how to work out a way to 'combine' the 'let' statements of 'LabelChange' and 'EmailAttachments'.

Again, any suggestions much appreciated.

@JMSHW0420 

 

Sorry I don't have an example data so this is fake code

 

EmailEvents
| where AttachmentCount > 0
// this detects the file and its last timestamp
| summarize arg_max(TimeGenerated, *) by SenderMailFromAddress
// add one ms to make the new time *after* the record was found 
| extend endtime = TimeGenerated + 1ms  
//
// now see if the item is in EmailItems within the new time period 
// join to EmailItems ... by ....
// is the email item seen in this new time window?
| where TimeGenerated between (endtime .. now())

 

We could also use a datatable to fake the tables you are using, this is what I think EmailEvents may look like (or the key columns at least) 

let EmailEvents = datatable(AttachmentCount:int, TimeGenerated:datetime, SenderMailFromAddress:string)
[
"0", datetime(2021-11-04T11:36:42.6616095Z),"clive@fake.com",
"1", datetime(2021-11-03T12:30:53.4764186Z),"clive@morefake.com",
"2", datetime(2021-11-02T12:30:53.4764186Z),"clive@morefake.com"
];
EmailEvents
| where AttachmentCount > 0
| summarize arg_max(TimeGenerated, *) by SenderMailFromAddress
| extend endtime = TimeGenerated + 1ms  


 

Thank you for the quick response @CliveWatson. Once again, very much appreciated.

I am going to be humble and say, not quite sure what you mean with TimeGenerated 'expansion'.

I tried to run:

let endtime = 1d;
EmailEvents
| where AttachmentCount > 0
| summarize arg_max(TimeGenerated, *) by SenderMailFromAddress
| extend endtime = TimeGenerated + 1ms
| where TimeGenerated between (ago(endtime) .. now())

...and failed with 'endtime' in the TimeGenerated of the LAST line.

IF you have the time, maybe you could just expand a little on this please?

EmailEvents does not store Attachments either which is why I am trying to link up with EmailAttachmentInfo log.

I was hoping I could use the FileName from EmailAttachmentInfo and see IF there was a match (or contains) with the ItemName from the InformationProtectionEvents log.