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()
Advertisements

DAYSPUG Presentation December 13th 2011


Last night I spoke to a great crowd of PowerShell Enthusiasts at the Dayton SharePoint Users Group (DAYSPUG) in Dayton, Ohio. I knew most of the folks in attendance from other local SharePoint and PowerShell events, so it was nice to see everyone again.

It was a pleasure to speak in front of all of you, and I thoroughly enjoyed the engagement that you all showed.

Since the actual presentation/demo wasn’t much different from my recent engagement at SharePoint Saturday Cincinnati, I’ll simply point to that post for the actual PowerShell and XML code I used in the demos. That content is located here: SPS Cincinnati Post

Here is a post which contains the two Christmas functions I shared last night as well: Two PowerShell Functions for the Christmas Season

Thanks again to Tony Maddin and the rest of the DAYSPUG members for welcoming me to speak. See you all next time!

RD

SharePoint Saturday Cincinnati 2011


This past weekend I broke new ground in my career – I completed my first public speaking engagement! While I have spoken on various topics in front of my SharePoint Team at ICC – this was my first public speaking engagement and overall I think it went very well.

The topic: The Power is in the Shell, use it wisely!
The story: What is PowerShell – how does it fit into the SharePoint 2010 puzzle? How can we take commands run in the Shell and easily convert them to scripts or functions? How can we use the Get-Content cmdlet and some XML to automate content loading or migrations? What are some best practices around PowerShell as it relates to SharePoint 2010?

This was the first SharePoint Saturday in Cincinnati, and I was very proud to be a part of a great event.

My session went pretty flawlessly, as I lucked out and had zero issues with the presentation or the three demos. I had a small group of attendees, but all of them were very engaged in dialog throughout. For those of you who attended, thank you for being a part of it – and if you have any feedback or questions feel free to contact me either on Twitter or via e-mail (rdennis at iccohio dot com).

I promised to upload my slides and demo PowerShell code, so the slides are on Slideshare and the XML and PowerShell code is below:

First demo function – Set-SPWebTitle

function Set-SPWebTitle {
Param(
[string]$SiteUrl,
[string]$SiteTitle
)
$site = Get-SPSite $SiteUrl
$web = $site.RootWeb                                                                                                   
$web.Title = $SiteTitle
Write-Host "Changing title to:" $SiteTitle
$web.Update()                                                                                                          
$web.Dispose()                                                                                                        
$site.Dispose()           
Write-Host "Finished!"
}

Second demo function – New-SPWebFromXml
XML Syntax:

<?xml version="1.0" encoding="utf-8"?>
<Sites>
  	<Site>
    		<SiteTitle>Ryan Dennis</SiteTitle>
	    	<SiteUrl>http://sps.adventureworks.com/rdennis</SiteUrl>
	    	<Page>
			<PageTitle>Home</PageTitle>
			<PageUrl>Home.aspx</PageUrl>
			<PageContent>HTML Content</PageContent>
			<PageLayout>Body Only</PageLayout>
		</Page>
  	</Site>
</Sites>

PowerShell code:

function New-SPWebFromXml {
# Xml Input parameter - accepts string to filename
[CmdletBinding()]
	Param(
    [Parameter(Mandatory=$true)]
	[string]$XmlInput
	)

# Read in list of sites from XML file
[xml]$SitesXml = Get-Content $($XmlInput)
if ($SitesXml -eq $null) {return}
Start-SPAssignment -Global #Stores all objects in the global store for proper disposal
$StartTime = Get-Date #Grab the date & time for further calculation later

# Upload speaker images to the PublishingImages library
Write-Host "Uploading speaker images to the PublishingImages library..."
Add-SPFilesToLibrary -WebUrl http://sps.adventureworks.com -LibraryName PublishingImages -FileExtension "*.jpg" -FolderLocation "C:\SPSDemo\Speakers"

	# Loop through each site node to extract data
	$SitesXml.Sites.Site | ForEach-Object {
	$SiteTitle = [string]$_.SiteTitle
	$SiteUrl = [string]$_.SiteUrl
	$WebTemplate = "CMSPUBLISHING#0"
	$LangId = "1033"
	
	# Get publishing site and web objects
	$site = New-Object Microsoft.SharePoint.SPSite($SiteUrl)
	$psite = New-Object Microsoft.SharePoint.Publishing.PublishingSite($site)
	$web = $site.OpenWeb()
	$pWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
	
	# Create the SPWeb
	Write-Host "Creating an SPWeb at $($SiteUrl)"
	New-SPWeb -Url $SiteUrl	-Language $LangId -Template $WebTemplate -Name $SiteTitle
	
	# Create page content variables from XML file
	$PageTitle = [string]$_.Page.PageTitle
	$PageUrl = [string]$_.Page.PageUrl
	$PageLayout = [string]$_.Page.PageLayout
	$PageContent = [string]$_.Page.PageContent
	$PageImage = [string]$_.Page.PageImage
	$layout = $pWeb.GetAvailablePageLayouts() | Where-Object {$_.Title -match $PageLayout}
	
    # Create blank page using Add method
	Write-Host "Creating $($PageTitle).aspx page"
    $pages = $pWeb.GetPublishingPages($pWeb)
	$page = $pages.Add($PageUrl, $layout)
	$page.Update()
	
    # Update the filename to the one specified in the XML, add HTML content to Page Content zone
    $item = $page.ListItem
	$item["Title"] = $PageTitle;
	$item["Page Content"] = $PageContent;
	$item.Update()
	
    # Check-in and publish page
    $item.File.CheckIn("")
    $item.File.Publish("")
	$file = $item.File
	$pWeb.DefaultPage = $file
	$pWeb.Update()
	
	# Get and delete original default.aspx page
	Write-Host "Deleting default.aspx page"
	$list = $web.lists["Pages"]
	$oldPage = $list.items | Where-Object {$_.Name -match "default"}
	$oldPage.Delete();
	$web.Update()
	} #End ForEach-Object loop
	
$EndTime = Get-Date #Grab the ending date & time to get the timespan
$TimeSpan = New-TimeSpan $StartTime $EndTime #Calculate total time taken
Write-Host "$($SitesXml.Sites.Site.Count) sites created in $timespan"
Stop-SPAssignment -Global #Stop assignment, safely disposing all site and web objects
} #End Function

