Tuesday, May 28, 2013

Using PowerShell to Create a New Site Collection with a Custom Site Template Definition and/or Template

OK –

Despite the help from google, this one had stumped for the better half of two hours -

To expedite development efforts i will always use automation techniques to avoid mundane and repetitive tasks.  i.e. – Developing/troubleshooting/Testing the activation of a feature with declarative xml and/or feature receiver as well as provisioning of a custom site definitions .

in the example above I’d simply have a script to:

  1. Delete an existing Site Collection (always handy if you have declarative content types – you don’t want existing features/deployments getting in your way)
  2. Create a new site collection
  3. Activate any features as required

Depending on what you’re doing, you don’t always need to redeploy the solution or even re-create the site collection – so there’s always benefit to adding a few flags at the top of the script to control execution and save costly wsp retractions/redeployments (subsequently resulting in costly app pool recycles), IIS Resets (even more costly) and site collection / sub web provisioning (which can take some time for those complex definitions involving multiple sub webs / lists and/or libraries).

A good SharePoint developer knows where to cut corners in terms of general development/deployment techniques – productivity is key in working with this platform.  If you can avoid an App Pool Recycle and/or IIS Reset with code deployments you can easily save 20 seconds per incremental deployment.  A focused developer will see one of these at least every two minutes.  30 per hour * 8 = 240.  240 deployments @ 20 seconds = 4800 seconds = 80 minutes.  You could have left yesterday at 3.40! :)

Anyway – off topic –

For this post I'd opened said PowerShell prompt a long long time ago (possibly weeks even?? – seeing as though i rarely restart my dev vms – this is more than possible).  After numerous attempts of creating/deploying my custom site definition and getting sick of creating a new site collection through the UI i looked into a programmatic provision. 

I tried the standard:

new-spsite –url http://url/sites/blah –owneralias domain\username –template TemplateName#ID –name siteName

