/// <summary> /// Timer job run definition /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void ProvisioningJob_TimerJobRun(object sender, TimerJobRunEventArgs e) { try { e.WebClientContext.Load(e.WebClientContext.Web, p => p.Title); e.WebClientContext.ExecuteQueryRetry(); var ctx = e.WebClientContext; Console.WriteLine("Opened site {0} with title {1}", e.Url, e.WebClientContext.Web.Title); SiteProvisioningFactory spf = new SiteProvisioningFactory { SiteCollectionRequestsListTitle = ConfigurationManager.AppSettings["SiteCollectionListTitle"] , SubsiteRequestsListTitle = ConfigurationManager.AppSettings["SubsiteListTitle"] , SiteTemplatesListTitle = ConfigurationManager.AppSettings["SiteTemplateListTitle"] }; //Provision sites spf.ProvisionSites(ctx, SiteProvisioningFactory.SiteType.SiteCollection); //Provision subsites spf.ProvisionSites(ctx, SiteProvisioningFactory.SiteType.Subsite); } catch (Exception ex) { Console.WriteLine("Exception: {0}", ex.Message); } }
private void ExecuteProvisioningJobs(object sender, TimerJobRunEventArgs e) { Console.WriteLine("Starting job"); // Show the current context Web web = e.SiteClientContext.Web; web.EnsureProperty(w => w.Title); Console.WriteLine("Processing jobs in Site: {0}", web.Title); // Retrieve the list of pending jobs var provisioningJobs = ProvisioningRepositoryFactory.Current.GetTypedProvisioningJobs<ProvisioningJob>( ProvisioningJobStatus.Pending); foreach (var job in provisioningJobs) { Console.WriteLine("Processing job: {0} - Owner: {1} - Title: {2}", job.JobId, job.Owner, job.Title); Type jobType = job.GetType(); if (PnPPartnerPackSettings.ScheduledJobHandlers.ContainsKey(jobType)) { PnPPartnerPackSettings.ScheduledJobHandlers[jobType].RunJob(job); } } Console.WriteLine("Ending job"); }
private void EnforceTwoAdministratorsTimerJob_TimerJobRun(object sender, TimerJobRunEventArgs e) { Console.WriteLine("Starting job"); var web = e.SiteClientContext.Web; var siteUsers = e.SiteClientContext.LoadQuery(web.SiteUsers.Include(u => u.Email).Where(u => u.IsSiteAdmin)); e.SiteClientContext.ExecuteQueryRetry(); if (siteUsers.Count() < 2) { Console.WriteLine("Site found"); if (!web.IsPropertyAvailable("Url")) { e.SiteClientContext.Load(web, w => w.Url); e.SiteClientContext.ExecuteQueryRetry(); } var adminUser = siteUsers.FirstOrDefault(); EmailProperties mailProps = new EmailProperties(); mailProps.Subject = "Action required: assign an additional site administrator to your site"; StringBuilder bodyBuilder = new StringBuilder(); bodyBuilder.Append("<html><body style=\"font-family:sans-serif\">"); bodyBuilder.AppendFormat("<p>Your site with address <a href=\"{0}\">{0}</a> has only one site administrator defined: you. Please assign an additional site administrator.</p>", e.SiteClientContext.Web.Url); bodyBuilder.AppendFormat("<p>Click here to <a href=\"{0}/_layouts/mngsiteadmin.aspx\">assign an additional site collection adminstrator.</a></p>", e.SiteClientContext.Web.Url); bodyBuilder.Append("</body></html>"); mailProps.Body = bodyBuilder.ToString(); mailProps.To = new[] { adminUser.Email }; Utility.SendEmail(e.SiteClientContext, mailProps); e.SiteClientContext.ExecuteQueryRetry(); } Console.WriteLine("Ending job"); }
void ContentTypeRetentionEnforcementJob_TimerJobRun(object sender, TimerJobRunEventArgs e) { try { Log.Info("ContentTypeRetentionEnforcementJob", "Scanning web {0}", e.Url); //Get all document libraries. Lists are excluded. var documentLibraries = GetAllDocumentLibrariesInWeb(e.WebClientContext, e.WebClientContext.Web); //Iterate through all document libraries foreach (var documentLibrary in documentLibraries) { Log.Info("ContentTypeRetentionEnforcementJob", "Scanning library {0}", documentLibrary.Title); //Iterate through configured content type retention policies in app.config foreach (var contentTypeName in configContentTypeRetentionPolicyPeriods.Keys) { var retentionPeriods = configContentTypeRetentionPolicyPeriods.GetValues(contentTypeName as string); if (retentionPeriods != null) { var retentionPeriod = int.Parse(retentionPeriods[0]); ApplyRetentionPolicy(e.WebClientContext, documentLibrary, contentTypeName, retentionPeriod); } } } } catch(Exception ex) { Log.Error("ContentTypeRetentionEnforcementJob", "Exception processing site {0}. Exception is {1}", e.Url, ex.Message); } }
private void TestTimerJob_TimerJobRun(object sender, TimerJobRunEventArgs e) { var web = e.SiteClientContext.Web; var users = e.SiteClientContext.LoadQuery(web.SiteUsers.Include(uc => uc.Email).Where(uc => uc.IsSiteAdmin)); e.SiteClientContext.ExecuteQueryRetry(); }
void SiteGovernanceJob_TimerJobRun(object o, TimerJobRunEventArgs e) { try { string library = ""; // Get the number of admins var admins = e.WebClientContext.Web.GetAdministrators(); Log.Info("SiteGovernanceJob", "ThreadID = {2} | Site {0} has {1} administrators.", e.Url, admins.Count, Thread.CurrentThread.ManagedThreadId); // grab reference to list library = "SiteAssets"; List list = e.WebClientContext.Web.GetListByUrl(library); if (!e.GetProperty("ScriptFileVersion").Equals("1.0", StringComparison.InvariantCultureIgnoreCase)) { if (list == null) { // grab reference to list library = "Style%20Library"; list = e.WebClientContext.Web.GetListByUrl(library); } if (list != null) { // upload js file to list list.RootFolder.UploadFile("sitegovernance.js", "sitegovernance.js", true); e.SetProperty("ScriptFileVersion", "1.0"); } } if (admins.Count < 2) { // Oops, we need at least 2 site collection administrators e.WebClientContext.Site.AddJsLink(SiteGovernanceJobKey, BuildJavaScriptUrl(e.Url, library)); Console.WriteLine("Site {0} marked as incompliant!", e.Url); e.SetProperty("SiteCompliant", "false"); } else { // We're all good...let's remove the notification e.WebClientContext.Site.DeleteJsLink(SiteGovernanceJobKey); Console.WriteLine("Site {0} is compliant", e.Url); e.SetProperty("SiteCompliant", "true"); } e.CurrentRunSuccessful = true; e.DeleteProperty("LastError"); } catch(Exception ex) { Log.Error("SiteGovernanceJob", "Error while processing site {0}. Error = {1}", e.Url, ex.Message); e.CurrentRunSuccessful = false; e.SetProperty("LastError", ex.Message); } }
/// <summary> /// Run preprocess for the current site /// </summary> /// <param name="sender">The current timer job instance</param> /// <param name="e">The timer job run event arguments</param> protected override void TimerJobRunImpl(object sender, TimerJobRunEventArgs e) { DbRepository.UsingContext(dbContext => { var web = dbContext.GetWeb(e.Url); var site = dbContext.GetSite(web.SiteUrl); Policy.Preprocess(site, web, e); dbContext.SaveChanges(); }); }
/// <summary> /// Timer Job worker method /// </summary> /// <param name="sender">The event sender</param> /// <param name="e">The timer job argument</param> protected override void TimerJobRunImpl(object sender, TimerJobRunEventArgs e) { // build site information from database or create a new one var siteInformation = GetSiteInformation(e.Url); // load the current site status from SPO Tenant tenant; Site site; SiteProperties properties; LoadSiteStatus(e, out tenant, out site, out properties); // update the site information object with updated site status siteInformation.Guid = site.Id; siteInformation.Title = site.RootWeb.Title; siteInformation.Description = site.RootWeb.Description; siteInformation.Lcid = (int)site.RootWeb.Language; siteInformation.CreatedDate = site.RootWeb.Created; siteInformation.StorageMaximumLevel = properties.StorageMaximumLevel; siteInformation.StorageWarningLevel = properties.StorageWarningLevel; siteInformation.UserCodeMaximumLevel = properties.UserCodeMaximumLevel; siteInformation.UserCodeWarningLevel = properties.UserCodeWarningLevel; siteInformation.TimeZoneId = properties.TimeZoneId; siteInformation.SharingStatus = IsExternalSharingEnabled(properties.SharingCapability, tenant.SharingCapability); // update site collection administrators var admins = site.RootWeb.GetAdministrators(); siteInformation.Administrators = (from a in admins select new SiteUser() { LoginName = a.LoginName, Email = a.Email, }).ToList(); // update external users if (siteInformation.SharingStatus != 0) { var externalUsers = site.RootWeb.GetExternalUsersForSiteTenant(new Uri(e.Url)); siteInformation.ExternalUsers = (from u in externalUsers select new ExternalSiteUser() { LoginName = u.AcceptedAs, Email = u.InvitedAs, ExternalUser_AcceptedAs = u.AcceptedAs, ExternalUser_CreatedDate = u.WhenCreated, ExternalUser_DisplayName = u.DisplayName, ExternalUser_InvitedAs = u.InvitedAs, ExternalUser_InvitedBy = u.InvitedBy, ExternalUser_UniqueId = u.UniqueId, } as SiteUser).ToList(); } // write site information into database Log.Info(base.Name, TimerJobsResources.SynchJob_UpdateDbRecord, e.Url); DbRepository.UsingContext(dbContext => { dbContext.SaveSite(siteInformation); }); }
/// <summary> /// Remove database record if the site is not existing in SharePoint /// </summary> /// <param name="sender">The current time job instance</param> /// <param name="e">Time job event arguments</param> protected override void TimerJobRunImpl(object sender, TimerJobRunEventArgs e) { var tenant = new Tenant(e.TenantClientContext); bool existed = tenant.SiteExists(e.Url); if (existed) return; Log.Info(TimerJobsResources.CleanUpJob_RemoveSite, e.Url); DbRepository.UsingContext(context => { var site = context.GetSite(e.Url); context.Sites.Remove(site); }); }
void TenantAPIJob_TimerJobRun(object sender, TimerJobRunEventArgs e) { Tenant t = new Tenant(e.TenantClientContext); var sites = t.GetSiteProperties(0, true); e.TenantClientContext.Load(sites); e.TenantClientContext.ExecuteQueryRetry(); foreach(var site in sites) { Console.WriteLine(site.Template); } }
/// <summary> /// Run policy checking and enforcement for the current site colleciton /// </summary> /// <param name="sender">The current timer job instance</param> /// <param name="e">Time job run event arguments</param> protected override void TimerJobRunImpl(object sender, TimerJobRunEventArgs e) { SiteInformation site = null; DbRepository.UsingContext(dbContext => { site = dbContext.GetSite(e.Url); if (site == null) return; PolicyManager.Run(e.TenantClientContext, site, SuppressEmail); if (site.ComplianceState.DeleteDate == DateTime.MaxValue) dbContext.Sites.Remove(site); dbContext.SaveChanges(); }); }
void ExpandJob_TimerJobRun(object sender, TimerJobRunEventArgs e) { // Read the title from the site being processed e.WebClientContext.Load(e.WebClientContext.Web, p => p.Title); e.WebClientContext.ExecuteQueryRetry(); // Read the title from the root site of the site being processed e.SiteClientContext.Load(e.SiteClientContext.Web, p => p.Title); e.SiteClientContext.ExecuteQueryRetry(); Console.WriteLine("Root site of site {0} has title {1}", e.Url, e.SiteClientContext.Web.Title); Console.WriteLine("Sub site {0} has title {1}", e.Url, e.WebClientContext.Web.Title); // Show some threading information ThreadingDebugInformation(); }
/// <summary> /// Timer job run event handler to report the current job progress to console /// </summary> /// <param name="sender">The current timer job instnace</param> /// <param name="e">Timer job run event arguments</param> protected void ManagementTimerJob_TimerJobRun(object sender, TimerJobRunEventArgs e) { try { TimerJobRunImpl(sender, e); } catch (Exception exception) { Console.WriteLine(TimerJobsResources.TenantJob_SiteError, Name, e.Url); Console.WriteLine(exception.Message); throw; } finally { e.TenantClientContext.Dispose(); // Dispose the tenant client context object Console.WriteLine(TimerJobsResources.TenantJob_Progress, ++CompletedSites, TotalSites, Name); } }
void SiteCollectionScopedJob_TimerJobRun(object sender, TimerJobRunEventArgs e) { // Get all the sub sites in the site we're processing IEnumerable<string> expandedSites = GetAllSubSites(e.SiteClientContext.Site); // Manually iterate over the content foreach (string site in expandedSites) { // Clone the existing ClientContext for the sub web using (ClientContext ccWeb = e.SiteClientContext.Clone(site)) { // Here's the timer job logic, but now a single site collection is handled in a single thread which // allows for further optimization or prevents race conditions ccWeb.Load(ccWeb.Web, s => s.Title); ccWeb.ExecuteQueryRetry(); Console.WriteLine("Here: {0} - {1}", site, ccWeb.Web.Title); } } }
void GetWebPartUsage_TimerJobRun(object sender, TimerJobRunEventArgs e) { e.WebClientContext.Load(e.WebClientContext.Web, p => p.Url); e.WebClientContext.ExecuteQueryRetry(); GetWebPartUsage(WebPartType, e.WebClientContext, OutPutDirectory); }
/// <summary> /// Triggers the event to fire and deals with all the pre/post processing needed to automatically manage state /// </summary> /// <param name="e">TimerJobRunEventArgs event arguments class that will be passed to the event handler</param> private void OnTimerJobRun(TimerJobRunEventArgs e) { try { // Copy for thread safety? TimerJobRunHandler timerJobRunHandlerThreadCopy = TimerJobRun; if (timerJobRunHandlerThreadCopy != null) { PropertyValues props = null; JavaScriptSerializer s = null; // if state is managed then the state value is stored in a property named "<timerjobname>_Properties" string propertyKey = String.Format("{0}_Properties", NormalizedTimerJobName(this.name)); // read the properties from the web property bag if (this.manageState) { props = e.WebClientContext.Web.AllProperties; e.WebClientContext.Load(props); e.WebClientContext.ExecuteQueryRetry(); s = new JavaScriptSerializer(); // we've found previously stored state, so this is not the first timer job run if (props.FieldValues.ContainsKey(propertyKey)) { string timerJobProps = props.FieldValues[propertyKey].ToString(); // We should have a value, but you never know... if (!string.IsNullOrEmpty(timerJobProps)) { Log.Info(Constants.LOGGING_SOURCE, CoreResources.TimerJob_OnTimerJobRun_PropertiesRead, propertyKey, e.Url); // Deserialize the json string into a TimerJobRun class instance TimerJobRun timerJobRunProperties = s.Deserialize<TimerJobRun>(timerJobProps); // Pass the state information as part of the event arguments if (timerJobRunProperties != null) { e.PreviousRun = timerJobRunProperties.PreviousRun; e.PreviousRunSuccessful = timerJobRunProperties.PreviousRunSuccessful; e.PreviousRunVersion = timerJobRunProperties.PreviousRunVersion; e.Properties = timerJobRunProperties.Properties; Log.Info(Constants.LOGGING_SOURCE, CoreResources.TimerJob_OnTimerJobRun_PrevRunRead, e.PreviousRun, e.Url); Log.Info(Constants.LOGGING_SOURCE, CoreResources.TimerJob_OnTimerJobRun_PrevRunSuccessRead, e.PreviousRunSuccessful, e.Url); Log.Info(Constants.LOGGING_SOURCE, CoreResources.TimerJob_OnTimerJobRun_PrevRunVersionRead, e.PreviousRunVersion, e.Url); } } } } Log.Info(Constants.LOGGING_SOURCE, CoreResources.TimerJob_OnTimerJobRun_CallEventHandler, e.Url); // trigger the event timerJobRunHandlerThreadCopy(this, e); Log.Info(Constants.LOGGING_SOURCE, CoreResources.TimerJob_OnTimerJobRun_CallEventHandlerDone, e.Url); // Update and store the properties to the web property bag if (this.manageState) { // Retrieve the values of the event arguments and complete them with defaults TimerJobRun timerJobRunProperties = new TimerJobRun() { PreviousRun = DateTime.Now, PreviousRunSuccessful = e.CurrentRunSuccessful, PreviousRunVersion = this.version, Properties = e.Properties, }; Log.Info(Constants.LOGGING_SOURCE, CoreResources.TimerJob_OnTimerJobRun_PrevRunSet, timerJobRunProperties.PreviousRun, e.Url); Log.Info(Constants.LOGGING_SOURCE, CoreResources.TimerJob_OnTimerJobRun_PrevRunSuccessSet, timerJobRunProperties.PreviousRunSuccessful, e.Url); Log.Info(Constants.LOGGING_SOURCE, CoreResources.TimerJob_OnTimerJobRun_PrevRunVersionSet, timerJobRunProperties.PreviousRunVersion, e.Url); // Serialize to json string string timerJobProps = s.Serialize(timerJobRunProperties); props = e.WebClientContext.Web.AllProperties; // Get the value, if the web properties are already loaded if (props.FieldValues.Count > 0) { props[propertyKey] = timerJobProps; } else { // Load the web properties e.WebClientContext.Load(props); e.WebClientContext.ExecuteQueryRetry(); props[propertyKey] = timerJobProps; } // Persist the web property bag entries e.WebClientContext.Web.Update(); e.WebClientContext.ExecuteQueryRetry(); Log.Info(Constants.LOGGING_SOURCE, CoreResources.TimerJob_OnTimerJobRun_PropertiesSet, propertyKey, e.Url); } } } catch (Exception ex) { // Catch error in this case as we don't want to the whole program to terminate if one single site operation fails Log.Error(Constants.LOGGING_SOURCE, CoreResources.TimerJob_OnTimerJobRun_Error, e.Url, ex.Message); } }
/// <summary> /// Processes the amount of work that will be done for a single site/web /// </summary> /// <param name="site">Url of the site to process</param> private void DoWork(string site) { Log.Info(Constants.LOGGING_SOURCE, CoreResources.TimerJob_DoWork_Start, site); // Get the root site of the passed site string rootSite = GetRootSite(site); // Instantiate the needed ClientContext objects ClientContext ccWeb = CreateClientContext(site); ClientContext ccSite = null; if (rootSite.Equals(site, StringComparison.InvariantCultureIgnoreCase)) { ccSite = ccWeb; } else { ccSite = CreateClientContext(rootSite); } #if !CLIENTSDKV15 // Instantiate ClientContext against tenant admin site, this is needed to operate using the Tenant API string tenantAdminSiteUrl = tenantAdminSite; if (string.IsNullOrEmpty(tenantAdminSiteUrl)) { tenantAdminSiteUrl = GetTenantAdminSite(site); } ClientContext ccTenant = CreateClientContext(tenantAdminSiteUrl); #else // No easy way to detect tenant admin site in on-premises, so uses has to specify it ClientContext ccTenant = null; if (!String.IsNullOrEmpty(tenantAdminSite)) { ccTenant = CreateClientContext(tenantAdminSite); } #endif // Prepare the timerjob callback event arguments TimerJobRunEventArgs e = new TimerJobRunEventArgs(site, ccSite, ccWeb, ccTenant, null, null, "", new Dictionary<string, string>(), this.ConfigurationData); // Trigger the event to fire, but only when there's an event handler connected if (TimerJobRun != null) { OnTimerJobRun(e); } else { Log.Warning(Constants.LOGGING_SOURCE, CoreResources.TimerJob_DoWork_NoEventHandler); } Log.Info(Constants.LOGGING_SOURCE, CoreResources.TimerJob_DoWork_Done, site); }
public virtual void Preprocess(SiteInformation siteCollection, WebInformation web, TimerJobRunEventArgs e) { }
/// <summary> /// Update HasBroadAccess to 1 for both of the site collection and the current web record if any large security group permission assignment was found on the current web /// </summary> /// <param name="dbSiteRecord">The site collection record</param> /// <param name="dbWebRecord">The current web record</param> /// <param name="e">The timer job run event arguments</param> public override void Preprocess(SiteInformation dbSiteRecord, WebInformation dbWebRecord, TimerJobRunEventArgs e) { var tenant = new Tenant(e.TenantClientContext); var site = tenant.GetSiteByUrl(e.Url); var web = e.Url == dbWebRecord.SiteUrl ? site.RootWeb : site.OpenWeb(e.Url.Substring(dbWebRecord.Name.IndexOf('/') + 1)); // load additional properties could be used to optimize the permission checking process e.TenantClientContext.Load(web, w => w.HasUniqueRoleAssignments, w => w.Url, w => w.ServerRelativeUrl, w => w.ParentWeb.ServerRelativeUrl); var assignments = new List<PermissionAssignment>(); var entries = from groupLoginName in BroadAccessGroups.Keys select new PermissionAssignment { Url = e.Url, Group = groupLoginName, Permission = web.GetUserEffectivePermissions(groupLoginName) }; assignments.AddRange(entries); e.TenantClientContext.ExecuteQuery(); var incompliantAssignments = assignments.Where( p => p.Permission.Value != null && ( p.Permission.Value.Has(PermissionKind.ViewPages) || p.Permission.Value.Has(PermissionKind.ViewListItems))); dbWebRecord.HasBroadAccess = incompliantAssignments.Any(); if (dbWebRecord.HasBroadAccess) { dbWebRecord.BroadAccessGroups = string.Join(";", (from a in incompliantAssignments select a.Group).ToArray()); dbSiteRecord.HasBroadAccess = true; } }
void SimpleJob_TimerJobRun(object sender, TimerJobRunEventArgs e) { e.WebClientContext.Load(e.WebClientContext.Web, p => p.Title); e.WebClientContext.ExecuteQueryRetry(); Console.WriteLine("Site {0} has title {1}", e.Url, e.WebClientContext.Web.Title); }
private void ValidateExternalUsersTimerJob_TimerJobRun(object sender, TimerJobRunEventArgs e) { Console.WriteLine("Starting job"); var web = e.SiteClientContext.Web; Tenant tenant = new Tenant(e.TenantClientContext); var siteAdmins = e.SiteClientContext.LoadQuery(web.SiteUsers.Include(u => u.Email).Where(u => u.IsSiteAdmin)); e.SiteClientContext.ExecuteQueryRetry(); List<string> adminEmails = new List<string>(); foreach (var siteAdmin in siteAdmins) { adminEmails.Add(siteAdmin.Email); } SiteProperties p = tenant.GetSitePropertiesByUrl(e.SiteClientContext.Url, true); var sharingCapability = p.EnsureProperty(s => s.SharingCapability); if (sharingCapability != Microsoft.Online.SharePoint.TenantManagement.SharingCapabilities.Disabled) { DateTime checkDate = DateTime.Now; var lastCheckDate = e.WebClientContext.Web.GetPropertyBagValueString(PNPCHECKDATEPROPERTYBAGKEY, string.Empty); if (lastCheckDate == string.Empty) { // new site. Temporary set the check date to less than one Month checkDate = checkDate.AddMonths(-2); } else { if (!DateTime.TryParse(lastCheckDate, out checkDate)) { // Something went wrong with trying to parse the date in the propertybag. Do the check anyway. checkDate = checkDate.AddMonths(-2); } } if (checkDate.AddMonths(1) < DateTime.Now) { e.SiteClientContext.Web.EnsureProperty(w => w.Url); e.WebClientContext.Web.EnsureProperty(w => w.Url); EmailProperties mailProps = new EmailProperties(); mailProps.Subject = "Review required: external users with access to your site"; StringBuilder bodyBuilder = new StringBuilder(); bodyBuilder.AppendFormat("<html><head>{0}</head><body style=\"font-family:sans-serif\">", CSSSTYLE); bodyBuilder.AppendFormat("<p>Your site with address {0} has one or more external users registered. Please review the following list and take appropriate action if such access is not wanted anymore for a user.</p>", e.SiteClientContext.Web.Url); bodyBuilder.Append("<table class=\"tg\"><tr><th>Name</th><th>Invited by</th><th>Created</th><th>Invited As</th><th>Accepted As</th></tr>"); var externalusers = e.TenantClientContext.Web.GetExternalUsersForSiteTenant(new Uri(e.WebClientContext.Web.Url)); if (externalusers.Any()) { foreach (var externalUser in externalusers) { bodyBuilder.AppendFormat("<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td></tr>", externalUser.DisplayName, externalUser.InvitedBy, externalUser.WhenCreated, externalUser.InvitedAs, externalUser.AcceptedAs); } bodyBuilder.Append("</table></body></html>"); mailProps.Body = bodyBuilder.ToString(); mailProps.To = adminEmails.ToArray(); Utility.SendEmail(e.SiteClientContext, mailProps); e.SiteClientContext.ExecuteQueryRetry(); } e.WebClientContext.Web.SetPropertyBagValue(PNPCHECKDATEPROPERTYBAGKEY, DateTime.Now.ToString()); } } Console.WriteLine("Ending job"); }
/// <summary> /// The abstract method which should be implemented in overriden classes to /// </summary> /// <param name="sender">The current timer job instnace</param> /// <param name="e">Timer job run event arguments</param> protected abstract void TimerJobRunImpl(object sender, TimerJobRunEventArgs e);
/// <summary> /// Processes the amount of work that will be done for a single site/web /// </summary> /// <param name="site">Url of the site to process</param> private void DoWork(string site) { Log.Info(Constants.LOGGING_SOURCE, CoreResources.TimerJob_DoWork_Start, site); // Get the root site of the passed site string rootSite = GetRootSite(site); // Instantiate the needed ClientContext objects ClientContext ccWeb = CreateClientContext(site); ClientContext ccSite = null; if (rootSite.Equals(site, StringComparison.InvariantCultureIgnoreCase)) { ccSite = ccWeb; } else { ccSite = CreateClientContext(rootSite); } // Prepare the timerjob callback event arguments TimerJobRunEventArgs e = new TimerJobRunEventArgs(site, ccSite, ccWeb, null, null, "", new Dictionary<string, string>(), this.ConfigurationData); // Trigger the event to fire, but only when there's an event handler connected if (TimerJobRun != null) { OnTimerJobRun(e); } else { Log.Warning(Constants.LOGGING_SOURCE, CoreResources.TimerJob_DoWork_NoEventHandler); } Log.Info(Constants.LOGGING_SOURCE, CoreResources.TimerJob_DoWork_Done, site); }
/// <summary> /// Load the latest site collection status from SharePoint /// </summary> /// <param name="e">Timer job event arguments</param> /// <param name="tenant">The tenant object</param> /// <param name="site">The site object</param> /// <param name="properties">The site properties object</param> private void LoadSiteStatus(TimerJobRunEventArgs e, out Tenant tenant, out Site site, out SiteProperties properties) { var tenantClientContext = e.TenantClientContext; Log.Info(base.Name, TimerJobsResources.SynchJob_GetSiteStatus, e.Url); tenant = new Tenant(tenantClientContext); site = tenant.GetSiteByUrl(e.Url); properties = tenant.GetSitePropertiesByUrl(e.Url, includeDetail: false); tenantClientContext.Load(tenant, t => t.SharingCapability); tenantClientContext.Load(site, s => s.RootWeb.Title, s => s.RootWeb.Description, s => s.RootWeb.Language, s => s.RootWeb.Created, s => s.Id); tenantClientContext.Load(properties, s => s.StorageMaximumLevel, s => s.StorageWarningLevel, s => s.UserCodeMaximumLevel, s => s.UserCodeWarningLevel, s => s.TimeZoneId, s => s.SharingCapability); tenantClientContext.ExecuteQueryRetry(); }