Add custom columns in document content type by default when MySite is created and also for Existing MySite

I recently got a requirement asking how can we create Mysite for new users(also existing users) so that it already contains the custom site columns(field type choice) and Document content type with those custom columns. Well, you know the answer “Feature Stapling”. There are good number of articles that explains about Feature Stapling.

Yes, using feature stapling we can get this done easily for newly created MySite. What about existing MySites? We can get this done by creating a small console application having little bit of smart code in it.

Code snippet : Adding custom columns in Document content type.

    1: public override void FeatureActivated(SPFeatureReceiverProperties properties)
    2:         {
    3:             using (SPWeb web = properties.Feature.Parent as SPWeb)
    4:             {
    5:                 try
    6:                 {
    7:                     string columnOne = "Document Class";
    8:  
    9:                     SPContentType documentContentType = web.ContentTypes["Document"];
   10:  
   11:                     //Check if the site column already exists
   12:                     if (!web.Fields.ContainsField(columnOne))
   13:                     {
   14:                         //If the site column doesn't exist then create a new column and assign it to custom columns group
   15:                         web.Fields.Add(columnOne, SPFieldType.Choice, true);
   16:                         SPFieldChoice choiceFields = (SPFieldChoice)web.Fields[columnOne];
   17:                         string[] choices = new string[3] {"Working", "Reference", "Record" };
   18:                         foreach (string choice in choices)
   19:                         {
   20:                             choiceFields.Choices.Add(choice);
   21:                         }
   22:                         choiceFields.Group = "Custom Document Columns";
   23:                         choiceFields.Update(true);
   24:                     }
   25:  
   26:                     if (!string.IsNullOrEmpty(columnOne))
   27:                     {
   28:                         //Get the field reference of new site column
   29:                         SPFieldLink fieldLink = new SPFieldLink(web.Fields[columnOne]);
   30:  
   31:                         if (fieldLink != null)
   32:                         {
   33:                             documentContentType.FieldLinks.Add(fieldLink);
   34:                             documentContentType.Update();
   35:                         }
   36:  
   37:                     }
   38:  
   39:                 }
   40:  
   41:                 catch (SPException ex)
   42:                 {
   43:                     //Write to Logger
   44:                 }
   45:  
   46:             }
   47:     }

For the existing MySite, first install Staplee feature in SharePoint farm.  Then, build a console application having this code in it.

    1: SPWebApplication objWebApplication = SPWebApplication.Lookup(new Uri(" "));//WebApplicaton Uri
    2: SPSiteCollection objSiteCollection = objWebApplication.Sites;
    3:  
    4: foreach (SPSite objSite in objSiteCollection)
    5: {
    6:     if (objSite.RootWeb.WebTemplate.ToString() == "SPSPERS")
    7:     {
    8:         objSite.RootWeb.Features.Add(new Guid("{4DEFA336-EDC4-43cb-9560-FE2E27E76DFB}")); // Guid of Staplee feature
    9:     }
   10: }

Run the executable file of the console application and it will activate the custom feature for all existing MySites under the web application