How To Disable SharePoint Designer on SharePoint 2010 Programmatically

Here's a little PowerShell script to disable users from using SharePoint Designer 2007 on your SharePoint 2010 sites. It is not really a complicated matter like it was during the SharePoint 2007; the only thing to note here are 3 main points:
  • you must have access to the namespace Microsoft.SharePoint.Client
  • you MUST run this script with at least Admin permissions for the Site Collection in question
  • The functionality to enable and disable this must have been set during the site collection creation. By default it is NOT. You can check that on the Site Collection properties.
Failing to attend these 2 conditions will throw you back an exception.

function Lock-SharePoint-Designer-Use([string]$url)
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null
    $rootSite = new-object Microsoft.SharePoint.SPSite($url)
    if($rootSite.RootWeb.AllowDesignerForCurrentUser -eq "true")
        $rootSite.AllowDesigner = false
        write-output "site "$($rootSite.RootWeb.Title)) "locked for SharePoint designer"
        write-output "site "$($rootSite.RootWeb.Title)) "does not allow designer to be configured for this site collection"

Additionally you can also try other configurations to increase the lockdown surface for nasty actions that can be accomplished by some users, such as :

See you later,



How to increase SharePoint performance. Use of retail and debug modes.

...when was the last time you checked your machine.config for retail="true" ?

I've heard a few times that SharePoint is a beast, a heavy monster, or is too slow, or is too boring. Truth is not many people out there are following SharePoint best practices. Just to mention one: when deploying a SharePoint solution many people overlook a simple switch that can make a huge difference and and have serious implications when we are talking about performance: The debug switch.
Maybe because it is too simple find in the web.config, maybe because it is too easy to change using notepad... the truth is: a lot of extra plumbing work is done when an application in debug mode is released to your users.
Scenario: we have a SharePoint page that has a delegate control. that delegate control loads a custom ascx that's deployed as a feature. that control might popup in many places across the whole portal.
What happens when your web.config has debug=false ?
For starters, let's take a look at the size of the generated assemblies, the number of handles created in the system and the internals of the DLL compilation.
When your SharePoint DLLs are compiled and deployed with the debug mode switch turned to false, the first thing you will notice is the assembly files. Look their sizes. They are determined by the compilation switch, not by the web.config switch. For comparison purposes I will use assemblies compiled in release mode against assemblies compiled in debug mode.

When your SharePoint web.config application has the web config debug = false SharePoint, or more precisely the .net framework, will handle the assembly reference this way:
When the user makes the very first request to a page that contains that ascx, the framework will compile that ascx into a temporary DLL. That DLL will receive a random name and it will not contain the code-behind that might be present in the GAC. The framework will also create a shadow copy of that DLL and both copies will be placed in the ASP.NET temporary folder. That reference will be returned to that page and the page will be rendered to the user.
If you get to inspect the content of one of these files you will that that a kind of 'proxy' will be generated for them with all the references for the real control stored in the 12 hive. That's generated when the first call is made to the control.

contents of the file myapps.aspx.d7b311e5_CBMResult.compiled
<?xml version="1.0" encoding="utf-8"?>
<preserve resultType="7" virtualPath="/MySharepointApp.Personalisation.MyApps/12/TEMPLATE/LAYOUTS/MySharepointApp/MyApps.aspx"
          hash="fffffff6f2b2ee5f" filehash="fffffff6c7a1c8b7"
        <filedep name="/MySharepointApp.Personalisation.MyApps/_controltemplates/AudienceTrimmedControl.ascx" />
        <filedep name="/MySharepointApp.Personalisation.MyApps/_controltemplates/LinkSection.ascx" />
        <filedep name="/MySharepointApp.Personalisation.MyApps/_layouts/application.master" />
        <filedep name="/MySharepointApp.Personalisation.MyApps/12/TEMPLATE/LAYOUTS/MySharepointApp/MyApps.aspx" />