Generic Error on Listedit.aspx page after SP1 and Aug 2011 CU


Wow did this issue get under my skin.

At my current client, where their SharePoint 2010 Enterprise Intranet is about as business critical as a SP environment can be – I performed the SP1 and Aug 2011 CU updates. The updates themselves went about as smooth as could be expected, until we noticed that lists and libraries would give the generic error w/ correlation ID when navigating to the List Settings page (/_layouts/listedit.aspx).

This seemed like not too big of a deal on the first site collection we noticed it on – then we realized it was farm-wide.

After doing a lot of log-reading, re-running PSCONFIG.exe to ensure that everything completed from an upgrade perspective; we were in the dark…

This morning I noticed something while browsing through the layouts folder – listedit.aspx (and some other files) was modified on 6/8/2011 at 11:46 AM. Most of the other aspx files were showing a modified date much further in the past.

On a whim I copied listedit.aspx from a known-good farm into my broken farm and VOILA – lists and libraries work again.

This might not help anybody, because I couldn’t find anyone else having this exact issue – but I didn’t want to lose track of the “fix.”

Using PowerShell to make an entire web application read-only


STSADM.exe was great in SharePoint 2007. It provided some really good functionality, some of which was not available in the GUI. STSADM is still available in SharePoint 2010, but why anybody would use it is beyond me. PowerShell is not only much more powerful (hence the name), but it’s here to stay.
There are loads of examples of scripts online for various SharePoint tasks, and there are lots of one-offs that I’ve made scripts for that I doubt anybody else would use; however, there is one thing I think everyone may want at some point, the ability to make an entire web application read-only. Could you make the content database read-only? Sure, but maybe you want just the sites to be read-only.
In 2007, you could set a site collection as read-only via STSADM; but I was never able to find a “good” way to make an entire web application read-only. In SharePoint 2010, it’s very easy with a few commands and a ForEach loop.
Here’s the advanced function:
function Set-LockState {
<#
.SYNOPSIS
Use this PowerShell script to set the Lock State of a SharePoint Web Application to Unlock, ReadOnly, NoAdditions or NoAccess.
.DESCRIPTION
This PowerShell script uses Set-SPSiteAdministration to set the Lock State of a SharePoint Web Application.
.EXAMPLE
C:\PS>.\SetAllSitesInAWebAppToReadOnly.ps1 -WebAppUrl http://intranet -LockState ReadOnly
This example sets all site collections in a web application at http://intranet to read-only.
.NOTES
This PowerShell script sets the Lock State of a SharePoint Web Application.
.LINK
http://www.iccblogs.com/blogs/rdennis
 http://twitter.com/SharePointRyan
.INPUTS
None
.OUTPUTS
None
#>

## Input Parameters ##
[CmdletBinding()]
Param(
[string]$WebAppUrl=(Read-Host "Please enter a Web Application URL (Example: http://intranet)"),
[string]$LockState=(Read-Host "Please enter a Lock State (Examples: Unlock, ReadOnly)")
)
## Add SharePoint Snap-in ##
Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue
### No need to modify these ###
$WebApp = Get-SPWebApplication $WebAppUrl
$AllSites = $WebApp | Get-SPSite

############################# The Script - no need to modify this section #############################
## Start SP Assignment for proper disposal of variables and objects ##
Write-Host "Starting SP Assignment..." -ForegroundColor Green
Start-SPAssignment -Global
## Use a ForEach-Object loop and Set-SPSiteAdministration to set an entire web application ##
Write-Host "Setting $WebAppUrl to $lockState..." -ForegroundColor Yellow
$AllSites | ForEach-Object { Set-SPSiteAdministration -LockState $lockState -Identity $_.url }
## End SP Assignment for proper disposal of variables and objects ##
Write-Host "Disposing of SP Objects.." -ForegroundColor Green
Stop-SPAssignment -Global
## Tell us it's done ##
Write-Host "Finished!" -ForegroundColor Green
}