To match the ScopeId in the EventData property of the SPAuditEntry
to a SPListItem
you need to use the hidden column ScopeId and not the Id property of SPListItem
.
Here is what I mean.
The following XML is returned in the EventData
proprty for a SPAuditEventType
of SecRoleBindUpdate
. To match the Scope
returned in the XML to SPSite
, SPWeb
and SPList
object you would use the Id
property of this object, but not for the SPListItem
.
1 2 3 <roleid > 1073741826</roleid > <principalid > 11</principalid > <scope > 72EEC412-B14B-4EFB-AB95-EA821A3A4C63</scope >
You need to use the ScopeId
column of the SPListItem
So why can’t I just use the SPAuditQuery.RestrictToListItem
method to return the audit entries for that SPListItem
.
It doesn’t work, that’s why and this has been confirmed by MS Support.
Here is a workaround that will link the ScopeId to the SPListItem that triggered the audit entry
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 using System; using System.Collections.Generic; using System.Text; using Microsoft.SharePoint;namespace ConsoleApplication1 { class Program { static void Main (string [] args ) { string siteUrl = "http://url" ; string listName = "TheList" ; string scopeIdFromItem = string .Empty; string scopeIdFromChange = string .Empty; try { using (SPSite site = new SPSite(siteUrl)) { using (SPWeb web = site.OpenWeb()) { SPList list = web.Lists[listName]; SPRegionalSettings regionalSettings = web.RegionalSettings; SPTimeZone timeZone = regionalSettings.TimeZone; SPAuditQuery query = new SPAuditQuery(site); SPAuditEntryCollection auditEntries = site.Audit.GetEntries(query); foreach (SPAuditEntry auditEntry in auditEntries) { if (IsSecurityEvent(auditEntry)) { try { if (auditEntry.Event.ToString().ToUpper() == "SECROLEBINDUPDATE" ) { scopeIdFromChange = auditEntry.EventData.ToString().Substring((auditEntry.EventData.ToString().Length - 44 ), 36 ); foreach (SPListItem item in list.Items) { scopeIdFromItem = item["ScopeId" ].ToString().Substring(1 , 36 ); if (scopeIdFromChange == scopeIdFromItem) { Console.Write("Event Data : " ); Console.WriteLine(auditEntry.EventData.ToString()); Console.Write("Occurred : " ); Console.WriteLine(timeZone.UTCToLocalTime(auditEntry.Occurred)); if (list.BaseType == SPBaseType.DocumentLibrary) { Console.WriteLine("Security changed on file: " + item.File.ToString()); } if (list.BaseType == SPBaseType.GenericList) { Console.WriteLine("Security changed on item: " + item.Name.ToString()); } } else { Console.WriteLine("No item found in list " + siteUrl + "/" + listName + " for " + auditEntry.EventData.ToString()); } } } } catch (Exception ex) { Console.WriteLine(ex.Message.ToString()); } } } } } } catch (Exception ex) { Console.WriteLine(ex.Message); } } private static bool IsSecurityEvent (SPAuditEntry entryToTest ) { SPAuditEventType[] SECURITY_EVENTS = new SPAuditEventType[] { SPAuditEventType.SecGroupCreate, SPAuditEventType.SecGroupDelete, SPAuditEventType.SecGroupMemberAdd, SPAuditEventType.SecGroupMemberDel, SPAuditEventType.SecRoleBindBreakInherit, SPAuditEventType.SecRoleBindInherit, SPAuditEventType.SecRoleBindUpdate, SPAuditEventType.SecRoleDefBreakInherit, SPAuditEventType.SecRoleDefCreate, SPAuditEventType.SecRoleDefDelete, SPAuditEventType.SecRoleDefModify }; foreach (SPAuditEventType eventType in SECURITY_EVENTS) { if (eventType == entryToTest.Event) return true ; } return false ; } } } } }
Comment and share