Planning Deployment of Farm Solutions for SharePoint 2013

Summary:  Mads Damgård, a Senior Microsoft Premier Field Engineer (and Microsoft Certified Master in SharePoint!) based in Denmark, provides insight and walks us through some of the things you need to consider when deploying farm solutions for SharePoint 2013, along with things to watch out for, and tips on code patterns.     

SharePoint 2013While everyone is talking about Apps, there are still significant investments in Full Trust Solutions (a.k.a. Farm Solutions) and I am sure that many OnPrem deployments will want to carry these forward when upgrading to SharePoint 2013.  The new SharePoint 2013 upgrade model allows Sites to continue to run in 2010 mode after upgrading and each Site Collection explicitly has to be upgraded individually.  Not the way it worked in 2010 with Visual Upgrade, but this time there is actually both a 14 and 15 Root folder deployed and all the Features and Layout files from SharePoint 2010 are deployed as part of the 2013 installation.

For those of you new to SharePoint, the root folder is where SharePoint keeps most of its application files and the default location for this is “C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\[SharePoint Internal Version]”, where the versions for the last releases have been 60 (6.0), 12, 14, and now 15. The location is also known as “The xx hive.

This is great in an upgrade scenario, where you may want to do a platform upgrade first or only want to share the new features of 2013 with a few users while maintaining an unchanged experience for the rest of the organization.  This also gives us the opportunity to have different functionality and features for sites running in 2010 and 2013 mode.  However, this requires some extra thought in the development and deployment process that I will give an introduction to here.

Because you can now have Sites running in both 2010 and 2013 mode, SharePoint 2013 introduces a new concept of a Compatibility Level.  Right now it can only be 14 or 15, but you can imagine that there is room for growth.  This Compatibility Level is available at Site Collection and Site (web) level and can be used in code constructs and PowerShell commands.  I will start by explaining how you use it while building and deploying wsp-files for SharePoint 2013 and then finish off with a few things to watch out for and some code tips.

Deployment Considerations

If you take your wsp-files from SharePoint 2010 and just deploy these with Add-SPSolution -> Install-SPSolution as you did in 2010, then SharePoint will assume it is a 2010 solution or a “14” mode solution.  If the level is not specified in the PowerShell command, it determines the level based on the value of the SharePointProductVersion attribute in the Solution manifest file of the wsp-package.  The value can currently be 15.0 or 14.0. If this attribute is missing, it will assume 14.0 (SharePoint 2010) and since this attribute did not exist in 2010, only very well informed people will have this included in existing packages.

For PowerShell cmdlets related to installing solutions and features, there is a new parameter called CompatibilityLevel. This can override the settings of the package itself and can assume the following values: 14, 15, New, Old, All and “14,15” (the latter currently also means All).  The parameter is available for Install-SPSolution, Uninstall-SPSolution, Install-SPFeature and Uninstall-SPFeature.  There is no way to specify “All” versions in the package itself – only the intended target – and therefore these parameters need to be specified if you want to deploy to both targets.

It is important to note that Compatibility Level impacts only files deployed to the Templates folder in the 14/15 Root folder. That is:  Features, Layouts-files, Images, ControlTemplates, etc.  This means that files outside of this folder (e.g. a WCF Service deployed to the ISAPI folder) will be deployed to the 15/ISAPI no matter what level is set in the manifest or PowerShell.  Files such as Assemblies in GAC/Bin and certain resource files will also be deployed to the same location regardless of the Compatibility Level.

It is possible to install the same solution in both 14 and 15 mode, but only if it is done in the same command – specifying Compatibility Level as either “All” or “14,15”.  If it is first deployed with 14 and then with 15, it will throw an exception.  It can be installed with the –Force parameter, but this is not recommended as it could hide other errors and lead to an unknown state for the system.

The following three diagrams illustrate where files go depending on parameters and attributes set (click on the individual images for a larger view). Thanks to the Ignite Team for creating these. I did some small changes from the originals to emphasize a few points.




When retracting the solutions, there is also an option to specify Compatibility Level.  If you do not specify this, it will retract all – both 14 and 15 files if installed.  When deployed to both levels, you can retract one, but the really important thing to understand here is that it will not only retract the files from the version folder, but also all version neutral files – such as Assemblies, ISAPI deployed files, etc. – leaving only the files from the Root folder you did not retract.

To plan for this, my suggestion would be the following during development/deployment:

  • If you want to only run sites in 2013 mode, then deploy the Solutions with CompatibilityLevel 15 or SharePointProductVersion 15.0.
  • If you want to run with both 2010 and 2013 mode, and want to share features and layout files, then deploy to both (All or “14,15”).
  • If you want to differentiate the files and features that are used in 2010 and 2013 mode, then the solutions should be split into two or three solutions:
    • One solution (“Xxx – SP2010”), which contains the files and features to be deployed to the 14 folder for 2010 mode.  including code-behind (for things like feature activation and Application pages), but excluding shared assemblies and files.
    • One solution (“Xxx – SP2013”), which contains the files and features to be deployed to the 15 folder for 2013 mode, including code-behind (for things like feature activation and Application pages), but excluding shared assemblies and files.
    • One solution (“Xxx – Common”), which contains shared files (e.g. common assemblies or web services). This solution would also include all WebApplication scoped features such as bin-deployed assemblies and assemblies with SafeControl entries.
  • If you only want to have two solutions for various reasons, the Common solution can be joined with the SP2013 solution as this is likely to be the one you will keep the longest.
  • The assemblies being used as code-files for the artifacts in SP2010 and SP2013 need to have different names or at least different versions to differentiate them. Web Parts need to go in the Common package and should be shared across the versions, however the installed Web Part templates can be unique to the version mode.

