private void ModernizationScanJob_TimerJobRun(object sender, OfficeDevPnP.Core.Framework.TimerJobs.TimerJobRunEventArgs e) { // Validate ClientContext objects if (e.WebClientContext == null || e.SiteClientContext == null) { ScanError error = new ScanError() { Error = "No valid ClientContext objects", SiteURL = e.Url, SiteColUrl = e.Url }; this.ScanErrors.Push(error); Console.WriteLine("Error for site {1}: {0}", "No valid ClientContext objects", e.Url); // bail out return; } // thread safe increase of the sites counter IncreaseScannedSites(); try { // Set the first site collection done flag + perform telemetry SetFirstSiteCollectionDone(e.WebClientContext, this.Name); // Manually iterate over the content IEnumerable <string> expandedSites = e.SiteClientContext.Site.GetAllSubSites(); bool isFirstSiteInList = true; string siteCollectionUrl = ""; List <Dictionary <string, string> > pageSearchResults = null; foreach (string site in expandedSites) { try { // thread safe increase of the webs counter IncreaseScannedWebs(); // Clone the existing ClientContext for the sub web using (ClientContext ccWeb = e.SiteClientContext.Clone(site)) { Console.WriteLine("Processing site {0}...", site); // Allow max server time out, might be needed for sites having a lot of users ccWeb.RequestTimeout = Timeout.Infinite; if (isFirstSiteInList) { // Perf optimization: do one call per site to load all the needed properties var spSite = (ccWeb as ClientContext).Site; ccWeb.Load(spSite, p => p.RootWeb, p => p.Url, p => p.GroupId); ccWeb.Load(spSite.RootWeb, p => p.Id); ccWeb.Load(spSite, p => p.UserCustomActions); // User custom action site level ccWeb.Load(spSite, p => p.Features); // Features site level ccWeb.ExecuteQueryRetry(); isFirstSiteInList = false; } // Perf optimization: do one call per web to load all the needed properties ccWeb.Load(ccWeb.Web, p => p.Id, p => p.Title, p => p.Url); ccWeb.Load(ccWeb.Web, p => p.WebTemplate, p => p.Configuration); ccWeb.Load(ccWeb.Web, p => p.MasterUrl, p => p.CustomMasterUrl, // master page check p => p.AlternateCssUrl, // Alternate CSS p => p.UserCustomActions); // Web user custom actions ccWeb.Load(ccWeb.Web, p => p.Features); // Features web level ccWeb.Load(ccWeb.Web, p => p.RootFolder); // web home page ccWeb.ExecuteQueryRetry(); // Split load in multiple batches to minimize timeout exceptions if (!SkipUserInformation) { ccWeb.Load(ccWeb.Web, p => p.SiteUsers, p => p.AssociatedOwnerGroup, p => p.AssociatedMemberGroup, p => p.AssociatedVisitorGroup); // site user and groups ccWeb.Load(ccWeb.Web, p => p.HasUniqueRoleAssignments, p => p.RoleAssignments, p => p.SiteGroups.Include(s => s.Users)); // permission inheritance at web level ccWeb.ExecuteQueryRetry(); ccWeb.Load(ccWeb.Web.AssociatedOwnerGroup, p => p.Users); // users in the Owners group ccWeb.Load(ccWeb.Web.AssociatedMemberGroup, p => p.Users); // users in the Members group ccWeb.Load(ccWeb.Web.AssociatedVisitorGroup, p => p.Users); // users in the Visitors group ccWeb.ExecuteQueryRetry(); } // Do things only once per site collection if (string.IsNullOrEmpty(siteCollectionUrl)) { // Cross check Url property availability ccWeb.Site.EnsureProperty(s => s.Url); siteCollectionUrl = ccWeb.Site.Url; // Site scan SiteAnalyzer siteAnalyzer = new SiteAnalyzer(site, siteCollectionUrl, this); var siteScanDuration = siteAnalyzer.Analyze(ccWeb); pageSearchResults = siteAnalyzer.PageSearchResults; } // Web scan WebAnalyzer webAnalyzer = new WebAnalyzer(site, siteCollectionUrl, this, pageSearchResults); var webScanDuration = webAnalyzer.Analyze(ccWeb); } } catch (Exception ex) { ScanError error = new ScanError() { Error = ex.Message, SiteColUrl = e.Url, SiteURL = site, Field1 = "MainWebLoop", Field2 = ex.StackTrace, }; this.ScanErrors.Push(error); Console.WriteLine("Error for site {1}: {0}", ex.Message, site); } } } catch (Exception ex) { ScanError error = new ScanError() { Error = ex.Message, SiteColUrl = e.Url, SiteURL = e.Url, Field1 = "MainSiteLoop", Field2 = ex.StackTrace, }; this.ScanErrors.Push(error); Console.WriteLine("Error for site {1}: {0}", ex.Message, e.Url); } // Output the scanning progress try { TimeSpan ts = DateTime.Now.Subtract(this.StartTime); Console.WriteLine($"Thread: {Thread.CurrentThread.ManagedThreadId}. Processed {this.ScannedSites} of {this.SitesToScan} site collections ({Math.Round(((float)this.ScannedSites / (float)this.SitesToScan) * 100)}%). Process running for {ts.Days} days, {ts.Hours} hours, {ts.Minutes} minutes and {ts.Seconds} seconds."); } catch (Exception ex) { Console.WriteLine($"Error showing progress: {ex.ToString()}"); } }
private void VisioScanJob_TimerJobRun(object sender, OfficeDevPnP.Core.Framework.TimerJobs.TimerJobRunEventArgs e) { // Validate ClientContext objects if (e.WebClientContext == null || e.SiteClientContext == null) { ScanError error = new ScanError() { Error = "No valid ClientContext objects", SiteURL = e.Url, SiteColUrl = e.Url }; this.ScanErrors.Push(error); Console.WriteLine("Error for site {1}: {0}", "No valid ClientContext objects", e.Url); // bail out return; } // thread safe increase of the sites counter IncreaseScannedSites(); try { // Set the first site collection done flag + perform telemetry SetFirstSiteCollectionDone(e.WebClientContext, this.Name); // Manually iterate over the content IEnumerable <string> expandedSites = e.SiteClientContext.Site.GetAllSubSites(); bool isFirstSiteInList = true; string siteCollectionUrl = ""; List <Dictionary <string, string> > pageSearchResults = null; foreach (string site in expandedSites) { try { // thread safe increase of the webs counter IncreaseScannedWebs(); // Clone the existing ClientContext for the sub web using (ClientContext ccWeb = e.SiteClientContext.Clone(site)) { Console.WriteLine("Processing site {0}...", site); // Allow max server time out, might be needed for sites having a lot of users ccWeb.RequestTimeout = Timeout.Infinite; if (isFirstSiteInList) { // Perf optimization: do one call per site to load all the needed properties var spSite = (ccWeb as ClientContext).Site; ccWeb.Load(spSite, p => p.Url); ccWeb.ExecuteQueryRetry(); isFirstSiteInList = false; } ListCollection listCollection = ccWeb.Web.Lists; ccWeb.Load(listCollection, coll => coll.Include(li => li.Title, li => li.Hidden, li => li.DefaultViewUrl, li => li.BaseTemplate, li => li.RootFolder)); ccWeb.ExecuteQueryRetry(); // Do things only once per site collection if (string.IsNullOrEmpty(siteCollectionUrl)) { // Cross check Url property availability ccWeb.Site.EnsureProperty(s => s.Url); siteCollectionUrl = ccWeb.Site.Url; // Site scan SiteAnalyzer siteAnalyzer = new SiteAnalyzer(site, siteCollectionUrl, this); var siteScanDuration = siteAnalyzer.Analyze(ccWeb); pageSearchResults = siteAnalyzer.PageSearchResults; } VisioWebPartAnalyzer visioWebPartAnalyzer = new VisioWebPartAnalyzer(site, siteCollectionUrl, this, pageSearchResults); visioWebPartAnalyzer.Analyze(ccWeb); } } catch (Exception ex) { ScanError error = new ScanError() { Error = ex.Message, SiteColUrl = e.Url, SiteURL = site, Field1 = "MainWebLoop", Field2 = ex.StackTrace, }; this.ScanErrors.Push(error); Console.WriteLine("Error for site {1}: {0}", ex.Message, site); } } } catch (Exception ex) { ScanError error = new ScanError() { Error = ex.Message, SiteColUrl = e.Url, SiteURL = e.Url, Field1 = "MainSiteLoop", Field2 = ex.StackTrace, }; this.ScanErrors.Push(error); Console.WriteLine("Error for site {1}: {0}", ex.Message, e.Url); } // Output the scanning progress try { TimeSpan ts = DateTime.Now.Subtract(this.StartTime); Console.WriteLine($"Thread: {Thread.CurrentThread.ManagedThreadId}. Processed {this.ScannedSites} of {this.SitesToScan} site collections ({Math.Round(((float)this.ScannedSites / (float)this.SitesToScan) * 100)}%). Process running for {ts.Days} days, {ts.Hours} hours, {ts.Minutes} minutes and {ts.Seconds} seconds."); } catch (Exception ex) { Console.WriteLine($"Error showing progress: {ex.ToString()}"); } }