Tuesday 28 September 2010

Set object caching user accounts with PowerShell

In all installations of SharePoint, it’s important to properly configure object caching so that SharePoint can efficiently retrieve cached versions of items where possible. In my experience, this is one of THE most frequently forgotten configuration steps – yet Technet is clear that SharePoint cannot perform optimally without this being done. Object caching configuration mainly involves the configuration of two specific user accounts which SharePoint will use to simulate a reader and high-privileged user. If these accounts are not configured, you’ll see entries like this in the Windows event log:

Object Cache: The super user account utilized by the cache is not configured. This can increase the number of cache misses, which causes the page requests to consume unneccesary system resources.

The full details of why this configuration is necessary are in the Technet article Configuring object cache user accounts. The article outlines the process for performing the configuration, but bizarrely (IMHO) lists a process which is half PowerShell, half manual steps in Central Admin. My guess is that, just like software, shipping documentation has compromises too, and this article didn’t yet make the cut to receive the full treatment. I’ve written some PowerShell which does the full configuration – make sure you edit it to use your account names and web application URLs. You'll need to paste this into a tool which can strip out HTML, before saving as a .ps1 file. If anyone has any trouble working with it, let me know and I'll post the actual file somewhere.

Add-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue
 
# EDIT THIS TO ENSURE ACCOUNTS ARE CORRECT FOR ENVIRONMENT..
 
$objectCachePortalSuperReader = "sp2010\portalsuperreader" 
$objectCachePortalSuperUser = "sp2010\portalsuperuser" 
 
$allWebApps = ("http://one.myCompany.com", "http://two.myCompany.com") 
 
Function ConfigureObjectCachingOnWebApp([Microsoft.SharePoint.Administration.SPWebApplication]$webApplication)
{
      Write-Host ("Processing " + $webApplication.Url);
 
      try
      {
            GrantPolicy $webApplication $objectCachePortalSuperReader FullRead
            GrantPolicy $webApplication $objectCachePortalSuperUser FullControl
 
            SetPropertyOnWebApp $webApplication "portalsuperuseraccount" $objectCachePortalSuperUser
            SetPropertyOnWebApp $webApplication "portalsuperreaderaccount" $objectCachePortalSuperReader
 
            $webApplication.Update()
 
            Write-Host -BackgroundColor DarkGreen -ForegroundColor White ("Configured " + $webApplication.Url);
      }
      catch
      {
            Write-Host -BackgroundColor DarkRed -ForegroundColor White ("Failed to configure " + $webApplication.Url + ". Error details : " + $_)        
      }
}
 
Function GrantPolicy([Microsoft.SharePoint.Administration.SPWebApplication]$webApplicationForPolicy, [string]$userOrGroup, 
      [Microsoft.SharePoint.Administration.SPPolicyRoleType]$policyLevel)
{
      $policy = $webApplicationForPolicy.Policies.Add($userOrGroup, $userOrGroup) 
      $policy.PolicyRoleBindings.Add($webApplicationForPolicy.PolicyRoles.GetSpecialRole($policyLevel)) 
}
 
Function SetPropertyOnWebApp([Microsoft.SharePoint.Administration.SPWebApplication]$webApplicationForProperty, [string]$property, 
      [string]$propertyValue)
{
      $webApplicationForProperty.Properties[$property] = $propertyValue 
}
 
# inline script starts here..
 
$confirmed = Read-Host "This script must be edited before running for correct user accounts for each environment - have you done this? Enter Y to continue or N to exit."
if ($confirmed -eq 'y')
{
      foreach($webAppName in $allWebApps)
      {
            $webApp = Get-SPWebApplication -Identity $webAppName -ErrorAction SilentlyContinue
 
            if($webApp)
            {
                  ConfigureObjectCachingOnWebApp($webApp)     

            }
            else
            {
                  Write-Host -ForegroundColor DarkRed ("Failed to find web app '" + $webAppName + "' in this environment. ")
            }
      }
}
 
Write-Host -BackgroundColor Blue -ForegroundColor White "Script completed"

8 comments:

Andras Gaal said...

Hi Chris,

On small note: if you are in claims mode, you'll need to use the claims equivalent of the username otherwise you'll end up with sharepoint serving access denied errors to all people trying to access the site.

Cheers,
Andras

Chris O'Brien said...

@Andras,

Great point, thanks!

Chris.

Anonymous said...

fantastic article and script. Thanks so much.

Anonymous said...

Hi Chris,

Could you post this as a download somewhere?

Cheers!

Vincent

Chris O'Brien said...

@Vincent,

Done - http://dl.dropbox.com/u/11342240/SetObjectCachingUsers.ps1

Thanks,

Chris.

Tina said...

Hi Chris,

I ran the script on my sharepoint environment as the servers were pegging high CPU all the time.. And now I have these errors as I try to access home page,
Error
The user does not exist or is not unique.

Troubleshoot issues with Microsoft SharePoint Foundation.

Correlation ID: cd0b7307-b096-446b-8900-4f258ade57d9

Date and Time: 5/27/2011 2:26:19 PM


Any idea why that is?

Thanks!

Chris O'Brien said...

@Tina,

I've never heard of this before, but it does smack of configuring one of the settings with a user doesn't exist. If you're 100% sure both users do exist, could there be a temporary domain connectivity issue or some such?

Cheers,

Chris.

Unknown said...

The reason for user does not exist errors is that the account isnt registered as a managed account. I did a script similar to this and added a piece to verify the account was added to managed accounts before the web app pieces.

Keith