For all the subsequent requests from other pages using that same control, the same reference will be retrieved. It means the page will apply less pressure in the server and naturally the application will perform close to its best.
Now let's navigate the site opening more pages and see what's happening in the system. The number of handles keeps a steady balance.
Now let's observe what happens if we do the same process and leave the web.config debug=true and we deploy the DLLs compiled in debug mode.
First thing we will notice is an increase in the assembly file, because the symbols added to the assembly.
It is not much of a difference, just 1-5 KB here and there.
so we are led to believe it will not increase the footprint on the system, right? Yeah.. but no...but yeah; that's not the problem, the problem will reveal itself when we inspect the page lifecycle...That's what's going to happen in this scenario.  
For every single call to the page using the control, a brand new temporary DLL will be generated and that's my friend... is a problem. You can not afford to have a portal with, let's say, 500 pages and do not suffer from (the lack of) performance management  there with every single one of these assemblies loaded. See the overhead placed in the temp folder, see the overhead placed in the SharePoint portal handler...
Let's repeat the same process as case 1 and let's open another page that uses the same control. Look at the handlers in the system. They had a significantly increase. Now imagine that with hundreds of users.
That's going to be a lot of work for the garbage collector that should not be there if the person only took time to apply some basic best practices when deploying solutions. And the garbage collection is as we know a very expensive operation to be carried (probably) that often.

What should we do then?
Avoid debug=true in production environment. User Retail=true. Maybe you can't avoid people going there to the web.config and changing the settings to debug=true and false, but you can reduce the surface for problems. And one of the very first things you apply in production is the not so much talked about: retail mode.
      <deployment retail="true" />
The retail mode is a switch in the machine.config that automatically:
  1. ignores all the debug=true switches and force them to be false.
  2. disable the trace output in the pages
  3. disable the custom errors configuration
  4. disable the debug capabilities
In short: just flicking this switch you automatically reduces the surface for performance issues and also some hacking attacks by not exposing unnecessary information on the screen in case of an application crash. And because machine.config is hierarchically higher that web.config it will take precedence over any web.config from other applications deployed to your server.
Now go there and take a look how is your retail mode set and maybe with just a little flick you can change the performance of a whole portal and offer a better experience to the users.
See you later,



How to list all the sites for a sharepoint web application using powershell script ?

Solution 1:
Here's an quick and very useful script often requested by admin guys that I'd like to share and hopefully it will be useful to someone as well: list all the sites for a SharePoint Url and its owners.
Made in PowerShell
function List-Sites([string]$url)
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration") > $null
    $rootSite = new-object Microsoft.SharePoint.SPSite($url)
    $webApp = $rootSite.WebApplication
    if($webApp.Sites.Count -gt 0)
        write-output "site url`tlast date content modified`tsite owner`tsite name`tsite url`tsite template`tsite description"
        foreach ($site in $webApp.Sites)
            $rootweb = $site.RootWeb
            foreach($template in $allwebtemplates)
                if ($template.ID -eq $rootweb.WebTemplateId)
            $lastUpdatedDate = Get-Date "1/1/2000 1:00 AM"
            foreach($web1 in $site.AllWebs)
                foreach($list in $web1)
                    if ($lastUpdatedDate -lt $list.LastItemModifiedDate)
            $SiteAdmin = new-object Microsoft.SharePoint.Administration.SPSiteAdministration($rootweb.URL)
            write-output "$($site.Url)`t$($lastUpdatedDate)`t$($site.Owner.LoginName)`t$($rootWeb.PortalName) $($rootWeb.Title)`t$($site.PortalUrl)`t$($rootWeb.WebTemplate) ( $templatename )`t$($rootWeb.Description)"

There is also a reference for the object SPSiteAdministration just in case you want to output more information.
Execute this script in the Powershell command line in your server and the output will be something like this:

Solution 2:
Not really a good solution if you have several sites; but if you just want to quickly find out the templates of a specific site alternatively you can go to your root web site and add this to your query string: /_vti_bin/owssvr.dll?Cmd=GetProjSchema
this will display the ONET.XML for that site, and if you scroll down until the Configuration node you can get the template being used currently

The admin guys are happy, developers are happy... win-win :)
See you later,



How to Customize My Links Control in SharePoint

