Provisioning SharePoint Site Collections in Office 365 or SharePoint 2013 through Code

We were working on some provisioning code for creating and deleting site collections in Office 365.  Microsoft provides the SharePoint 2013 Client Components SDK that includes a tenant library for managing activities such as creating and deleting site collections.

The lifecycle of a site collection is three stages, not two: 1) create the site collection; 2) delete the site collection and 3) remove the site collection from the second stage recycle bin.  SharePoint will not allow you to create a site collection with the same URL as an existing site collection even if it is in the recycle bin.  Using the Office 365, there is no ability to empty the second stage recycle bin at all and the default waiting period is 30 days before it is permanently removed, so the only method for removing the Site Collection from the recycle bin is through code.

Creating a Context

In order to use any of the client methods, you will need a client context.  The code for logging into Office 365 looks like this:

public ClientContext Login(string URL)
{
     SecureString passWord = new SecureString();
     foreach (char c in Password.ToCharArray()) passWord.AppendChar(c);
     ClientContext tenantContext = new ClientContext(URL);
     tenantContext.Credentials = new SharePointOnlineCredentials(Username, passWord);
     return tenantContext;
}

public ClientContext LoginTenant()
         {
             return Login(TenantAdminURL);
         }

The URL in this case needs to be the tenant admin URL which is in the format XXX-admin.sharepoint.com where XXX is the name of your tenant.

Creating a Site Collection

Creating a site collection requires a number of properties to supply in the creation process such as the TItle, URL, resources, etc. for your new site collection.  The tenant library provides the methods for creating a site collection.

I created a value object to store these properties like this:

public class SharePointSiteCollection
    {
        public string URL { get; set; }
        public string Title { get; set; }
        public string Owner { get; set; }
        public string RootSiteTemplate { get; set; }

       public int StorageLimit { get; set; }
        public int ResourcePoints { get; set; }
    }

This makes it easier to pass around the configuration information as an entity and will support serialization of the configuration data at some point in the future.

The method for creating a site collection looks like this:

public void CreateSiteCollection(SharePointSiteCollection SiteCollection )
{
     using (ClientContext ctx = LoginTenant())
     {
         //Properties of the New SiteCollection
         var siteCreationProperties = new SiteCreationProperties();
         var tenant = new Tenant(ctx);
         string URL = AssembleAbsoluteURL(SiteCollection.URL);
         siteCreationProperties.Url = URL;
         //Title of the Root Site
         siteCreationProperties.Title = SiteCollection.Title;
         //Email of Owner
         siteCreationProperties.Owner = SiteCollection.Owner;
         siteCreationProperties.Lcid = (uint) LCID;
         //Template of the Root Site. Using Team Site for now.
         siteCreationProperties.Template = SiteCollection.RootSiteTemplate;
         //Storage Limit in MB
         siteCreationProperties.StorageMaximumLevel = SiteCollection.StorageLimit;
         //UserCode Resource Points Allowed
         siteCreationProperties.UserCodeMaximumLevel = SiteCollection.ResourcePoints;
         //Create the SiteCollection
         SpoOperation spo = tenant.CreateSite(siteCreationProperties);
         ctx.Load(tenant);
         //We will need the IsComplete property to check if the provisioning of the Site Collection is complete.
         ctx.Load(spo, i => i.IsComplete);
         ctx.ExecuteQuery();
         Console.WriteLine(“Waiting for site collection to be created.”);
         //Check if provisioning of the SiteCollection is complete.
         while (!spo.IsComplete)
         {
             //Wait for 30 seconds and then try again
             System.Threading.Thread.Sleep(30000);
             spo.RefreshLoad();
             ctx.ExecuteQuery();
         }
         Console.WriteLine(“Site collection created.”);


    }


}

Note the process for waiting for the site collection process to complete – creating a site collection can take a few minutes and the method simply waits until finished before completion.

Deleting a Site Collection

Deleting a site collection can be done using the following code:

public void DeleteSiteCollection(string URL)
         {
             URL = AssembleAbsoluteURL(URL);
             using (ClientContext ctx = LoginTenant())
             {
                 var tenant = new Tenant(ctx);
                 var spo = tenant.RemoveSite(URL);
                 ctx.Load(spo);
                 ctx.ExecuteQuery();


                Console.WriteLine(“Waiting for site to be deleted.”);


                //Check if provisioning of the SiteCollection is complete.
                 while (!spo.IsComplete)
                 {


                    //Wait for 30 seconds and then try again
                     System.Threading.Thread.Sleep(30000);
                     spo.RefreshLoad();
                     ctx.ExecuteQuery();
                 }


                Console.WriteLine(“Site deleted.”);


            }


        }

Removing the Site Collection from the Recycle Bin

The last step is to remove the site collection from the second stage recycle bin. 

public void RemoveSiteFromRecycleBin(string URL)
         {
                 URL = AssembleAbsoluteURL(URL);
                 using (ClientContext ctx = LoginTenant())
                 {
                     var tenant = new Tenant(ctx);
                     var spo = tenant.RemoveDeletedSite(URL);
                     ctx.Load(spo);
                     ctx.ExecuteQuery();


                    Console.WriteLine(“Waiting for Site to be removed from the recycle bin.”);


                    //Check if provisioning of the SiteCollection is complete.
                     while (!spo.IsComplete)
                     {


                        //Wait for 30 seconds and then try again
                         System.Threading.Thread.Sleep(30000);
                         spo.RefreshLoad();
                         ctx.ExecuteQuery();
                     }


                    Console.WriteLine(“Site removed from the recycle bin.”);


                }
         }