Пример #1
0
        /// <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);
            }
        }
Пример #5
0
        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();
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
 /// <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();
     });            
 }
Пример #8
0
        /// <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);
            });
        }
Пример #9
0
 /// <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);
     });
 }
Пример #10
0
        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);
            }

        }
Пример #11
0
 /// <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();
         });
 }
Пример #12
0
        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();
        }
Пример #13
0
 /// <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);
     }
 }
Пример #14
0
        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);
 }
Пример #16
0
        /// <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);
            }
        }
Пример #17
0
        /// <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);
        }
Пример #18
0
 public virtual void Preprocess(SiteInformation siteCollection, WebInformation web, TimerJobRunEventArgs e)
 {
 }
Пример #19
0
        /// <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;
            }
        }
Пример #20
0
 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");

		}
Пример #22
0
 /// <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);
Пример #23
0
        /// <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);
        }
Пример #24
0
 /// <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();
 }