User adoption is  everything in a successful SharePoint implementation and one of the main things to attract users to use the site is by customizing the site according to their needs or a previous product. In a lot of cases this never gets 100% done and then one day when a power users is browsing the site he can see things like that: A reference to the Microsoft product inside their own organization.

My SharePoint Sites link being displayed in the client screen
The ideal situation is for a product to be vendor/technology agnostic. From the user's point of view, he doesn't care what is the framework or the company; he just want to have access to his tools.
So, how to customize that My Links control from SharePoint web sites?
Answer: We will create a SharePoint feature to place our own ASCX control in the page instead the default SharePoint OOTB control.
First let's inspect how is this control implemented. If you open the homepage using SharePoint Designer and search for that specific part of the code you will notice that control is a SharePoint DelegateControl.
A delegate control is one of the coolest aspects of the SharePoint ecosystem. This control has the ability to render any user custom ASP.NET controls inside SharePoint pages on the fly by just changing the ControlId.
If we come back to our case, what that line is doing is: at this exact position, render the control called 'GlobalSiteLink2'.
Now remember these functionality are available to the application by features. Let's go then and search for the key 'GlobalSiteLink2' in the TEMPLATE\FEATURES folder on the 12 hive.

You will discover that there is a feature called 'MySite' there which implements the actual control.
Open the file MySiteFeatureElements.xml and you will see this:
   1 <Elements xmlns="">
    2   <Control Id="GlobalSiteLink1" Sequence="100" ControlSrc="~/_controltemplates/mysitelink.ascx" />
    3   <Control Id="GlobalSiteLink2" Sequence="100" ControlSrc="~/_controltemplates/mylinks.ascx"/>
    4   <Control Id="ProfileRedirection" Sequence="100" ControlSrc="~/_controltemplates/mysiteredirection.ascx"/>
    5 </Elements>
there it is our control Id='GlobalSiteLink2' and its source is in a file called 'mylinks.ascx'.
Next step, we need to find out the mylinks.ascx control. For that you have to navigate to the user controls folder at the 12 hive ($\TEMPLATE\CONTROLTEMPLATES). There you will see all the user controls available to SharePoint.  Let's have a look at the source code of this control.

Code Snippet
  1. <%@ Control className="MyLinksUserControl" Language="C#" Inherits="Microsoft.SharePoint.Portal.WebControls.MyLinksUserControl&#44;Microsoft.SharePoint.Portal, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
  2. <%@ Register Tagprefix="OSRVWC" Namespace="Microsoft.Office.Server.WebControls" Assembly="Microsoft.Office.Server, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
  3. <%@ Register Tagprefix="SPSWC" Namespace="Microsoft.SharePoint.Portal.WebControls" Assembly="Microsoft.SharePoint.Portal, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
  4. <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
  5. <table><tr>
  6. <td class="ms-globallinks"><SPSWC:MyLinksMenuControl id="MyLinksMenu" runat="server" /></td>
  7. <td class="ms-globallinks"><asp:Literal id="hlMySiteSpacer" runat="server" /></td>
  8. </tr></table>

We now see that MyLinksMenu is an object of MyLinksMenuControl, and this class is defined inside Microsoft.SharePoint.Portal.WebControls.Dll

