SharePoint provides a framework for tasks that can be executed at scheduled intervals called SharePoint timer jobs. These timer jobs, when configured, are executed by the SharePoint Timer Windows service. In a large site with a lot of contributors, there may be the need to enforce some rules in the environment in a more automated fashion, such as using consistent branding. In this recipe, we will create a timer job that ensures the site branding feature is activated on all sites in the site collection.
Follow these steps to create a timer job:
BrandingTimerJob
).public
access modifier and inherit from the SPJobDefinition
base class as follows:public class BrandingTimerJob : SPJobDefinition
BrandingTimerJob
class, add a static GUID
for our SiteBranding feature ID. Replace the sample feature ID with the feature ID from your SiteBranding feature as follows:private static Guid BrandingFeatureId = new Guid("1150dec7-4af6-44d8-b241-d976d26b723c");
BrandingTimerJob
class using the following code:public BrandingTimerJob(SPWebApplication webApplication, string title) : base("Custom Branding Job", webApplication, null, SPJobLockType.ContentDatabase) { this.Title = title; } public BrandingTimerJob() : base() { }
Execute
method as follows:public override void Execute(Guid targetInstanceId)
Execute
method, attempt to get the site collection ID associated with the timer job instance using the following code:Guid? siteId = null; if (this.Properties.ContainsKey("SiteId")) siteId = this.Properties["SiteId"] as Guid?;
using
statement as follows:using (var site = new SPSite(siteId.Value))
null
as follows:if (site != null)
foreach (SPWeb web in site.AllWebs)
null
and that it exists as follows:if (web != null && web.Exists)
if (web.Features[BrandingFeatureId] == null) web.Features.Add(BrandingFeatureId);
BrandingTimerJob.cs
file.SiteCollectionBranding.EventReceiver.cs
file.private static string FormatJobName = "Custom Branding Job_{0}";
FeatureActivated
method, after the foreach
loop iterates through each site in the site collection, create the timer job name, get the web application ID, and then get the site collection ID as follows:var jobName = string.Format(CultureInfo.InvariantCulture, FormatJobName, site.ID.ToString()); var webAppId = site.WebApplication.Id; var siteId = site.ID;
delegate
method to be executed by the SPSecurity.RunWithElevatedPrivleges
method as follows:SPSecurity.RunWithElevatedPrivileges(delegate() { });
delegate
method, get the web application as follows:var webApplication = SPWebService.ContentService.WebApplications[webAppId];
foreach (SPJobDefinition job in webApplication.JobDefinitions.Where(p => p.Name == jobName)) job.Delete();
BrandingTimerJob
and give it a daily schedule.var brandingJob = new BrandingTimerJob(webApplication, jobName); brandingJob.Properties.Add("SiteId", siteId); brandingJob.Schedule = new SPDailySchedule() { BeginHour = 1 }; brandingJob.Update();
FeatureDeactivating
method.FeatureDeactivating
method, get the site collection in a using
statement as follows:using (var site = properties.Feature.Parent as SPSite)
null
as follows:if (site != null)
var jobName = string.Format(CultureInfo.InvariantCulture, FormatJobName, site.ID.ToString()); var webAppId = site.WebApplication.Id;
delegate
method to be executed by the SPSecurity.RunWithElevatedPrivleges
method:SPSecurity.RunWithElevatedPrivileges(delegate() { });
delegate
method, get the web application as follows:var webApplication = SPWebService.ContentService.WebApplications[webAppId];
foreach (SPJobDefinition job in webApplication.JobDefinitions.Where(p => p.Name == jobName)) job.Delete();
A SharePoint timer job can be created for various scopes in the SharePoint farm. These scopes include the farm, a web application, a service application, and so on. In our example, we created a timer job at the web application level with the ID of the site collection. This allows for us to have multiple timer jobs in the web application for various site collections. Our timer job runs daily to ensure all sites in the site collection have the site branding feature enabled.
Using the RunWithElevatedPrivileges
method, we can run the code as the SharePoint farm account. This essentially provides full administrator access to the SharePoint farm. As such, this technique should be used sparingly and in limited scopes. When passing variables into the delegate method, it is important to use simple types, such as strings, integers, and GUIDs. Passing complex objects, such as a site collection (SPSite
), can result in the objects referencing the wrong SharePoint content.
18.118.20.68