Fix access denied errors for Claims-based authentication sites for users with permissions


Wow this was a fun issue. A web application using Claims-based authentication started giving access denied errors to ALL users after setting the values of the PortalSuperUserAccount and PortalSuperReaderAccount properties of the web application.

I won’t write much because it’s all explained in this excellent blog post by Andras Gaal.

Essentially, if you setup the accounts and give them permission via Web App Policy – you have to assign the account values using the Claims ID (i:0#.w|domain\user), NOT the (domain\user) NTLM ID.

To set the properties, use PowerShell!

$webapp = Get-SPWebApplication http://webappurl
$webapp.Properties["portalsuperuseraccount"] = "<claimsId>
$webapp.Properties["portalsuperreaderaccount"] = <claimsId>
$webapp.Update()
Advertisement

Add Cache “Super User” Account Using PowerShell


One of the things you may see in your event logs if you’re using the WCM features of SharePoint 2010 is a Warning event with ID 7362:

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 unnecessary system resources.

It goes on to say: To configure the account use the following command ‘stsadm -o setproperty -propertyname portalsuperuseraccount -propertyvalue account -url webappurl’.
Sure, I could easily type that STSADM command into my boring old CMD.exe window and solve the issue and ensure that my caching works perfectly. OR… I could play with my favorite tool, PowerShell!
After a little bit of playing, I discovered that you can do the following to set the super user account using PowerShell:

$wa = Get-SPWebApplication http://myspwebapp
$wa.Properties.Add("portalsuperuseraccount","domain\acct")
$wa.Update()
Take that STSADM!

Configure SharePoint Blob Cache using PowerShell


I am working on an installation of SharePoint 2010 For Internet Sites for my present client, and I’m automating almost everything using PowerShell cmdlets, scripts and advanced functions.
A lot of credit goes to guys like Phil Childs and Brian Lalancette for their work around PowerShell, however; today I’m thanking Ed Wilson, Scripting Guy for his post on Using PowerShell to script changes to the SharePoint Web.config file.
Thanks to this post, I was able to adapt with VERY little work to my needs. Really the only thing I needed that wasn’t provided in this set of functions was the ability to use a different location (not the default C:\BlobCache\14).
It was very easy to add another $configMod section ($configMod3) to do this, here’s the additional code I added:
I also added a parameter for $BlobCacheLocation, so you can provide the WebApplication and BlobCacheLocation values from the pipeline.
Easy, efficient and clean!
Here’s the code I added:
$configMod3 = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
$configMod3.Path = "configuration/SharePoint/BlobCache"
$configMod3.Name = "location"
$configMod3.Sequence = "0"
$configMod3.Owner = "BlobCacheMod"
##SPWebConfigModificationType.EnsureChildNode -> 0 
##SPWebConfigModificationType.EnsureAttribute -> 1
##SPWebConfigModificationType.EnsureSection -> 2 
$configMod3.Type = 1
$configMod3.Value = $BlobCacheLocation
$WebApp.WebConfigModifications.Add( $configMod3 )

Here’s the entire set of functions:

# Enable-SPBlobCache Function
function Enable-SPBlobCache { 
param( 
	[Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)]
	[Microsoft.SharePoint.PowerShell.SPWebApplicationPipeBind] 
	$WebApplication,
	[Parameter(Mandatory=$false, ValueFromPipeline=$true, Position=1)]
	$BlobCacheLocation="C:\BlobCache\14"
) 

process { 
    $WebApp = $WebApplication.Read() 
    # SPWebConfigModification to enable BlobCache 
    $configMod1 = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification 
    $configMod1.Path = "configuration/SharePoint/BlobCache" 
    $configMod1.Name = "enabled" 
    $configMod1.Sequence = 0 
    $configMod1.Owner = "BlobCacheMod" 
    ## SPWebConfigModificationType.EnsureChildNode -> 0 
    ## SPWebConfigModificationType.EnsureAttribute -> 1 
    ## SPWebConfigModificationType.EnsureSection -> 2 
    $configMod1.Type = 1 
    $configMod1.Value = "true"
		
    ######################################################################
	
	# SPWebConfigModification to enable client-side Blob caching (max-age) 
    $configMod2 = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification 
    $configMod2.Path = "configuration/SharePoint/BlobCache" 
    $configMod2.Name = "max-age" 
    $configMod2.Sequence = 0 
    $configMod2.Owner = "BlobCacheMod" 
    ## SPWebConfigModificationType.EnsureChildNode -> 0 
    ## SPWebConfigModificationType.EnsureAttribute -> 1 
    ## SPWebConfigModificationType.EnsureSection -> 2 
    $configMod2.Type = 1 
    $configMod2.Value = "86400" 
	
	######################################################################
	
	# SPWebConfigModification to change the default location for the Blob Cache files
	$configMod3 = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
	$configMod3.Path = "configuration/SharePoint/BlobCache"
	$configMod3.Name = "location"
	$configMod3.Sequence = "0"
	$configMod3.Owner = "BlobCacheMod"
	## SPWebConfigModificationType.EnsureChildNode -> 0 
    ## SPWebConfigModificationType.EnsureAttribute -> 1 
    ## SPWebConfigModificationType.EnsureSection -> 2 
	$configMod3.Type = 1
	$configMod3.Value = $BlobCacheLocation
    # Add mods, update, and apply 
    $WebApp.WebConfigModifications.Add( $configMod1 ) 
    $WebApp.WebConfigModifications.Add( $configMod2 )
	$WebApp.WebConfigModifications.Add( $configMod3 )
    $WebApp.Update() 
    $WebApp.Parent.ApplyWebConfigModifications() 
} 
}