That's good news. We find a method called LoadMenuItems() that returns an array list of menu items.
Ok. At this point we have to question ourselves something very important: We should avoid as much as we can interfere during the natural course of SharePoint's behavior. Given that method call we assume that instead modifying it we should be able to configure that string somewhere in the configuration files and then LoadMenuItems() would just return the items with the new label. Would not be the easier and most logical way for Microsoft and everybody else to modify that value?
As much as this proposition might sound correct, unfortunately the answer is no. That string is hardcoded somewhere into the SharePoint source code as a resource file and embedded within the DLL. If you try to inspect that, here's what you get:
The funny thing is that many other areas and messages and labels across the whole SharePoint platform can be configured by updating the resource files, makes you wonder:  "why they did not used the same approach here?"
So, how to fix that?
Using the same delegate control to render your control instead of the out of the box one; and to avoid breaking the natural SharePoint flow of things we are going to create a control inheriting from the OOTB SharePoint MyLinksMenuControl.
We should start by creating a solution that looks like this with WSPBuilder. We will mimic the complete structure for MyLinks.ascx's feature and give it another name.
Compile the solution for the very first time and then extract the public key token. Go to the folder where the DLL is located and execute this command.
Copy and paste the public key token displayed in the screen in our next step, into the ascx source code.
Now will create a similar ascx control just like the original one, but instead of using the webcontrols part we will be using our own MyCustomLinksMenu.ascx
Code Snippet
  1. <%@ Control className="MyLinksUserControl" Language="C#" Inherits="Microsoft.SharePoint.Portal.WebControls.MyLinksUserControl&#44;Microsoft.SharePoint.Portal, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
  2. <%@ Register Tagprefix="OSRVWC" Namespace="Microsoft.Office.Server.WebControls" Assembly="Microsoft.Office.Server, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
  3. <%@ Register Tagprefix="SPSWC" Namespace="CustomizeMyLinks" Assembly="CustomizeMyLinks, Version=, Culture=neutral, PublicKeyToken=995e4d025d306cec" %>
  4. <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
  5. <table><tr>
  6. <td class="ms-globallinks"><SPSWC:MyCustomLinksMenu id="MyLinksMenu" runat="server" /></td>
  7. <td class="ms-globallinks"><asp:Literal id="hlMySiteSpacer" runat="server" /></td>
  8. </tr></table>

Let's go to and get ourselves a brand new Guid for the feature. Keep this Guid, we will use it in our next step to assign it to the feature Id.
This is how it will looks like our new feature.XML.
    1 <?xml version="1.0" encoding="utf-8"?>
    2 <Feature Id="{6fed26c0-57d3-4237-afd7-722c5c13a147}"
    3         Title="Customize MyLinks menu control"
    4         Description="Renames the mention to SharePoint from the MyLinks control, to make the website more vendor agnostic"
    5         Version=""
    6         Hidden="FALSE"
    7         Scope="Site"
    8         xmlns=""
    9         ImageUrl ="">
   10   <ElementManifests>
   11     <ElementManifest Location="elements.xml"/>
   12   </ElementManifests>
   13 </Feature>

And this is our new elements.XML which is a copy from MySiteFeatureElements.XML. Note the control GlobalSiteLink2 pointing to our brand new ascx control.
    1 <Elements xmlns="">
    2   <Control Id="GlobalSiteLink1" Sequence="100" ControlSrc="~/_controltemplates/mysitelink.ascx" />
    3   <Control Id="GlobalSiteLink2" Sequence="100" ControlSrc="~/_controltemplates/MyCustomLinksMenu/MyCustomLinksMenu.ascx"/>
    4   <Control Id="ProfileRedirection" Sequence="100" ControlSrc="~/_controltemplates/mysiteredirection.ascx"/>
    5 </Elements>

And here's the code for the custom control. The comments in the code are self-explanatory.
    1 using System.Collections;
    2 using Microsoft.SharePoint.Portal.WebControls;
    3 using Microsoft.SharePoint.WebControls;
    5 namespace CustomizeMyLinks
    6 {
    7     /// <summary>
    8     /// Customize the current MyLinks menu control
    9     /// and rename the link 'My SharePoint Sites' to 'Visit Your Sites'
   10     /// </summary>
   11     public class MyCustomLinksMenu : MyLinksMenuControl
   12     {
   13         /// <summary>
   14         /// Loads the menu items.
   15         /// </summary>
   16         /// <returns>a <see cref="ArrayList"/> with
   17         /// all the menu items from <see cref="MyLinksMenuControl.LoadMenuItems"/></returns>
   18         protected override ArrayList LoadMenuItems()
   19         {
   20             // make sure you will call the out of the box method that generates
   21             // the default items in SharePoint
   22             var currentMenuItems = base.LoadMenuItems();
   24             if ((currentMenuItems != null) && (currentMenuItems.Count>0))
   25             {
   26                 // now that you have the items, you can manipulate them the way you want
   27                 SubMenuTemplate customMenuTemplate;
   28                 using (customMenuTemplate = (SubMenuTemplate) (currentMenuItems[0]))
   29                 {
   30                     if (customMenuTemplate != null)
   31                     {
   32                         customMenuTemplate.Text = "Visit Your Sites"; // or any other text you want here
   33                         currentMenuItems.RemoveAt(0);
   34                         currentMenuItems.Add(customMenuTemplate);
   35                         // you can also try currentMenuItems.InsertAt(0,customMenuTemplate);
   36                     }
   37                 }
   38             }
   39             return currentMenuItems;
   40         }
   41     }
   42 }