This didn’t work :(

(it failed saying it couldn’t locate the template)

after a bit of googling, i was led down the garden path in needing to get a random guid based on the fact it was a custom template.  I tried numerous methods of getting web templates without success:

SPSite.GetWebTemplates(UInt32);

SPSite.GetCustomWebTemplates(UInt32);

SPWeb.GetAvailableWebTempaltes(UInt32);

SPWeb.GetAvailableWebTempaltes(UInt32, Bool);

SPWeb.GetAvailableCrossLanguageTemplates();

SPWeb.GetCatalog(SPListTemplateType);

None of these returned any indication of my custom site definition (yet i know it was there as I'd previously successfully created it through the central admin UI).

Anyway -

short of the story is -

PowerShell (and more accurately, the SharePoint Snap In) happens to cache the available web templates per web application when the first site/web within said web app is referenced.

Simply closing the PowerShell console, opening a new one and re-adding the snap-in allowed me to see (and more importantly create new sites from) the custom site definition. 

What’s more – didn’t have to worry about any of the guid based referencing of the template that is common in Google.  Seeing as though I've developed it as a traditional / full site definition there’s been no random guid associated with the template and I'm able to reference it as I've declared in the webtemp file.

Monday, August 13, 2012

SharePoint 2013 – Social Networking on Steroids

I’ve been playing around with the preview release of Microsoft’s latest SharePoint offering: SharePoint 2013.  First impressions are good, really good!

There’s a couple of major changes in this release, in this article I’m going to focus on the social aspects.  In comparison, the social networking capabilities offered in SharePoint 2010 now seem archaic.  Sure, the previous release included a concept of a personal wall that could be written on.  In the same way, the publishing infrastructure allowed users to provide comments and ratings on publishing pages.  While these features in their time were leaps and bounds ahead of the previous generation, discussions were flat with no chance to reply to individual comments.  These ‘discussion’ areas were also somewhat limited in terms of findability.  Comments were tied to the subject of interest (page or person) limiting the functionality in terms of a true social networking tool designed to promote collaboration through ad-hoc discussion.

SharePoint 2013 introduces a raft of new features and functionality that tackle these shortcomings head on making for a truly powerful social networking platform.

Newsfeeds

Newsfeeds (previously known as a user’s wall) are still found in user’s My Sites, but are also available in many out of the box templates.  Users can post comments, questions or general information about the subject of interest (be it a person, or a site).  What makes the newsfeed so exciting is the ability to #tag topics or @mention other users.  @Mentions are immediately made available in the associated users My Site newsfeed while #tagged posts are automatically amalgamated through Search.  The search engine constantly analyses recent posts providing visibility into real time, hot topics of discussion.  To ensure a contextual feed and meaningful discussions, posts can now be replied to! 

Users have the option to ‘Follow’ colleagues or sites.  In doing so, any comments, questions or replies posted in the respective newsfeed will also appear in their ‘My Site’ news feed.  This provides users the ability to now not only register their interest in other people, but content as well.  Finally, any comments can be liked, unliked or marked to follow up.  The latter option provides an automatic task in the user’s personal task list prompting them to respond to a comment or question.

 

image       

 

 

Community Sites

Community Sites are provided by SharePoint 2013 as an out-of-the-box template.  They are designed to facilitate and encourage ad-hoc discussion of a topic, event or specific content in a controlled and engaging fashion.  Much like a news feed, users initiate dialog through the creation of a post.  This may be a question, general comment or semi-controlled content.  In much the same way as a typical news feed, users can respond to form threaded discussions.  What’s exciting here is that comments can now be star rated or even nominated as ‘best answer’ promoting their reply to the top of the stack.  Where the community site template really shines is the use of gamification to create an engaging experience whilst encouraging desired behaviours (ie: informative, no-nonsense replies).  The functionality is provided by awarding a users positive participation with merit points based on their activity type.  Posting a reply might award the user 10 points, having another user like the response might award them another 20 points and if the answer is marked as ‘best answer’ the user may be awarded an additional 100 points and so on.  To compliment the merit points systems, each user is allocated a ranking based on the number of merit points obtained.  A users ranking is made available right along side any posts or replies providing users a simple, intuitive and fun way to quickly identify which reply might offer the most value.  Rankings (the rank names and merit points required to achieve) are configured on a site by site basis by administrators.  A promotion is awarded as an event in a users newsfeed (also showing up in the newsfeed of other colleagues following the promoted user).  Finally, site administrators have the ability to gift awards and merits to those users who may have demonstrated expertise in a subject through alternate means.

 

image image

 

The new social networking features provided by SharePoint 2013 are light years ahead of any previous version.  What use to be regarded as ‘oh, that’s kinda neat’ by our typical clients is now ‘Wow, I want that yesterday’.  Microsoft have made a smart move investing and ultimately, capitalizing in the phenomena that have made Facebook, Twitter and Linked In such huge successes.  Used properly, these features will not only initially attract employees to your new intranet, but keep them coming back!

Tuesday, July 24, 2012

SharePoint 2013 Search – Removing Inactive Search Topologies with Powershell

Real quick one (as per title):

Get-SPEnterpriseSearchServiceApplication | Get-SPEnterpriseSearchTopology |? {$_.State -eq "Inactive"} |% { Remove-SPEnterpriseSearchTopology -Identity $_ -Confirm:$false};

 

 

 

SharePoint 2013 – Unable to retrieve topology component health states…

 

I’ve just started playing with the SharePoint 2013 preview –

I had an issue provisioning the search service application in that the Search Service Application Administrative interface in Central Administration was reporting a “Unable to retrieve topology component health states.  This may be because the admin component is not up and running.”

image

 

At this stage, it’s a single server farm.  It was a fresh build of Server 2008 R2 SP1 and the server is not a domain controller or hosting SQL.

Initially I did miss a couple of additional hot fixes required after the pre-requisite installer (see step 6 in this article or grab them below)

  • KB 2554876

  • KB 2708075

  • KB 2472264

     

    After installing these hot fixes, i was still getting the same issue…

    I managed to resolve it by simply running windows update and installing all patches/hotfixes reported as critical.

    Once this had been done (and a reboot or two later) the problem was resolved!

    image

     

    The updates in installed are below (so it’s one or more of them?)

     

    image

  • Friday, December 9, 2011

    Developing a Re-Useable pattern for Deploying and Activating a custom SharePoint 2010 Master Page without Publishing

    (long winded title I know – just trying to assist anyone who might find this article of any use)

     

    Ok – so this post will hopefully outline my preferred approach in packaging and activating a custom master page and associated supporting files (.css, .js and images etc) without needing to activate the publishing features (and thus giving you the option to set through the UI)

    It’s also the standard I’ve just implemented within my current employer - Myriad Technologies – a Brisbane SharePoint Consulting Firm here in Australia… click here for more info ..

    There are a couple of other little tricks/patterns demonstrated in the article… namely:

    1. Creating / Ensuring Master Page Compatibility with a search centre / minimal.master
    2. Setting an icon of a feature
    3. Creating a feature with a feature receiver
    4. Feature Stapling

    This is not an article on how to create a custom brand or style for SharePoint 2010, nor is it an article explaining the ins and outs of masterpage development.  It’s simply a framework or pattern that can be used to ensure branding and/or style compliance for all new site’s and site collections created in your farm, web application or site collection irrespective of SKU (Foundation, Standard or Enterprise) and/or relying on the Publishing Features activation or user intervention. 

    A little visual studio knowledge is required as it will be utilized to create the wsp.  Also note I’ve chosen to use wsp builder to do my packaging… Purely because it’s what I've been using for the last 4 or 5 years and is what I'm most comfortable with.  The same pattern can be designed and built utilizing the Visual Studio 2010 SharePoint Project types if required.

    (Note: You will need the WSPBuilder Extensions 2010 Beta 1.4 package for integration with Visual Studio 2010 and SharePoint 2010)

    One final thing to note before I jump in - Having a development background, I refer to a site collection as a site and a sub site or root site as a web

     

    Solution Overview

    The end solution consists of three features as outlined in the table below.

    Feature

    Scope

    Purpose

    CustomBrandingDeployment Site Contains the Master Page, CSS File(s), Images and other supporting files required by the custom brand/style.  Activation of this feature will see the Master Pages deployed to the Master Page Catalogue in the root web of the site collection, and depending on how where you want your supporting files to live, the CSS, Javascript and/or Image files deployed to the Style Library and/or Layouts Directories
    CustomBrandingApplication Web This feature does not contain any resources, but is wired up to a block of code to execute at time of feature activation.  It is responsible for configuring the current web to use the master page(s) deployed by the CustomBrandingDeployment feature.
    CustomBrandingApplicationStapler Site* This feature is responsible for stapling the ‘CustomBrandingApplication’ feature to site definitions.  After a feature has been ‘stapled’ to an existing site definition, it’ll immediately be activated by the web provisioning process whenever a new web using that definition is being created. 

    *Note:The Scope of the ‘CustomBrandingApplicationStapler’ can be either site, webapplication or farm.  By making it scoped at the farm, all new webs created in the farm (irrespective of web application or site collection will be branded).  If you scope it at a web application, all webs created in a site collection that exist in a web application that has the feature activated will be branded.  A site collection scope will see all webs created in that site collection branded accordingly. 

    Depending on the individual requirements, any one of these scopes may be used.  At minimum, it’s designed to work at the site collection level.  If you do scope it above this (webapplication or farm) you will need to also use stapling to ensure the ‘CustomBrandDeployment’ feature is also automatically activated at the site collection level.  If not, the masterpage resources won’t be deployed and your new sites will break!

     

     

    Step by Step


    Contents


    Step 1. Create a New WSP Builder Project

    Step 2. Create the CustomBrandingDeployment feature

    Step 3. Create the Master Page

    Step 4. Create the Minimalistic Master Page 

    Step 5. Create / Add any supporting files to the CustomBrandingDeployment feature

    Step 6. Configure the CustomBrandingDeployment Feature to deploy the files

    Step 6. Create the CustomBrandingApplication feature

    Step 7. Create the Feature Receiver for the CustomBrandingApplication feature

    Step 8. Create the CustomBrandingApplicationStapler Feature

    Step 9. Package

    Step 10. Deploy

    Step 11. Verify Deployment
    Step 12. Activate Features

     

     

    (It looks like a bit to get through – but after a couple iterations and assuming styling/master page development is done, you’ll have these steps done within less than an hour)

     

    Create a New WSP Builder Project

    1. Create a new project in visual studio 2010 choosing the WSPBuilder –> WSPBuilder Project Template.  Note that by default, the name of the root folder your solution exists in will be the name of your WSP file once packaged.

      image
    2. Your solution explorer should now look like this:
      Note that WSP Builder Extensions 1.4 will see the creation of a ‘SharePointRoot’ folder instead of a ‘12’ folder.

    image

    Create the CustomBrandingDeployment feature

    1. Right Click your ‘CustomBrand’ Project and choose Add –> New Item
    2. Select WSPBuilder –> Blank Feature and give the feature a name ‘CustomBrandingDeployment’.  click ‘Add’

      image
    3. Provide appropriate details in the Feature Wizard Dialogue.  Ensure the feature is scoped at the ‘Site’ level and the Event handler option is unchecked.  Click ‘Finish’

      image
    4. The wizard will modify your project folder adding the required folders and files.

    image

    Create and Add the Master Page

    Note: the following steps are provided under the assumption you are going to develop your master page from the OOB v4.master in the layouts directory.  If this is not the case, be sure to add your custom master page from where ever it might currently live.

    1. Create a new project folder under ‘CustomBrandingDeployment’ called ‘MasterPage’
    2. Right click new folder and ‘Add Existing Item’

      image
    3. Add v4.master from the directory:
      c:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS
      Note: If you have a pre-developed master page sitting somewhere, obviously you would browse to that master page… for the purpose of this demonstration however, I’m using a copy of the OOB v4.master
    4. Rename the Master Page (if you are developing from scratch, this step is required, otherwise skip it!)
    5. Create / Modify Master Page (if you are developing from scratch, this step is required, otherwise skip it!)

    As I said earlier, I’m not about to dive in and give you a detailed set of instructions around master page development for SharePoint 2010.  This article is focusing on the packaging, deployment and activation aspect of a custom brand solution.  As a result, My Custom Master page is going to be a copy of the v4.master from the layouts directory with the addition of a simple image top left hand corner.

    image

     

    Step 4. Create the Minimalistic Master Page

    Any custom branding solution that requires a custom master page generally also requires a minimalistic master page.  Why?  Web’s created from the Basic, Enterprise or Fast search centres will not work with a page derived from v4.master.  It’s unfortunate, but true.  If you don’t believe me, skip this step and come back to me when you have learnt the hard way :) 

    Technically, the search centre definitions define ‘Minimal.master’ as the master page for the provisioned webs.   In turn, the pages created during the provisioning of a web deriving from a search site definition place controls in the place holders as required by the Minimal.master master page.  Place holder locations between minimal.master and v4.master are not the same causing the main search textbox to be rendered in the dropdown breadcrumb control.

    image

    ‘So what’ you might say? There’s no scope to include a search site in my deployment?… fair call – but what happens when your client happens to try to create a search site after you've gone and delivered your solution? FAIL!

    Before I go any further: Full Credit for these steps to Randy Drisgill

    So, assuming you developed your master page using v4.master as a base design, follow the steps below to convert that master page into one that can be used by the search site definitions.  Even if you’ve some other method to get to where you are now, the guide below should provide you enough information to get you up and running.

    1. Make copy of your custom master page in the same directory calling it something appropriate

      image
    2. Open the minimal master page for edit
    3. Locate Remove (actually ‘cut’ – you’ll need them for step 4) the <asp:ContentPlaceHolder id="PlaceHolderTitleBreadcrumb" runat="server"> tag and corresponding closing tag.  (The tag envelopes a <SharePoint:ListSiteMapPath … tag…. ensure this remains!)

      image
    4. Paste the placeholder tags removed in step 3 directly before the <asp:ContentPlaceHolder id=”PlaceHolderMain” tag

      image
    5. Wrap the <asp:ContentPlaceHolder id=”PlaceHolderPageTitleInTitleArea” runat=”server”> tags (And any surrounding html) in a hidden div, remove the <SharePoint:ClusteredDirectionalSeparatorArrow runat=”server” /> directly before this.

      image
    6. Wrap the <asp:ContentPlaceHolder id="PlaceHolderGlobalNavigation" runat="server"> tag and all it’s contents in a hidden div

      image
    7. Add CSS Below to the head

      <style type="text/css">

              /* remove left margin */

              .s4-ca {

              margin-left: 0px;

              }

              /* remove gray background at top (optional) */

              .srch-sb-results {

              background:transparent none repeat scroll 0 0;

              }

              /* clean up top padding on 1st search page */

              .srch-sb-main {

              padding-top: 20px;

              }

              /* remove centering on 1st search page (optional) */

              .srch-sb-results4 {

              margin: inherit;

              padding-left: 20px;

              }

              /* remove background color on 1st search page (useful for colored designs) */

              .ms-bodyareaframe {

              background-color: transparent;

              }

              /* ------------------------------------------ */

              /* -- CSS that may be req. to reset the search styling -- */

              /* ------------------------------------------ */

              /* fix height of area above search results */

              td.ms-titleareaframe, div.ms-titleareaframe, .ms-pagetitleareaframe {

              height: auto !important;

              }

              /* fix border color on search results */

              .ms-main .ms-ptabrx, .ms-main .ms-sctabrx, .ms-main .ms-ptabcn, .ms-main .ms-sctabcn {

              border-color: #eeeeee;

              }

              /* fix arrangement of body area on search results */

              .srch-sb-results {

              height: auto;

              }

              /* fix positioning of prefs and advanced link on results */

              .ms-sblink {

              display:block;

              }

              /* fix the color of the prefs and advanced link on results */

              .ms-sblink a:link, .ms-sblink a:visited, .ms-sblink a:hover {

              color:#0072BC;

              }

      </style>


    8. Remove the ‘<div id=”s4-brbboncont”> tag and all internal content
      image

     

     

    Step 5. Create / Add any supporting files to the CustomBrandingDeployment feature

    This step will involve adding a custom css file and an image file to the CustomBrandingDeployment feature.  The css file won’t actually be used by the master page for the purpose of this demo, it’s simply included to show how one would include a file that needed to be deployed to the style library.

    1. Create the directory structure as shown in the image below

      image
    2. Add the files to the directories as below

    image

    Step 6. Configure the CustomBrandingDeployment Feature to deploy the files

    1. Double Click ‘feature.xml’ to edit it.  Note the addition of the ‘ImageUrl’ attribute corresponding to the ‘MTFeatureLogo.png’ added to the solution.  This will add an icon to the feature on the manage features interface.

      image
    2. Double click ‘elements.xml’ to edit it
    3. Add a <module> tag for the master pages.  This tells SharePoint to deploy the files listed to the library located at the url ~site/_catalogs/masterpage when the feature is activated. 
    4. Add a <module> tag for the style sheet.  This will see the style sheet deployed.

      image

     

    As far as what is required to package and deploy the master pages and associated files, we are done. 

    Note that we needed to define <Module> tags for the resources to be deployed to the content database (libraries in the site collection) – one module for the master pages for deployment to the master pages catalogue, and another for the style sheet deployment to the style library.

    The two image files were placed in folders contained in the ‘IMAGES’ folder.  The wsp build process will automatically detect these and have included in the wsp file for deployment to the location: <14 Hive>/Layouts/Images/<directoryname>.  WSP Builder knows to include these and where to configure their deployment path because they have been created in the SharePointRoot/Template/Images folder.

    Step 7. Create the CustomBrandingApplication feature

    The CustomBrandingApplication feature will be responsible for programmatically configuring the web to use the master page.  To achieve this we will write a custom feature receiver and bind it to our new feature.

    1. Right Click your ‘CustomBrand’ Project and choose Add –> New Item
    2. Select WSPBuilder –> Blank Feature and give the feature a name ‘CustomBrandingApplication’.  click ‘Add’
    3. Provide appropriate details in the Feature Wizard Dialogue.  Ensure the feature is scoped at the ‘Web’ level and the Event handler option is checked.  Click ‘Finish’

      image
    4. The wizard will modify your project folder adding the required folders and files.

      image
    5. Delete the ‘elements.xml’ file and double click ‘feature.xml’ to edit it.  Remove the <ElementManifests> tags.
      Note that this feature contains no resources, and as a result, we don’t need the ‘elements.xml’ file or the reference to it in the feature.xml file.

      image

    Step 7. Create the Feature Receiver for the CustomBrandingApplication feature

    I’m not going to go into any great detail about the code here, it’s fairly self explanatory.

    1. Double click the ‘CustomBrandingApplicationReciever.cs’ file in the CustomBrandingApplicationFeature folder to edit it
    2. Add the following code to the event receiver

    using System;

    using System.Collections.Generic;

    using System.Xml;

    using System.Text;

    using System.Globalization;

    using Microsoft.SharePoint;

    using Microsoft.SharePoint.Administration;

     

    namespace CustomBrand.EventHandlers.Features

    {

        public class CustomBrandingApplicationReceiver : SPFeatureReceiver

        {

            //we can declare these two constants as they are explicitly defined/known:

            private const string MasterPageURL = "_catalogs/masterpage/MyCustomMasterPage.master";

            private const string MinimalMasterPageURL = "_catalogs/masterpage/MyMinimalMasterPage.master";

            private const string DefaultMasterPageURL = "_catalogs/masterpage/v4.master";

            private string siteServerURL = string.Empty;

     

            private string GetWebRelativeMasterPageURL(SPWeb web, string siteRelativeMasterPageURL)

            {

                //Check we have a value for siteServerURL:

                if (string.IsNullOrEmpty(this.siteServerURL))

                {

                    //if it is empty, we need to find it:

                    //(Remember: this feature will be scoped at the web (or sub-site) level

                    //and the master page themselves will have been deployed in the master page catalog

                    //located in the root web of the site collection)

                    using (SPSite site = web.Site)

                    {

                        this.siteServerURL = web.Site.ServerRelativeUrl.TrimEnd(char.Parse("/"));

                    }

                }

     

                return string.Format("{0}/{1}", this.siteServerURL, siteRelativeMasterPageURL);

            }

     

            public override void FeatureActivated(SPFeatureReceiverProperties properties)

            {

                //We know that the feature is scoped at the web, so we can safely cast it!:

                SPWeb web = (SPWeb)properties.Feature.Parent;

     

                string mpURL = string.Empty;

                if (web.CustomMasterUrl.Equals("minmal.master", StringComparison.CurrentCultureIgnoreCase))

                {

                    //we need to use our minmal master page:

                    mpURL = MinimalMasterPageURL;

                }

                else

                {

                    //we can use our standard master page:

                    mpURL = MasterPageURL;

                }

     

                //get server/host relative master page URL:

                string serverRelativeMasterPageURL = GetWebRelativeMasterPageURL(web,mpURL);

     

                //set master pages:

                web.CustomMasterUrl = serverRelativeMasterPageURL;

                web.MasterUrl = serverRelativeMasterPageURL;

     

                //update:

                web.Update();

            }

     

            public override void FeatureDeactivating(SPFeatureReceiverProperties properties)

            {

                //We know that the feature is scoped at the web, so we can safely cast it!:

                SPWeb web = (SPWeb)properties.Feature.Parent;

     

                //get server/host relative master page URL:

                string serverRelativeMasterPageURL = GetWebRelativeMasterPageURL(web, DefaultMasterPageURL);

     

                //set master pages:

                web.CustomMasterUrl = serverRelativeMasterPageURL;

                web.MasterUrl = serverRelativeMasterPageURL;

     

                //update:

                web.Update();

            }

        }

    }

     

         

        Step 8. Create the CustomBrandingApplicationStapler Feature

        As explained previously, the final feature of the three will be responsible for stapling the automatic branding feature to all existing site templates.  By ‘Stapling’ a feature to a site template you are effectively instructing sharepoint that said feature is to be activated whenever a new site using that template is provisioned. 

        Being a branding solution, our requirement is to have each new site branded with our master page.  There are two potential ways to achieve this. 

        We can explicitly staple our automatic branding feature to all site templates:
        image

        or, we can use the ‘GLOBAL’ option:

        image

        As one might might expect, using the ‘GLOBAL’ option will have the feature activated at all templates (well - nearly)… As you can also see, I’ve included an explicit FeatureSiteTemplateAssociation entry for STS#1 (Blank Site).  If we take a look at the blank site template as declared in the 14 hive:

        image

        Notice the ‘AllowGlobgalFeatureAssociations=”False” ? – guess what that means?

        (Check it out for yourself – file is located @ <14 Hive>\Template\1033\XML\webtemp.xml)

        Out of the box, blank site is the only template that has this attribute set to false.  It might be possible in the future to have some consultant or developer come along and develop a custom site template with that same flag, in which case your custom branding will not be applied. 

        One final thing to note here is that I’m creating the stapling feature scoped against a site collection.  So that I will need to activate it at all new site collections created to ensure branding compliance.  Do a little planning for yourself, it might be that this feature is better scoped at web application or even farm level level depending on your specific business requirements.

        1. Create the CustomBrandingApplicationStapler Feature
           image
        2. Double click ‘elements.xml’ to open it
        3. Add the following tags
          image
          Note: I’ve blurred Feature GUIDs to avoid you blindly copying what i have… they need to relate to the features that have been created in your environment!!

        Step 9. Package

        This is a simple step, right click your project and choose ‘WSPBuilder –> Build WSP’.

        image

        If you ensure the visibility of your ‘Output’ window in visual studio, you should see WSPBuilder doing it’s thing followed up by a ‘Done!’ success message:

        image

        Hint: The completed package (.wsp file) can be inspected by opening in winrar or 7zip!  This is true for all wsp files and can be an especially handy titbit if you want to pull apart someone else’s solution to see how it’s done…

         

        Step 10. Deploy

        This can again be potentially achieved through a ‘right click –> deploy’ approach… this of course will only deploy to a local farm, so assuming you copy the CustomBrand.wsp file to a path: c:\WSPs:

        1. Navigate to the bin directory within your 14 hives

          cd c:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\Bin\
        2. Execute the following command to add the solution to the solution store

          stsadm.exe –o addsolution –filename c:\WSPs\CustomBrand.wsp
        3. Execute the following command to deploy the solution

          stsadm.exe –o deploysolution –name CustomBrand.wsp –allowGacDeployment –immediate

        image

        The result should be a timer job created to deploy your solution.  Once this happens (timer job execution – give it a couple of minutes) your features will be available for activation.

        Step 11. Verify Deployment

        1. Navigate to ‘Manage Farm Solutions’ (http://<YourCentralAdmin>/_admin/Solutions.aspx) and verify the solution has deployed successfully

          image

        Step 12. Activate Features

        1. Navigate to ‘Manage Site Collection Features’ and activate
          1. CustomBrandingDeployment
          2. CustomBrandingApplicationStapler
        2. Navigate to the ‘Manage Site Features’ of your root site and activate the ‘CustomBrandingApplication’ feature to brand your root site.

        That should be it – all new webs created in your site collection should be branded with the single copy of the master page sitting in the masterpage catalog.

         

        Note – I did hope to have some screen shots of the last couple of steps and the outcome, but somewhere along the line I’ve lost the VM i was working in to get this far?! 

        If I have made an errors, or you feel I’ve not explained everything, let me know – will be happy to help.