This is one of those posts that’s been in my head for a while. I had some time on the couch last weekend and was prompted by a question in the SharePoint forums so I spent some time looking into the inner workings of a Record in SharePoint 2010. This is part 1 of 2 where I’ll list my findings regarding how SharePoint (internally) declares items as a record. In other words, what really happens when you click “declare as record” in the UI. Part 2 will use this info to create a search page to allow users to search all records.
Most of this was discovered using ILSpy to look into the methods SharePoint uses when an item is declared a record and when it needs to determine if an item is a record. I’ll start with the latter.
Within the Microsoft.Office.RecordsManagement.RecordsRepository namespace within the Microsoft.Office.Policy assembly, there is a method called Records.IsRecord(SPListItem item). Long story short, that method will eventually get you to a common utility method called GetHoldAndRecordStatus which pulls out the value of a HoldRecordStatus field:
Title | Hold and Record Status |
Internal Name | _vti_ItemHoldRecordStatus |
GUID | 3AFCC5C7-C6EF-44f8-9479-3561D72F9E8E |
Microsoft.SharePoint.Publishing.FieldId | HoldRecordStatus |
Hidden | True |
Type | Double |
A few notes here. First, notice it’s a Double. Hmmm, magic numbers? Maybe. Also notice it’s hidden, and it seems to cover both items on hold and flagged as a record judging by the name. If you pull out the value of this column from an item that has been marked as on hold or as a record, here are the values you’ll see:
Normal record | Empty, or 0 |
Hold | 4353 |
Record | 273 |
I’m sure there are other combinations of numbers that will work, judging on how the math is done internally in the other methods. Basically, they add a mask (int) depending on what you’re doing. The mask for records is 16 and the mask for holds is 4096. Someone better at math can open up those classes and let me know how the numbers are actually used.
Another column that’s used in this process is:
Title | Declared Record |
Internal Name | _vti_ItemDeclaredRecord |
GUID | f9a44731-84eb-43a4-9973-cd2953ad8646 |
Microsoft.SharePoint.Publishing.FieldId | DeclaredRecord |
Hidden | False |
Type | DateTime |
This is basically the timestamp for when the item was declared a record. It gets populated when the item is declared, and cleared out when it’s undeclared. Note that it’s not hidden.
Now we know two properties on the list item that are set when an item is declared a record. Now what? How about we use them to search for all records?!?
I think that I have found the meaning of the Hold and Record Status mask.
The mask for the Hold and Record Status field is defined by the internal class Microsoft.SharePoint.Publishing.HoldAndRecordStatusMask which is the following enum
internal enum HoldAndRecordStatusMask
{
DeleteBlockedMask = 0x100,
EditBlockedMask = 1,
HoldMask = 0x1000,
RecordMask = 0x10
}
The 273 value equal 0x0111, which defines that the items is declared as record and that edit and deleted are blocked.
Best Regards
Allan Juncher Pedersen
Nice find, Allan. Thanks for solving that mystery and sharing.
…and so,
4353 => 1101 (Hold, DeleteBlocked, EditBlocked)
Hi;
I’m new to SharePoint and already hit this issue.
How can I change a Declared Record and make it deleteable 🙂 meaning to set it so I’ll be able to delete it?
Is there any way to do it through PowerShell commands?
Thanks a lot
Have a great day
Eric