Compile. Build the package with WSPBuilder and deploy the feature to the 12 hive, activate the feature in the web site and voilá! You will see the link customized.
See you later



Workaround for Aptimize bug and list access denied in SharePoint

Update: It looks like this was a false positive. Yes, all the errors could be replicated by switching the Aptimize on and off but I could not reproduce this issue in a brand new environment which means, Aptimize might not be the problem here but other environmental issues.
As soon as I have more news/fix/info about it I will update this post. Thanks to all the Aptimize people for the contact and great support on this case.

If you are using a product called Aptimize for SharePoint you might have noticed that it is a great product when it comes to minimizing the footprint in the front end and reducing the rendered size of the output. Unfortunately with great power comes also some inconvenient bugs. Like the one below.
In our test scenario we will have a normal SharePoint document library...
...with versioning, content approval and major and minor versions enabled.
...Nothing unusual here. Very well.
Then we will have a custom SharePoint page with a custom webpart in it that does a simple thing: loop through the specified library and builds up a list of those items who are published or have a published version.
1 private static void LoadFake(SPSite site, string virtualLibraryPath, IDictionary<string, bool> fake)
2 {
3 using (SPWeb web = site.OpenWeb(virtualLibraryPath))
4 {
5 SPList list = web.GetList(virtualLibraryPath);
6 SPListItemCollection items = list.Items;
7 foreach (SPListItem item in items)
8 {
9 if(item.HasPublishedVersion)
10 {
11 // do anything here...
12 }
13 }
14 }
15 }
The code above works EXCEPT if you have at least one item in that library in pending approval state AND you have APTIMIZE installed in the server; then you will see that SharePoint error.
error: access denied - current user - you are currently signed in as: xxx - sign in as a different user
If you go to the event viewer you will notice that Aptimize might be running with no problems at all.
Aptimize Website Accelerator initialized successfully.
Enabled: True
RunMode: Development
AutoVersionUrls: True
UseAlternateAutoVersionUrlFormat: False
NewInstall: True
UseDefaultSystemProxy: False
MaxOptimizationsPerSecond: 50
CacheMaxMemory: 100
ResourceSetCacheMaxAge: 172800
PageSpriteCacheMaxAge: 28800
HandlerName: wax.axd
RunAsDaemon: False
PreviewMode: False
IncludeOriginalImageUrl: False
InlineCssImagesOnVista: True
ForceGzipOn: False
ForwardClientAddress: False
PageCachingEnabled: False
PageCachingVaryBy: Cookie
IncludeFromDomains: ThisDomain
DiskCacheCleanupInterval: 60
MemoryCacheCleanupInterval: 1
ResourceClientCacheDuration: 259200
ResourceRecheckInterval: 60
PageClientCacheDuration: 30
PageRecheckInterval: 10
Action: Exclude
CombineStyleSheets: All
CombineImages: All
HttpCompression: Smallest
CombineBodyScripts: All
CombineHeadScripts: All
InlineCssImages: True
MaxInlineImageSize: 1200
BodyScriptInsertionPoint: BodyStart
HeadScriptInsertionPoint: BodyStart
AsyncScriptLoading: False
AsyncStyleSheetLoading: False
LogInfoLevel: Info
ProxyCacheable: False
ShrinkCss: True
ShrinkScripts: True
ShrinkImages: True
JpegQuality: 85
ConvertGifToPng: False
HttpFetchTimeout: 5000
EnableClientApi: False
CacheableMimeTypes: text/css,text/javascript,application/x-javascript,image/gif,image/png,image/jpeg,image/jpg,image/bmp,image/x-icon,application/x-shockwave-flash
CompressableMimeTypes: text/html,application/xhtml+xml,text/css,text/javascript,application/x-javascript,text/xml,application/xml,application/json

