SharePoint: Setting master page for publishing sites

I am upgrading local community portal from SharePoint Server 2007 to SharePoint Server 2010. I also have to write deployment scripts so other guys can also use our codebase. One thing my deployment script has to do is to force correct master pages to sites. There is one little trick you should know when setting master pages for publishing webs. Here’s how I got things work.

The problem

Publishing site have two master pages – one is custom master page that is used to show site for visitors and the other is system master page that is used with site settings etc. SharePoint publishing infrastructure allows webs to inherit master page settings from parent web. If you do something like this:


$web.CustomMasterUrl = "/_catalogs/masterpage/My.master"

then it sometimes works and sometimes it doesn’t.

How is master page inheritance defined?

SharePoint Publishing infrastructure extends SharePoint existing sites. Yes, it extends, it doesn’t replace anything. If we need to keep custom information about web we have to use web’s properties collection. Let’s see what we have there.


__WebTemplates:
__InheritsMasterUrl:  True
vti_defaultlanguage:  en-us
vti_approvallevels:  Approved Rejected Pending\ Review
__ImagesListId:  a20437ed-9fe4-41f1-8e58-7a41218f7928
__PublishingFeatureActivated:  True
vti_associategroups:  8;4;4;7;6;9;10;11;12;13;14
NavigationPropertiesSet:  True
vti_customuploadpage:  /_layouts/UploadEx.aspx
vti_filedialogpostprocessorid:  {f68e6d4e-383a-4c8d-ba4d-d2139f164281}
__DocumentsListId:  a5c43bc5-92f3-4e3e-ae9d-91228756bc53
__InheritsCustomMasterUrl:  True
__CurrentNavigationIncludeTypes:  3
vti_associatevisitorgroup:  7
vti_extenderversion:  14.0.0.4762
__InheritWebTemplates:  True
__NavigationShowSiblings:  True
__GlobalNavigationIncludeTypes:  3
__PageLayouts:  __inherit
vti_associateownergroup:  6
__DefaultPageLayout:  __inherit
__InheritsThemedCssFolderUrl:  True
__NewPageUrlToken:  __inherit
__InheritsAlternateCssUrl:  True
__PagesListId:  5a169de8-6d00-444a-882a-3a47f10422fd
vti_associatemembergroup:  8
vti_categories:  Travel Expense\ Report Business Competition Goals/Objectives Ideas Miscellaneous Waiting VIP In\ Process Planning Schedule

Okay, seems like we are on our way. Take a look at the property that I made bold. This property affects the checkbox selection on the following screenshot fragment (taken from master page settings screen).

Master page inheritance settings

You may set custom master to whatever you want but if you don’t change inheritance rule too then SharePoint still uses master page of parent web.

My solution

Here is my solution and that works for me. Besides setting master page for web I also set __InheritsCustomMasterUrl to False.


$site = new-object Microsoft.SharePoint.SPSite("$siteUrl")
$web = $site.OpenWeb("/news/blogs/")

# break custom master inheritance and set correct master
$web.AllProperties["__InheritsCustomMasterUrl"] = "False"
$web.CustomMasterUrl = "/_catalogs/masterpage/My.master"

$web.Update()
$web.Dispose(
)

One thing more to mention – this is PowerShell script here. Don’t be confused! :)

Conclusion

As with many other things the behavior of SharePoint is unintuitive. You can find a lot of different sources from web where people suggest you to set custom master page and they don’t know that it doesn’t work without additional cool porn I just described here. Changing properties like this directly is technical design flaw in SharePoint and things like these should be done through PublishingWeb or another class one day when SharePoint API evolves.

No Comments