Setting several SharePoint sites read only

Setting a SharePoint site collection is quite an easy task. Setting several sites and subsites read only is not. There’s no cmdlet available to set one or more SharePoint sites read only.

For me read only means that all the permissions that exist are being put to “Read”. So here’s the script that does all the magic:

There are 3 parameters: The LogFilePath (for instance c:\temp\log.txt) where the old permissions are being written to for later consultation. The SiteUrl of the SharePoint site collection where the sites are located. And the exclusionSitesTitles is an array of titles of sites that should not be put read only. You can also change these to URLs, but then you have to edit the AllWebs line:

$webs = $site.AllWebs | ?{-not ($exclusionSitesTitles -contains $_.Title)}

Param (
  [Parameter(Mandatory=$True, Position=0)]
  [string]$LogFilePath,

  [Parameter(Mandatory=$True, Position=1)]
  [string]$SiteUrl,

  [Parameter(Mandatory=$True, Position=2)]
  [string[]]$exclusionSitesTitles
)

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
$site = New-Object Microsoft.SharePoint.SPSite($siteUrl)
$webs = $site.AllWebs | ?{-not ($exclusionSitesTitles -contains $_.Title)}

function checkPermissions([Microsoft.SharePoint.SPRoleAssignmentCollection]$roles)
{
	$roles | Out-File -Append -FilePath $logfilepath
	$roles | %{
		if($_.RoleDefinitionBindings.Count -eq 1 -and $_.RoleDefinitionBindings.Contains($guestPermission))
		{
			$_.RoleDefinitionBindings.RemoveAll();
		}
		else
		{
			$_.RoleDefinitionBindings.RemoveAll();
			$_.RoleDefinitionBindings.Add($readPermission);
		}
		$_.Update();
	}
}

function checkLists($web)
{
	$web.Lists | %{
		if($_.HasUniqueRoleAssignments)
		{
			checkPermissions($_.RoleAssignments)
		}
	}
}

$webs | %{
	$readPermission = $_.RoleDefinitions.GetByType([Microsoft.SharePoint.SPRoleType]::Reader);
	$guestPermission = $_.RoleDefinitions.GetByType([Microsoft.SharePoint.SPRoleType]::Guest);
	$_.Url | Out-File -Append -FilePath $logfilepath
	if($_.HasUniqueRoleAssignments)
	{
		checkPermissions($_.RoleAssignments)
	}
	checkLists($_)
	$_.Dispose();
}
$site.Dispose();

Enable-SPSessionStateService; Check your SQL permissions

Enable-SPSessionStateService will do the following:

Creates a session state database and turns on the session state service.

Nice! Everything runs smoothly until the following health rule generates a warning:

Expired sessions are not being deleted from the ASP.NET Session State database.

Strange? Not so. According to the permissions and security settings article, your main account only needs dbcreator and securityadmin rights. But, when you enable the session state service, a job has to be created under the SQL Agent Service, which you need sysadmin rights for. So if your account only has dbcreator and securityadmin at runtime, kindly ask the SQL team to give sysadmin for just a sec.

If you already created the service application with the wrong SQL permissions, you can always manually create a job under the SQL Agent Service to execute the “DeleteExpiredSessions job”.

Sandboxed code execution request failed

Update 19/08:

Seems that by doing the following steps, you reset the sandbox account permissions and set them back correctly:

  1. Put the farm account as managed account for the sandbox service
  2. Remove the sandbox service managed account
  3. Add the sandbox service account back as managed account
  4. Stop the sandbox service
  5. Put the sandbox account back as managed account for the sandbox service
  6. Start the sandbox service

Update 16/08:

For people who still have issues with their sandbox permissions, there’s a “workaround” that can be applied so that the sandbox worker process doesn’t have to use farm credentials for it to work. In essence you force user solutions to run on the same server where the call was made.

Open up central administration and go to system settings:

system settings

Next, click on manage user solutions:

manage user solutions

Here, select the “All sandboxed code runs on the same machine as a request” and click ok:

all sandboxed code runs on the same machine as a request

That should “solve” most of the problems. It takes out the flexibility sandbox solutions offer and can be considered a temporary fix.

Original Solution

“Sandboxed code execution request failed”; The error I always received while trying to execute a sandboxed webpart on my web front end, while the Sandboxed Code Service was running on an application server. Both with different credentials.

web application sandboxed code service

After investigation and fiddling out how sandboxed code is managed, the problem could be narrowed down to a permission issue. When starting the sandboxed code service on the web front end, everything seemed to run fine. So what was not set right?

Firstly, the managed service account that runs the sandbox service has to be a member of the group “Performance Monitor Users”

performance monitor users

Secondly, the managed service account which runs the web application pool is never added to the “WSS_WPG” group on the application servers.

wss_wpg

After adding the service account of the web application pool to the WSS_WPG group on the application server, the sandboxed web parts ran without any issues.