# Disable-SPBlobCache Function
function Disable-SPBlobCache { 
param( 
    [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)] 
    [Microsoft.SharePoint.PowerShell.SPWebApplicationPipeBind] 
    $WebApplication 
) 

process { 
    $WebApp = $WebApplication.Read() 
    $mods = @() 
    foreach ( $mod in $WebApp.WebConfigModifications ) { 
        if ( $mod.Owner -eq "BlobCacheMod" ) { 
            $mods += $mod 
        } 
} 
    foreach ( $mod in $mods ) { 
        [void] $WebApp.WebConfigModifications.Remove( $mod ) 
    } 
    $WebApp.Update() 
    $WebApp.Parent.ApplyWebConfigModifications() 
} 
}

Warming up SharePoint 2010 using PowerShell


If you’ve been around SharePoint 2007, SharePoint 2010 or just .NET for any amount of time, you know that pages are not compiled until the first time a server request is made to view them. This causes the first load to be the slowest.

There have been numerous solutions for this, most of them are some form of a warm-up script.

In SharePoint 2007, there were a few versions; all of which used the command-line STSADM tool to basically enumerate all sites in a web application and then submit an HTTP request to cache the pages on the server side.

In SharePoint 2010, the STSADM based scripts still work; but why use them? We have PowerShell!

I found some really good examples of PowerShell based Warm-up scripts, but none of them served my purposes or my clients. Since I’m really starting to dig PowerShell, I decided to do my part in the SharePoint community by developing my own version of the SPWarmup script.

#################################################################################
## SPWarmUp.ps1 - Enumerates all web sites in web applications in a SharePoint  #
## 2010 farm and opens each in a browser.  This version does not use STSADM	#
## and instead uses PowerShell.							#
## 										#
## Notes:									#
## -"get-webpage" function borrowed from:					#
## http://kirkhofer.wordpress.com/2008/10/18/sharepoint-warm-up-script/		#
##										#
## Assumptions:									#
## -Running on machine with SharePoint 2010 installed				#
## Although bits and pieces were borrowed from Kirk Hofer and Martin Laukkanen,	#
## The final working version with nice enhancements is courtesy of Ryan Dennis.	#
## www.iccblogs.com/blogs/rdennis - Twitter: @SharePointRyan			#
#################################################################################
  
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

# By uncommenting the following lines as well as lines 54-60 you can warmup other sites such as SSRS #
#$extrasitelistfile = 'c:\warmup-extrasites.txt'

Start-SPAssignment -Global  
function get-webpage([string]$url,[System.Net.NetworkCredential]$cred=$null)
{
   $wc = new-object net.webclient
   if($cred -eq $null)
   {
     $cred = [System.Net.CredentialCache]::DefaultCredentials;
   }
   $wc.credentials = $cred;
   return $wc.DownloadString($url);
}
  
#This passes in the default credentials needed. If you need specific
#credentials you can pass them in to elevate the permissions.
#Or run this task as a user that has a Policy above all the Web
#Applications with the correct permissions
  
$cred = [System.Net.CredentialCache]::DefaultCredentials;
#$cred = new-object System.Net.NetworkCredential("username","password","machinename")
  
$apps = Get-SPWebApplication -IncludeCentralAdministration
foreach ($app in $apps) {
$sites = Get-SPSite -WebApplication $app.url -Limit ALL -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
foreach ($site in $sites) {
Write-Host $site.Url;
$html=get-webpage -url $site.Url -cred $cred;
}
}

## Warm up other sites specified in warmup-extrasites.txt file (such as SSRS)
#if (test-path $extrasitelistfile) {
#   $extrasites = get-content $extrasitelistfile
#   foreach ($site in $extrasites) {
#     write-host $site;
#     $html=get-webpage -url $site -cred $cred;
#   }
#}

Stop-SPAssignment -Global

Access Denied (401) on SharePoint 2010 Sites


I came across a weird error today, site collections which were working great just last week are now giving Access Denied errors. Surely I have access, I’m using the System Account… So I tried the normal things like trying to go straight to http://myintranet/_layouts/settings.aspx, etc but to no avail.

After some log reading and searching, I came across this Technet Post which triggered my memory. I was getting the SuperUser Cache warning in my Health Analyzer, so I created a domain account (DOMAIN\SPCache) and configured it to be the super user cache account. Great I thought at the time, warnings now gone, cache working, awesome… Not so awesome, this super user account needs Full Control to the Web Application(s) which it caches.

Not a big deal, I added the account to the Web Application User Policy with Full Control and Voila!; the sites are now back to normal. Whew!