Things to watch out for…

There are a few issues that are worth being aware of that may be fixed in future updates, but you’ll need to watch out for these currently.  I’ve come across an issue where installing the same solution in both levels can go wrong.  If you install it with level All and then uninstall it with level 14 two times, the deployment logic will think that it completely removed the solution, but the files in the 15/Templates folder will still be there. To recover from this, you can install it with –Force in the orphan level and then uninstall it.  Again, it is better to not get in this situation.

Another scenario that can get you in trouble is if you install a solution in one Compatibility Level (either through PowerShell Parameter or manifest file attribute) and then uninstall with the other level.  It will then remove the common files but leave the specific 14 or 15 folder files and display the solution as fully retracted.

Unfortunately there is no public API to query which Compatibility Levels a package is deployed to.  So you need to get it right the first time or as quickly as possible move to native 2013 mode and packages (this is where we all want to be anyway).

Code patterns

An additional tip is to look for hard coded paths in you custom code such as _layouts and _controltemplates.  The SPUtility class has been updated with static methods to help you parse the current location based on the upgrade status of the Site.   For example, SPUtility.ContextLayoutsFolder will give you the path to the correct layouts folder.  See the reference article on SPUtility properties for more examples.

Round up

I hope this gave you an insight into some of the things you need to consider when deploying Farm Solutions for SharePoint 2013. There are lots of scenarios that are not covered here. If you find some, please share these or share your concerns and I will try to add it as comments or an additional post.

Written by Mads Damgård.  Posted by Frank Battiston, MSPFE Editor

Comments (9)

  1. good article, thanks for sharing

  2. Anonymous says:

    Agreed. Haven't checked if WSP Builder added that attribute. I know the built-in SharePoint 2010 tools for VS 2010 did. Also agree that both is the safest bet which covers situations where the code hasn't been updated for 2013 or is only partially updated (and hopefully using the ContextLayoutsFolder). Good discussion. 🙂

  3. Anonymous says:

    @Randy: Thank you very much for your comments. I agree with your comment around the availability of SharePointProductVersion in 2010. But just as a warning, not all tools used in the 2010 timeframe included this setting by default.

    CompatibilityLevel is a setting of the SPSite (Site Collection) as you also point out. Runtime this would be available in the executing context of a web using the SPUtility.ContextCompatibilityLevel, which would reflect the SPSite setting.

    The last comment about where to deploy solution is more debatable. True that if you are just bringing over you existing solutions and have not taken care of references as suggested in the section around Code Patterns, then the safe bet will always be to deploy it to both. However there could be reasons for later wanting to add similar files in the 14 section and this would also be a good practice to ensure compatibility with 16, 17, …

  4. Prasath C says:

    How do we do the same while updating/upgrading the solution, we don’t have compatiblelevel in Updated-SPSolution?

  5. Anonymous says:

    @Aanchal22: From an API level, the methods on the SPSolution object have not yet been extended with this property – it just calls the inner methods with a null, which means use whatever is in the manifest file (as explained in the article).

    So the only way to install it in both directories for the same Solution is to use the PowerShell scripts. This could potentially be added in a later CU depending on feedback through our support channels.

    Your best option at this time is to spawn a PowerShell process from you code and call these Cmdlets

  6. Anonymous says:

    Somehow my first comments didn't take. What I had said is that this is a good article, but there were two issues (now three with my other comment) that I noticed. First is that the SharePointProductVersion was used in the SharePoint 2010 solution schema, and I know for sure Visual Studio 2010 would use the 14.0 setting by default. Second is that the CompatibilityLevel setting only applies to SPSite, not SPWeb, since upgrade is scoped at the site collection level.

  7. Anonymous says:

    How to  install the same solution in both 14 and 15 mode programmatically without using command line or powershell scripts?

  8. Randy Williams says:

    I missed this on the first pass, but I disagree with one of your suggestions. The first one, in particular, could be a problem. "If you want to only run sites in 2013 mode, then deploy the Solutions with CompatibilityLevel 15 or SharePointProductVersion 15.0". This could cause legacy solutions from SP2010 or SP2007 to fail, even if you intend on running them in a 15 compatibility level site collection. The easiest way to understand how is think about the _layouts virtual directory in IIS. In SP2013, this continues to point to 14templatelayouts folder as it did with SP2010. When developing for SP2010 (and even 2007) it is/was very common to reference template artifacts by using the "/_layouts/…" convention. Thus, if you take an older solution package and deploy it using the 15 compatibility level setting, you are forcing the template artifacts into the 15template folders with nothing going into the 14template folders. When the code runs and tries to reference these artifacts using its _layouts syntax, it will not be found. The way this could work is if the code were changed to use the SP2013 reference convention which is "/_layouts/15/…" which I wouldn't advise. Hope this makes sense.


    Wow… This is an excellent article. It just covered very important aspects of the sharepoint migration issues and resolution. I have been searching for this information from past three days. I got the partial information on different sites and BLOGs but this is an amazing article. Mads Damgård,has demonstrated his in-depth knowledge with this article. I would like to get more articles on Sharepoint 2016 migration issues and resolutions from him. I have become a fan of him now. 🙂

    Here is my issue: We are in the process of migrating a sharepoint 2010 application to Sharepoint 2016. The application project files and Config files have been upgraded. I have created WSP files using VS 2015 IDE and provided them to SharePoint Admin. When he has deployed the WSP files on the SharePoint server the Project layouts are updated in C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\. How do we fix this issue so that we can see the files in \15\template\layouts….

Skip to main content