But then a lit bit later you will see these two entries in the event log
Error initializing Safe control - Assembly:Mondosoft.Ontolica.SharePoint.Reporting, Version=, Culture=neutral, PublicKeyToken=c7127db7656685c6 TypeName: Mondosoft.Ontolica.SharePoint.Reporting.WebControls.WebParts.ReportingWebPart Error: Could not load file or assembly 'Microsoft.ReportingServices.SharePoint.UI.WebParts, Version=, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its dependencies. The system cannot find the file specified.
For more information, see Help and Support Center at
The description for Event ID ( 8214 ) in Source ( Windows SharePoint Services 3 ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. You may be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following information is part of the event: A request was made for a URL, http://xx.xx.xx.xx, which has not been configured in Alternate Access Mappings. Some links may point to the Alternate Access URL for the default zone, http://www.www.ww. Review the Alternate Access mappings for this Web application at http://myserver:9100/_admin/AlternateUrlCollections.aspx and consider adding as a Public Alternate Access URL if it will be used frequently. Help on this error:
If you now go to the Aptimize console and turn off the website optimization, the error goes away.
The curious thing. if you debug that code above you will noticed that an exception will happen at line #9.
Apparently Aptimize is doing something under the hood that causes a privilege exception when calling SPListItem.HasPublishedVersion even if you are running as System Administrator and even if you are running using RunWithElevatedPrivileges method. Inspect the returned error and it will see an UnauthorizedAccessException.
The fix for now is to avoid calling HasPublishedVersion until we hear back from the Aptimize guys.
If someone out there seen the same issue and would like to share any ideas, feel free. Meanwhile I hope this workaround helps someone.
See you later



How to create your own SharePoint HttpContext

Quick and short. Here's a function that I use to create my own SharePoint HttpContext objects outside the SharePoint websites domain. I hope it is somehow useful to someone out there as well.

    1         /// <summary>
    2         /// Enables a share point call from anywhere by creating your own context.
    3         /// </summary>
    4         /// <param name="siteCollectionUrl">The site collection URL where you want to create the context.</param>
    5         /// <example>
    6         /// EnableSharePointCallByCreatingYourOwnContext("");
    7         /// </example>
    8         private void EnableSharePointCallByCreatingYourOwnContext(string siteCollectionUrl)
    9         {
   10             using (var site = new SPSite(siteCollectionUrl))
   11             {
   12                 using (var web = site.OpenWeb())
   13                 {
   14                     // assumes that context does not exists
   15                     var contextCreated = false;
   17                     // if it does not exists, then create it
   18                     if (HttpContext.Current == null)
   19                     {
   20                         contextCreated = true;
   21                         // creates a request object for the current web URL
   22                         var request = new HttpRequest(string.Empty, web.Url, string.Empty);
   24                         // open the pipe to output the http stream
   25                         HttpResponse httpResponse;
   26                         using (var responseWriter = new StringWriter())
   27                         {
   28                             httpResponse = new HttpResponse(responseWriter);
   29                         }
   31                         // creates the context
   32                         HttpContext.Current = new HttpContext(request, httpResponse);
   34                         // HttpHandlerSPWeb is a the property name where you must assign the current web
   35                         // in order to associate the newly created context to sharepoint
   36                         if (HttpContext.Current.Items != null)
   37                         {
   38                             HttpContext.Current.Items["HttpHandlerSPWeb"] = web;
   39                         }
   40                     }
   42                     // ...
   43                     // do whatever you want to do here
   44                     // ...
   46                     // return the application context to the original state prior the execution
   47                     if (contextCreated)
   48                     {
   49                         HttpContext.Current = null;
   50                     }
   51                 }
   52             }
   53         }

See you later



How to Fix SharePoint MySite Auto-Creation Errors During Self Service ?

SharePoint MySites features is one of the best social features in the platform. It effectively gives to the end user control to his own area leveraging even more the collaboration capabilities of the enterprise.
One of these days we had a strange issue when creating my sites, which should be a trivial task. When an end user goes to his MySite link for the very first time the MySite creation can be automatically triggered, instead this error message was being displayed.
there has been an error creating the personal site. Contact your site administrator for more information.

With not so many clues to inspect this case we went to take a look at the event viewer to see what's going on.

When we saw this exception logged.
The site /personal/edge could not be created.  The following exception occured: Failed to instantiate file "default.master" from module "DefaultMasterPage": Source path "default.master" not found. For more information, see Help and Support Center at
A little bit further, we see some more exceptions related to that previous entry where we can see a more detailed explanation for the error.
My Site creation failure for user 'CORP\edge' for site url 'http://my.portaldev/personal/edge. The exception was: Microsoft.Office.Server.UserProfiles.PersonalSiteCreateException: A failure was encountered while attempting to create the site. ---> Microsoft.SharePoint.SPException: Failed to instantiate file "default.master" from module "DefaultMasterPage": Source path "default.master" not found. ---> System.Runtime.InteropServices.COMException (0x81070587): Failed to instantiate file "default.master" from module "DefaultMasterPage": Source path "default.master" not found.
   at Microsoft.SharePoint.Library.SPRequestInternalClass.ApplyWebTemplate(String bstrUrl, String& bstrWebTemplate, Int32& plWebTemplateId)
   at Microsoft.SharePoint.Library.SPRequest.ApplyWebTemplate(String bstrUrl, String& bstrWebTemplate, Int32& plWebTemplateId)
   --- End of inner exception stack trace ---
   at Microsoft.SharePoint.Library.SPRequest.ApplyWebTemplate(String bstrUrl, String& bstrWebTemplate, Int32& plWebTemplateId)
   at Microsoft.SharePoint.SPWeb.ApplyWebTemplate(String strWebTemplate)
   at Microsoft.SharePoint.Administration.SPSiteCollection.Add(SPContentDatabase database, String siteUrl, String title, String description, UInt32 nLCID, String webTemplate, String ownerLogin, String ownerName, String ownerEmail, String secondaryContactLogin, String secondaryContactName, String secondaryContactEmail, String quotaTemplate, String sscRootWebUrl, Boolean useHostHeaderAsSiteName)
   at Microsoft.SharePoint.SPSite.SelfServiceCreateSite(String siteUrl, String title, String description, UInt32 nLCID, String webTemplate, String ownerLogin, String ownerName, String ownerEmail, String contactLogin, String contactName, String contactEmail, String quotaTemplate)
   at Microsoft.Office.Server.UserProfiles.UserProfile.<>c__DisplayClass2.<CreateSite>b__0()
   --- End of inner exception stack trace ---
   at Microsoft.Office.Server.UserProfiles.UserProfile.<>c__DisplayClass2.<CreateSite>b__0()
   at Microsoft.SharePoint.SPSecurity.CodeToRunElevatedWrapper(Object state)
   at Microsoft.SharePoint.SPSecurity.<>c__DisplayClass4.<RunWithElevatedPrivileges>b__2()
   at Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode)
   at Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(WaitCallback secureCode, Object param)
   at Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(CodeToRunElevated secureCode)
   at Microsoft.Office.Server.UserProfiles.UserProfile.CreateSite(String strRequestUrl, Boolean bCollision, Int32 lcid).

For more information, see Help and Support Center at
So there we go. There is a clue indicating the a file called default.master was not found where it was supposed to be. We step into the Microsoft.SharePoint.Library.SPRequest class to understand what the method ApplyWebTemplate does but not much can be told from there as we can see in the picture. Also there is another method call to a private member, and probably obfuscated by Microsoft, which we can not debug.
In these cases, there is a straight forward thing to do which is if possible, compare against a working version of SharePoint and see the differences. Luckily we had one and we noted that (for some reason) the files in the SPSPERS were missing in the 12 hive.
  • \XML\onet.xml
  • blog.xsl
  • default.aspx
We just put the files back in there and it is all good and back to normal. If you ever have this problem  also pay special attention if you have done any modifications in these templates.
See you later,