While performing some testing as part of my current SharePoint 2007 migration project, I encountered the following error when accessing the Add Users link from People and Groups:
Object reference not set to an instance of an object. at Microsoft.SharePoint.SPRoleDefinitionCollection.Init()
at Microsoft.SharePoint.SPRoleDefinitionCollection.Undirty()
at Microsoft.SharePoint.SPBaseCollection.System.Collections.IEnumerable.GetEnumerator()
at Microsoft.SharePoint.ApplicationPages.AclInv.InitPage()
at Microsoft.SharePoint.ApplicationPages.CBaseAclPage.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
I also received the same error message when going to the Site Permissions page of the same site. Going to either screen in other sites in the same site collection did not have this issue so at least it wasn’t a wide spread problem.
A quick search returned
this forum post of someone encountering the same issue along with some responses indicating this was a mismatch between the Roles and Groups tables in the database. I didn’t want to edit the database directly as this would take the installation into an unsupported state and was about to continue searching when I saw in the last forum response that re-inheriting the site permissions also fixed this issue.
Along with the information about there being missing information in the database led me to the conclusion that something on those two pages was missing (a user or permission group perhaps) but this hadn’t be registered in the database properly. But how can I get to the re-inherit permissions screen if I can’t get to the Site Permissions page in the first place?
I contemplated digging through the source to figure out where that menu link takes you but instead figured this might be something I could achieve with the object model and hence Powershell! Another quick search revealed that SPWeb.ResetRoleInheritance() was what I needed so I fired up Powershell to see if I could resolve the issue.
First off I need a reference to my site (or Web in proper terminology):
$site = New-Object Microsoft.SharePoint.SPSite("http://my.intranet.local/sites/subsite/")
$web = $site.OpenWeb()
Now I could just immediately call $web.ResetRoleInheritance() but I first wanted to see if I could see what permissions are currently assigned to the site so I can try and put them back to their original state once the permissions are re-inherited.
$web.Permissions | ft Member,PermissionMask
I’m using format-table (or the abbreviated ft rather) to show just the Member and PermissionMask columns in a nicely formatted table which gives me the following:
Member PermissionMask
------ --------------
Intranet Owners FullMask
Intranet Visitors 138612833
Site Owners FullMask
Site Members 1011045712
Subsite Owners FullMask
Subsite Members 1011045712
Subsite Visitors 138612833
So what permission levels do the PermissionMask values correspond to? I can presume that FullMask = Full Control and can take a guess that 138612833 corresponds to Read and 1011045712 corresponds to Contribute but it would be nice to confirm this.
I decided to get a list of the permission levels assigned to the site by doing the following:
$web.Roles | ft Name,PermissionMask
Which gave me the following:
Name PermissionMask
---- --------------
Full Control FullMask
Design 1012866047
Manage Hierarchy 2129075183
Approve 1011028991
Contribute 1013125871
Read 138612833
Restricted Read 196641
Limited Access OpenWeb, BrowseUserInfo
View Only 138612801
From this I can see that FullMask does indeed equate to Full Control and that 138612833 corresponds to Read as suspected, but interestingly 1011045712 does not exist at all. This confirmed my suspicion that a missing entry had caused the original fault – in this case it looks like a custom Permission Level may have been removed from the site. I would have thought SharePoint would handle this gracefully but perhaps not though I haven’t gotten around to confirming this yet.
At any rate, all that was left for me to do was re-inherit the permissions using the following:
$web.ResetRoleInheritance()
$web.Update()
Once this was done I could access both the Add User and Site Permissions screens successfully and was able to manually break the permission inheritance and reconfigure as required!