Beispiel #1
0
        private static void CheckForCustomSearchExperience(Web web, SiteScanResult scanResult, string searchCenterUrlProperty)
        {
            if (web.AllProperties.FieldValues.ContainsKey(searchCenterUrlProperty))
            {
                var searchSettingsValue = web.AllProperties.FieldValues[searchCenterUrlProperty] as string;
                if (!string.IsNullOrEmpty(searchSettingsValue))
                {
                    // Convert the settings into a typed object
                    var searchSettings = JsonConvert.DeserializeAnonymousType(searchSettingsValue, new
                    {
                        Inherit            = false,
                        ResultsPageAddress = String.Empty,
                        ShowNavigation     = false,
                    });

                    if (searchSettings != null && !searchSettings.Inherit)
                    {
                        // Return the search results page URL of the current web
                        scanResult.SearchCenterUrl = searchSettings?.ResultsPageAddress;
                    }
                }
            }
        }
Beispiel #2
0
 /// <summary>
 /// Publishing analyzer construction
 /// </summary>
 /// <param name="url">Url of the web to be analyzed</param>
 /// <param name="siteColUrl">Url of the site collection hosting this web</param>
 public PublishingAnalyzer(string url, string siteColUrl, ModernizationScanJob scanJob, WebScanResult webScanResult, SiteScanResult siteScanResult) : base(url, siteColUrl, scanJob)
 {
     this.webScanResult  = webScanResult;
     this.siteScanResult = siteScanResult;
 }
Beispiel #3
0
        /// <summary>
        /// Override of the scanner execute method, needed to output our results
        /// </summary>
        /// <returns>Time when scanning was started</returns>
        public override DateTime Execute()
        {
            // Triggers the run of the scanning...will result in ModernizationScanJob_TimerJobRun being called per site collection
            var start = base.Execute();

            // Handle the export of the job specific scanning data
            string outputfile = string.Format("{0}\\ModernizationSiteScanResults.csv", this.OutputFolder);

            string[] outputHeaders = new string[] { "SiteCollectionUrl", "SiteUrl",
                                                    "ReadyForGroupify", "GroupifyBlockers", "GroupifyWarnings", "GroupMode", "PermissionWarnings",
                                                    "ModernHomePage", "ModernUIWarnings",
                                                    "WebTemplate", "Office365GroupId", "MasterPage", "AlternateCSS", "UserCustomActions",
                                                    "SubSites", "SubSitesWithBrokenPermissionInheritance", "ModernPageWebFeatureDisabled", "ModernPageFeatureWasEnabledBySPO",
                                                    "ModernListSiteBlockingFeatureEnabled", "ModernListWebBlockingFeatureEnabled", "SitePublishingFeatureEnabled", "WebPublishingFeatureEnabled",
                                                    "ViewsRecent", "ViewsRecentUniqueUsers", "ViewsLifeTime", "ViewsLifeTimeUniqueUsers",
                                                    "Everyone(ExceptExternalUsers)Claim", "UsesADGroups", "ExternalSharing",
                                                    "Admins", "AdminContainsEveryone(ExceptExternalUsers)Claim", "AdminContainsADGroups",
                                                    "Owners", "OwnersContainsEveryone(ExceptExternalUsers)Claim", "OwnersContainsADGroups",
                                                    "Members", "MembersContainsEveryone(ExceptExternalUsers)Claim", "MembersContainsADGroups",
                                                    "Visitors", "VisitorsContainsEveryone(ExceptExternalUsers)Claim", "VisitorsContainsADGroups" };
            Console.WriteLine("Outputting scan results to {0}", outputfile);
            using (StreamWriter outfile = new StreamWriter(outputfile))
            {
                outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, outputHeaders)));
                foreach (var item in this.SiteScanResults)
                {
                    var groupifyBlockers = item.Value.GroupifyBlockers();
                    var groupifyWarnings = item.Value.GroupifyWarnings(this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim);
                    var modernWarnings   = item.Value.ModernWarnings();
                    var groupSecurity    = item.Value.PermissionModel(this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim);

                    outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, ToCsv(item.Value.SiteColUrl), ToCsv(item.Value.SiteURL),
                                                                       (groupifyBlockers.Count > 0 ? "FALSE" : "TRUE"), ToCsv(SiteScanResult.FormatList(groupifyBlockers)), ToCsv(SiteScanResult.FormatList(groupifyWarnings)), ToCsv(groupSecurity.Item1), ToCsv(SiteScanResult.FormatList(groupSecurity.Item2)),
                                                                       item.Value.ModernHomePage, ToCsv(SiteScanResult.FormatList(modernWarnings)),
                                                                       ToCsv(item.Value.WebTemplate), ToCsv(item.Value.Office365GroupId != Guid.Empty ? item.Value.Office365GroupId.ToString() : ""), item.Value.MasterPage, item.Value.AlternateCSS, ((item.Value.SiteUserCustomActions != null && item.Value.SiteUserCustomActions.Count > 0) || (item.Value.WebUserCustomActions != null && item.Value.WebUserCustomActions.Count > 0)),
                                                                       item.Value.SubSites, item.Value.SubSitesWithBrokenPermissionInheritance, item.Value.ModernPageWebFeatureDisabled, item.Value.ModernPageFeatureWasEnabledBySPO,
                                                                       item.Value.ModernListSiteBlockingFeatureEnabled, item.Value.ModernListWebBlockingFeatureEnabled, item.Value.SitePublishingFeatureEnabled, item.Value.WebPublishingFeatureEnabled,
                                                                       (SkipUsageInformation ? 0: item.Value.ViewsRecent), (SkipUsageInformation ? 0 : item.Value.ViewsRecentUniqueUsers), (SkipUsageInformation ? 0 : item.Value.ViewsLifeTime), (SkipUsageInformation ? 0 : item.Value.ViewsLifeTimeUniqueUsers),
                                                                       item.Value.EveryoneClaimsGranted, item.Value.ContainsADGroup(), ToCsv(item.Value.SharingCapabilities),
                                                                       ToCsv(SiteScanResult.FormatUserList(item.Value.Admins, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim)), item.Value.HasClaim(item.Value.Admins, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim), item.Value.ContainsADGroup(item.Value.Admins),
                                                                       ToCsv(SiteScanResult.FormatUserList(item.Value.Owners, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim)), item.Value.HasClaim(item.Value.Owners, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim), item.Value.ContainsADGroup(item.Value.Owners),
                                                                       ToCsv(SiteScanResult.FormatUserList(item.Value.Members, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim)), item.Value.HasClaim(item.Value.Members, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim), item.Value.ContainsADGroup(item.Value.Members),
                                                                       ToCsv(SiteScanResult.FormatUserList(item.Value.Visitors, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim)), item.Value.HasClaim(item.Value.Visitors, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim), item.Value.ContainsADGroup(item.Value.Visitors)
                                                                       )));
                }
            }

            outputfile    = string.Format("{0}\\ModernizationWebScanResults.csv", this.OutputFolder);
            outputHeaders = new string[] { "SiteCollectionUrl", "SiteUrl",
                                           "WebTemplate", "BrokenPermissionInheritance", "ModernPageWebFeatureDisabled", "ModernPageFeatureWasEnabledBySPO", "WebPublishingFeatureEnabled",
                                           "MasterPage", "CustomMasterPage", "AlternateCSS", "UserCustomActions",
                                           "Everyone(ExceptExternalUsers)Claim",
                                           "UniqueOwners",
                                           "UniqueMembers",
                                           "UniqueVisitors" };
            Console.WriteLine("Outputting scan results to {0}", outputfile);
            using (StreamWriter outfile = new StreamWriter(outputfile))
            {
                outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, outputHeaders)));
                foreach (var item in this.WebScanResults)
                {
                    outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, ToCsv(item.Value.SiteColUrl), ToCsv(item.Value.SiteURL),
                                                                       ToCsv(item.Value.WebTemplate), item.Value.BrokenPermissionInheritance, item.Value.ModernPageWebFeatureDisabled, item.Value.ModernPageFeatureWasEnabledBySPO, item.Value.WebPublishingFeatureEnabled,
                                                                       ToCsv(item.Value.MasterPage), ToCsv(item.Value.CustomMasterPage), ToCsv(item.Value.AlternateCSS), (item.Value.WebUserCustomActions.Count > 0),
                                                                       item.Value.EveryoneClaimsGranted,
                                                                       ToCsv(SiteScanResult.FormatUserList(item.Value.Owners, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim)),
                                                                       ToCsv(SiteScanResult.FormatUserList(item.Value.Members, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim)),
                                                                       ToCsv(SiteScanResult.FormatUserList(item.Value.Visitors, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim))
                                                                       )));
                }
            }

            outputfile    = string.Format("{0}\\ModernizationUserCustomActionScanResults.csv", this.OutputFolder);
            outputHeaders = new string[] { "SiteCollectionUrl", "SiteUrl",
                                           "Title", "Name", "Location", "RegistrationType", "RegistrationId", "Reason", "CommandAction", "ScriptBlock", "ScriptSrc" };
            Console.WriteLine("Outputting scan results to {0}", outputfile);
            using (StreamWriter outfile = new StreamWriter(outputfile))
            {
                outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, outputHeaders)));
                foreach (var item in this.SiteScanResults)
                {
                    if (item.Value.SiteUserCustomActions == null || item.Value.SiteUserCustomActions.Count == 0)
                    {
                        continue;
                    }

                    foreach (var uca in item.Value.SiteUserCustomActions)
                    {
                        outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, ToCsv(item.Value.SiteColUrl), ToCsv(item.Value.SiteURL),
                                                                           ToCsv(uca.Title), ToCsv(uca.Name), ToCsv(uca.Location), uca.RegistrationType, ToCsv(uca.RegistrationId), ToCsv(uca.Problem), ToCsv(uca.CommandAction), ToCsv(uca.ScriptBlock), ToCsv(uca.ScriptSrc)
                                                                           )));
                    }
                }
                foreach (var item in this.WebScanResults)
                {
                    if (item.Value.WebUserCustomActions == null || item.Value.WebUserCustomActions.Count == 0)
                    {
                        continue;
                    }

                    foreach (var uca in item.Value.WebUserCustomActions)
                    {
                        outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, ToCsv(item.Value.SiteColUrl), ToCsv(item.Value.SiteURL),
                                                                           ToCsv(uca.Title), ToCsv(uca.Name), ToCsv(uca.Location), uca.RegistrationType, ToCsv(uca.RegistrationId), ToCsv(uca.Problem), ToCsv(uca.CommandAction), ToCsv(uca.ScriptBlock), ToCsv(uca.ScriptSrc)
                                                                           )));
                    }
                }
            }

            if (Options.IncludeLists(this.Mode))
            {
                outputfile    = string.Format("{0}\\ModernizationListScanResults.csv", this.OutputFolder);
                outputHeaders = new string[] { "Url", "Site Url", "Site Collection Url", "List Title", "Only blocked by OOB reasons",
                                               "Blocked at site level", "Blocked at web level", "Blocked at list level", "List page render type", "List experience", "Blocked by not being able to load Page", "Blocked by not being able to load page exception",
                                               "Blocked by managed metadata navigation", "Blocked by view type", "View type", "Blocked by list base template", "List base template",
                                               "Blocked by zero or multiple web parts", "Blocked by JSLink", "JSLink", "Blocked by XslLink", "XslLink", "Blocked by Xsl",
                                               "Blocked by JSLink field", "JSLink fields", "Blocked by business data field", "Business data fields", "Blocked by task outcome field", "Task outcome fields",
                                               "Blocked by publishingField", "Publishing fields", "Blocked by geo location field", "Geo location fields", "Blocked by list custom action", "List custom actions" };

                Console.WriteLine("Outputting scan results to {0}", outputfile);
                using (StreamWriter outfile = new StreamWriter(outputfile))
                {
                    outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, outputHeaders)));
                    foreach (var list in this.ListScanResults)
                    {
                        outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, ToCsv(list.Key.Substring(36)), ToCsv(list.Value.SiteURL), ToCsv(list.Value.SiteColUrl), ToCsv(list.Value.ListTitle), list.Value.OnlyBlockedByOOBReasons,
                                                                           list.Value.BlockedAtSiteLevel, list.Value.BlockedAtWebLevel, list.Value.BlockedAtListLevel, list.Value.PageRenderType, list.Value.ListExperience, list.Value.BlockedByNotBeingAbleToLoadPage, ToCsv(list.Value.BlockedByNotBeingAbleToLoadPageException),
                                                                           list.Value.XsltViewWebPartCompatibility.BlockedByManagedMetadataNavFeature, list.Value.XsltViewWebPartCompatibility.BlockedByViewType, ToCsv(list.Value.XsltViewWebPartCompatibility.ViewType), list.Value.XsltViewWebPartCompatibility.BlockedByListBaseTemplate, list.Value.XsltViewWebPartCompatibility.ListBaseTemplate,
                                                                           list.Value.BlockedByZeroOrMultipleWebParts, list.Value.XsltViewWebPartCompatibility.BlockedByJSLink, ToCsv(list.Value.XsltViewWebPartCompatibility.JSLink), list.Value.XsltViewWebPartCompatibility.BlockedByXslLink, ToCsv(list.Value.XsltViewWebPartCompatibility.XslLink), list.Value.XsltViewWebPartCompatibility.BlockedByXsl,
                                                                           list.Value.XsltViewWebPartCompatibility.BlockedByJSLinkField, ToCsv(list.Value.XsltViewWebPartCompatibility.JSLinkFields), list.Value.XsltViewWebPartCompatibility.BlockedByBusinessDataField, ToCsv(list.Value.XsltViewWebPartCompatibility.BusinessDataFields), list.Value.XsltViewWebPartCompatibility.BlockedByTaskOutcomeField, ToCsv(list.Value.XsltViewWebPartCompatibility.TaskOutcomeFields),
                                                                           list.Value.XsltViewWebPartCompatibility.BlockedByPublishingField, ToCsv(list.Value.XsltViewWebPartCompatibility.PublishingFields), list.Value.XsltViewWebPartCompatibility.BlockedByGeoLocationField, ToCsv(list.Value.XsltViewWebPartCompatibility.GeoLocationFields), list.Value.XsltViewWebPartCompatibility.BlockedByListCustomAction, ToCsv(list.Value.XsltViewWebPartCompatibility.ListCustomActions)
                                                                           )));
                    }
                }
            }

            if (Options.IncludePage(this.Mode))
            {
                outputfile    = string.Format("{0}\\PageScanResults.csv", this.OutputFolder);
                outputHeaders = new string[] { "SiteCollectionUrl", "SiteUrl", "PageUrl", "Library", "HomePage",
                                               "Type", "Layout", "Mapping %", "Unmapped web parts", "ModifiedBy", "ModifiedAt",
                                               "ViewsRecent", "ViewsRecentUniqueUsers", "ViewsLifeTime", "ViewsLifeTimeUniqueUsers" };
                Console.WriteLine("Outputting scan results to {0}", outputfile);

                string header1 = string.Join(this.Separator, outputHeaders);
                string header2 = "";
                for (int i = 1; i <= 30; i++)
                {
                    if (ExportWebPartProperties)
                    {
                        header2 = header2 + $"{this.Separator}WPType{i}{this.Separator}WPTitle{i}{this.Separator}WPData{i}";
                    }
                    else
                    {
                        header2 = header2 + $"{this.Separator}WPType{i}{this.Separator}WPTitle{i}";
                    }
                }

                List <string> UniqueWebParts = new List <string>();
                using (StreamWriter outfile = new StreamWriter(outputfile))
                {
                    outfile.Write(string.Format("{0}\r\n", header1 + header2));
                    foreach (var item in this.PageScanResults)
                    {
                        var part1 = string.Join(this.Separator, ToCsv(item.Value.SiteColUrl), ToCsv(item.Value.SiteURL), ToCsv(item.Value.PageUrl), ToCsv(item.Value.Library), item.Value.HomePage,
                                                ToCsv(item.Value.PageType), ToCsv(item.Value.Layout), "{MappingPercentage}", "{UnmappedWebParts}", ToCsv(item.Value.ModifiedBy), item.Value.ModifiedAt,
                                                (SkipUsageInformation ? 0 : item.Value.ViewsRecent), (SkipUsageInformation ? 0 : item.Value.ViewsRecentUniqueUsers), (SkipUsageInformation ? 0 : item.Value.ViewsLifeTime), (SkipUsageInformation ? 0 : item.Value.ViewsLifeTimeUniqueUsers));

                        string part2 = "";
                        if (item.Value.WebParts != null)
                        {
                            int           webPartsOnPage       = item.Value.WebParts.Count();
                            int           webPartsOnPageMapped = 0;
                            List <string> nonMappedWebParts    = new List <string>();
                            foreach (var webPart in item.Value.WebParts.OrderBy(p => p.Row).ThenBy(p => p.Column).ThenBy(p => p.Order))
                            {
                                var found = this.PageTransformation.WebParts.Where(p => p.Type.Equals(webPart.Type, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                                if (found != null && found.Mappings != null)
                                {
                                    webPartsOnPageMapped++;
                                }
                                else
                                {
                                    var t = webPart.Type.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)[0];
                                    if (!nonMappedWebParts.Contains(t))
                                    {
                                        nonMappedWebParts.Add(t);
                                    }
                                }

                                if (ExportWebPartProperties)
                                {
                                    part2 = part2 + $"{this.Separator}{ToCsv(webPart.TypeShort())}{this.Separator}{ToCsv(webPart.Title)}{this.Separator}{ToCsv(webPart.Json())}";
                                }
                                else
                                {
                                    part2 = part2 + $"{this.Separator}{ToCsv(webPart.TypeShort())}{this.Separator}{ToCsv(webPart.Title)}";
                                }

                                if (!UniqueWebParts.Contains(webPart.Type))
                                {
                                    UniqueWebParts.Add(webPart.Type);
                                }
                            }
                            part1 = part1.Replace("{MappingPercentage}", webPartsOnPage == 0 ? "100" : String.Format("{0:0}", (((double)webPartsOnPageMapped / (double)webPartsOnPage) * 100))).Replace("{UnmappedWebParts}", SiteScanResult.FormatList(nonMappedWebParts));
                        }
                        else
                        {
                            part1 = part1.Replace("{MappingPercentage}", "").Replace("{UnmappedWebParts}", "");
                        }

                        outfile.Write(string.Format("{0}\r\n", part1 + (!string.IsNullOrEmpty(part2) ? part2 : "")));
                    }
                }

                outputfile = string.Format("{0}\\UniqueWebParts.csv", this.OutputFolder);
                Console.WriteLine("Outputting scan results to {0}", outputfile);
                using (StreamWriter outfile = new StreamWriter(outputfile))
                {
                    outfile.Write(string.Format("{0}\r\n", $"Type{this.Separator}InMappingFile"));
                    foreach (var type in UniqueWebParts)
                    {
                        var found = this.PageTransformation.WebParts.Where(p => p.Type.Equals(type, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                        outfile.Write(string.Format("{0}\r\n", $"{ToCsv(type)}{this.Separator}{found != null}"));
                    }
                }
            }

            if (Options.IncludePublishing(this.Mode))
            {
                // "Calculate" publishing site results based upon the web/page level data we retrieved
                this.PublishingSiteScanResults = PublishingAnalyzer.GeneratePublishingSiteResults(this.Mode, this.PublishingWebScanResults, this.PublishingPageScanResults);

                // Export the site publishing data
                outputfile    = string.Format("{0}\\ModernizationPublishingSiteScanResults.csv", this.OutputFolder);
                outputHeaders = new string[] { "SiteCollectionUrl", "NumberOfWebs", "NumberOfPages",
                                               "UsedSiteMasterPages", "UsedSystemMasterPages",
                                               "UsedPageLayouts", "LastPageUpdateDate" };
                Console.WriteLine("Outputting scan results to {0}", outputfile);
                using (StreamWriter outfile = new StreamWriter(outputfile))
                {
                    outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, outputHeaders)));
                    if (PublishingSiteScanResults != null)
                    {
                        foreach (var item in this.PublishingSiteScanResults)
                        {
                            outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, ToCsv(item.Value.SiteColUrl), item.Value.NumberOfWebs, item.Value.NumberOfPages,
                                                                               ToCsv(PublishingPageScanResult.FormatList(item.Value.UsedSiteMasterPages)), ToCsv(PublishingPageScanResult.FormatList(item.Value.UsedSystemMasterPages)),
                                                                               ToCsv(PublishingPageScanResult.FormatList(item.Value.UsedPageLayouts)), item.Value.LastPageUpdateDate.HasValue ? item.Value.LastPageUpdateDate.ToString() : ""
                                                                               )));
                        }
                    }
                }

                // Export the web publishing data
                outputfile    = string.Format("{0}\\ModernizationPublishingWebScanResults.csv", this.OutputFolder);
                outputHeaders = new string[] { "SiteCollectionUrl", "SiteUrl", "WebRelativeUrl",
                                               "WebTemplate", "Level", "PageCount", "Language", "VariationLabels", "VariationSourceLabel",
                                               "SiteMasterPage", "SystemMasterPage", "AlternateCSS",
                                               "AllowedPageLayouts", "PageLayoutsConfiguration", "DefaultPageLayout",
                                               "GlobalNavigationType", "GlobalStructuralNavigationShowSubSites", "GlobalStructuralNavigationShowPages", "GlobalStructuralNavigationShowSiblings", "GlobalStructuralNavigationMaxCount", "GlobalManagedNavigationTermSetId",
                                               "CurrentNavigationType", "CurrentStructuralNavigationShowSubSites", "CurrentStructuralNavigationShowPages", "CurrentStructuralNavigationShowSiblings", "CurrentStructuralNavigationMaxCount", "CurrentManagedNavigationTermSetId",
                                               "ManagedNavigationAddNewPages", "ManagedNavigationCreateFriendlyUrls",
                                               "LibraryItemScheduling", "LibraryEnableModeration", "LibraryEnableVersioning", "LibraryEnableMinorVersions", "LibraryApprovalWorkflowDefined",
                                               "BrokenPermissionInheritance",
                                               "Admins",
                                               "Owners" };
                Console.WriteLine("Outputting scan results to {0}", outputfile);
                using (StreamWriter outfile = new StreamWriter(outputfile))
                {
                    outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, outputHeaders)));
                    foreach (var item in this.PublishingWebScanResults)
                    {
                        outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, ToCsv(item.Value.SiteColUrl), ToCsv(item.Value.SiteURL), ToCsv(item.Value.WebRelativeUrl),
                                                                           ToCsv(item.Value.WebTemplate), item.Value.Level.ToString(), item.Value.PageCount.ToString(), item.Value.Language.ToString(), ToCsv(item.Value.VariationLabels), ToCsv(item.Value.VariationSourceLabel),
                                                                           ToCsv(item.Value.SiteMasterPage), ToCsv(item.Value.SystemMasterPage), ToCsv(item.Value.AlternateCSS),
                                                                           ToCsv(item.Value.AllowedPageLayouts), ToCsv(item.Value.PageLayoutsConfiguration), ToCsv(item.Value.DefaultPageLayout),
                                                                           ToCsv(item.Value.GlobalNavigationType), item.Value.GlobalStructuralNavigationShowSubSites.HasValue ? item.Value.GlobalStructuralNavigationShowSubSites.Value.ToString() : "", item.Value.GlobalStructuralNavigationShowPages.HasValue ? item.Value.GlobalStructuralNavigationShowPages.Value.ToString() : "", item.Value.GlobalStructuralNavigationShowSiblings.HasValue ? item.Value.GlobalStructuralNavigationShowSiblings.Value.ToString() : "", item.Value.GlobalStructuralNavigationMaxCount.HasValue ? item.Value.GlobalStructuralNavigationMaxCount.Value.ToString() : "", ToCsv(item.Value.GlobalManagedNavigationTermSetId),
                                                                           ToCsv(item.Value.CurrentNavigationType), item.Value.CurrentStructuralNavigationShowSubSites.HasValue ? item.Value.CurrentStructuralNavigationShowSubSites.Value.ToString() : "", item.Value.CurrentStructuralNavigationShowPages.HasValue ? item.Value.CurrentStructuralNavigationShowPages.Value.ToString() : "", item.Value.CurrentStructuralNavigationShowSiblings.HasValue ? item.Value.CurrentStructuralNavigationShowSiblings.Value.ToString() : "", item.Value.CurrentStructuralNavigationMaxCount.HasValue ? item.Value.CurrentStructuralNavigationMaxCount.Value.ToString() : "", ToCsv(item.Value.CurrentManagedNavigationTermSetId),
                                                                           item.Value.ManagedNavigationAddNewPages.HasValue ? item.Value.ManagedNavigationAddNewPages.ToString() : "", item.Value.ManagedNavigationCreateFriendlyUrls.HasValue ? item.Value.ManagedNavigationCreateFriendlyUrls.ToString() : "",
                                                                           item.Value.LibraryItemScheduling.ToString(), item.Value.LibraryEnableModeration.ToString(), item.Value.LibraryEnableVersioning.ToString(), item.Value.LibraryEnableMinorVersions.ToString(), item.Value.LibraryApprovalWorkflowDefined.ToString(),
                                                                           item.Value.BrokenPermissionInheritance.ToString(),
                                                                           ToCsv(SiteScanResult.FormatUserList(item.Value.Admins, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim)),
                                                                           ToCsv(SiteScanResult.FormatUserList(item.Value.Owners, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim))
                                                                           )));
                    }
                }

                if (Options.IncludePublishingWithPages(this.Mode))
                {
                    // Export the page publishing data
                    outputfile    = string.Format("{0}\\ModernizationPublishingPageScanResults.csv", this.OutputFolder);
                    outputHeaders = new string[] { "SiteCollectionUrl", "SiteUrl", "WebRelativeUrl", "PageRelativeUrl", "PageName",
                                                   "ContentType", "ContentTypeId", "PageLayout", "PageLayoutFile",
                                                   "GlobalAudiences", "SecurityGroupAudiences", "SharePointGroupAudiences",
                                                   "ModifiedAt", "ModifiedBy", "Mapping %" };

                    string header1 = string.Join(this.Separator, outputHeaders);
                    string header2 = "";
                    for (int i = 1; i <= 20; i++)
                    {
                        if (ExportWebPartProperties)
                        {
                            header2 = header2 + $"{this.Separator}WPType{i}{this.Separator}WPTitle{i}{this.Separator}WPData{i}";
                        }
                        else
                        {
                            header2 = header2 + $"{this.Separator}WPType{i}{this.Separator}WPTitle{i}";
                        }
                    }

                    Console.WriteLine("Outputting scan results to {0}", outputfile);
                    using (StreamWriter outfile = new StreamWriter(outputfile))
                    {
                        outfile.Write(string.Format("{0}\r\n", header1 + header2));
                        foreach (var item in this.PublishingPageScanResults)
                        {
                            var part1 = string.Join(this.Separator, ToCsv(item.Value.SiteColUrl), ToCsv(item.Value.SiteURL), ToCsv(item.Value.WebRelativeUrl), ToCsv(item.Value.PageRelativeUrl), ToCsv(item.Value.PageName),
                                                    ToCsv(item.Value.ContentType), ToCsv(item.Value.ContentTypeId), ToCsv(item.Value.PageLayout), ToCsv(item.Value.PageLayoutFile),
                                                    ToCsv(PublishingPageScanResult.FormatList(item.Value.GlobalAudiences)), ToCsv(PublishingPageScanResult.FormatList(item.Value.SecurityGroupAudiences, "|")), ToCsv(PublishingPageScanResult.FormatList(item.Value.SharePointGroupAudiences)),
                                                    item.Value.ModifiedAt, ToCsv(item.Value.ModifiedBy), "{MappingPercentage}"
                                                    );

                            string part2 = "";
                            if (item.Value.WebParts != null)
                            {
                                int           webPartsOnPage       = item.Value.WebParts.Count();
                                int           webPartsOnPageMapped = 0;
                                List <string> nonMappedWebParts    = new List <string>();
                                foreach (var webPart in item.Value.WebParts.OrderBy(p => p.Row).ThenBy(p => p.Column).ThenBy(p => p.Order))
                                {
                                    var found = this.PageTransformation.WebParts.Where(p => p.Type.Equals(webPart.Type, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                                    if (found != null && found.Mappings != null)
                                    {
                                        webPartsOnPageMapped++;
                                    }
                                    else
                                    {
                                        var t = webPart.Type.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)[0];
                                        if (!nonMappedWebParts.Contains(t))
                                        {
                                            nonMappedWebParts.Add(t);
                                        }
                                    }

                                    if (ExportWebPartProperties)
                                    {
                                        part2 = part2 + $"{this.Separator}{ToCsv(webPart.TypeShort())}{this.Separator}{ToCsv(webPart.Title)}{this.Separator}{ToCsv(webPart.Json())}";
                                    }
                                    else
                                    {
                                        part2 = part2 + $"{this.Separator}{ToCsv(webPart.TypeShort())}{this.Separator}{ToCsv(webPart.Title)}";
                                    }
                                }
                                part1 = part1.Replace("{MappingPercentage}", webPartsOnPage == 0 ? "100" : String.Format("{0:0}", (((double)webPartsOnPageMapped / (double)webPartsOnPage) * 100))).Replace("{UnmappedWebParts}", SiteScanResult.FormatList(nonMappedWebParts));
                            }
                            else
                            {
                                part1 = part1.Replace("{MappingPercentage}", "").Replace("{UnmappedWebParts}", "");
                            }

                            outfile.Write(string.Format("{0}\r\n", part1 + (!string.IsNullOrEmpty(part2) ? part2 : "")));
                        }
                    }
                }
            }

            Console.WriteLine("=====================================================");
            Console.WriteLine("All done. Took {0} for {1} sites", (DateTime.Now - start).ToString(), this.ScannedSites);
            Console.WriteLine("=====================================================");

            return(start);
        }
        /// <summary>
        /// Override of the scanner execute method, needed to output our results
        /// </summary>
        /// <returns>Time when scanning was started</returns>
        public override DateTime Execute()
        {
            // Triggers the run of the scanning...will result in ModernizationScanJob_TimerJobRun being called per site collection
            var start = base.Execute();

            // Handle the export of the job specific scanning data
            string outputfile = string.Format("{0}\\ModernizationSiteScanResults.csv", this.OutputFolder);

            string[] outputHeaders = new string[] { "SiteCollectionUrl", "SiteUrl",
                                                    "ReadyForGroupify", "GroupifyBlockers", "GroupifyWarnings", "GroupMode", "PermissionWarnings",
                                                    "ModernHomePage", "ModernUIWarnings",
                                                    "WebTemplate", "Office365GroupId", "MasterPage", "AlternateCSS", "UserCustomActions",
                                                    "SubSites", "SubSitesWithBrokenPermissionInheritance", "ModernPageWebFeatureDisabled", "ModernPageFeatureWasEnabledBySPO",
                                                    "ModernListSiteBlockingFeatureEnabled", "ModernListWebBlockingFeatureEnabled", "SitePublishingFeatureEnabled", "WebPublishingFeatureEnabled",
                                                    "ViewsRecent", "ViewsRecentUniqueUsers", "ViewsLifeTime", "ViewsLifeTimeUniqueUsers",
                                                    "Everyone(ExceptExternalUsers)Claim", "UsesADGroups", "ExternalSharing",
                                                    "Admins", "AdminContainsEveryone(ExceptExternalUsers)Claim", "AdminContainsADGroups",
                                                    "Owners", "OwnersContainsEveryone(ExceptExternalUsers)Claim", "OwnersContainsADGroups",
                                                    "Members", "MembersContainsEveryone(ExceptExternalUsers)Claim", "MembersContainsADGroups",
                                                    "Visitors", "VisitorsContainsEveryone(ExceptExternalUsers)Claim", "VisitorsContainsADGroups" };
            Console.WriteLine("Outputting scan results to {0}", outputfile);
            using (StreamWriter outfile = new StreamWriter(outputfile))
            {
                outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, outputHeaders)));
                foreach (var item in this.SiteScanResults)
                {
                    var groupifyBlockers = item.Value.GroupifyBlockers();
                    var groupifyWarnings = item.Value.GroupifyWarnings();
                    var modernWarnings   = item.Value.ModernWarnings();
                    var groupSecurity    = item.Value.PermissionModel(this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim);

                    outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, ToCsv(item.Value.SiteColUrl), ToCsv(item.Value.SiteURL),
                                                                       (groupifyBlockers.Count > 0 ? "FALSE" : "TRUE"), ToCsv(SiteScanResult.FormatList(groupifyBlockers)), ToCsv(SiteScanResult.FormatList(groupifyWarnings)), ToCsv(groupSecurity.Item1), ToCsv(SiteScanResult.FormatList(groupSecurity.Item2)),
                                                                       item.Value.ModernHomePage, ToCsv(SiteScanResult.FormatList(modernWarnings)),
                                                                       ToCsv(item.Value.WebTemplate), ToCsv(item.Value.Office365GroupId != Guid.Empty ? item.Value.Office365GroupId.ToString() : ""), item.Value.MasterPage, item.Value.AlternateCSS, ((item.Value.SiteUserCustomActions != null && item.Value.SiteUserCustomActions.Count > 0) || (item.Value.WebUserCustomActions != null && item.Value.WebUserCustomActions.Count > 0)),
                                                                       item.Value.SubSites, item.Value.SubSitesWithBrokenPermissionInheritance, item.Value.ModernPageWebFeatureDisabled, item.Value.ModernPageFeatureWasEnabledBySPO,
                                                                       item.Value.ModernListSiteBlockingFeatureEnabled, item.Value.ModernListWebBlockingFeatureEnabled, item.Value.SitePublishingFeatureEnabled, item.Value.WebPublishingFeatureEnabled,
                                                                       (SkipUsageInformation ? 0: item.Value.ViewsRecent), (SkipUsageInformation ? 0 : item.Value.ViewsRecentUniqueUsers), (SkipUsageInformation ? 0 : item.Value.ViewsLifeTime), (SkipUsageInformation ? 0 : item.Value.ViewsLifeTimeUniqueUsers),
                                                                       item.Value.EveryoneClaimsGranted, item.Value.ContainsADGroup(), ToCsv(item.Value.SharingCapabilities),
                                                                       ToCsv(SiteScanResult.FormatUserList(item.Value.Admins, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim)), item.Value.HasClaim(item.Value.Admins, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim), item.Value.ContainsADGroup(item.Value.Admins),
                                                                       ToCsv(SiteScanResult.FormatUserList(item.Value.Owners, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim)), item.Value.HasClaim(item.Value.Owners, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim), item.Value.ContainsADGroup(item.Value.Owners),
                                                                       ToCsv(SiteScanResult.FormatUserList(item.Value.Members, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim)), item.Value.HasClaim(item.Value.Members, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim), item.Value.ContainsADGroup(item.Value.Members),
                                                                       ToCsv(SiteScanResult.FormatUserList(item.Value.Visitors, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim)), item.Value.HasClaim(item.Value.Visitors, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim), item.Value.ContainsADGroup(item.Value.Visitors)
                                                                       )));
                }
            }

            outputfile    = string.Format("{0}\\ModernizationWebScanResults.csv", this.OutputFolder);
            outputHeaders = new string[] { "SiteCollectionUrl", "SiteUrl",
                                           "WebTemplate", "BrokenPermissionInheritance", "ModernPageWebFeatureDisabled", "ModernPageFeatureWasEnabledBySPO", "WebPublishingFeatureEnabled",
                                           "MasterPage", "CustomMasterPage", "AlternateCSS", "UserCustomActions",
                                           "Everyone(ExceptExternalUsers)Claim",
                                           "UniqueOwners",
                                           "UniqueMembers",
                                           "UniqueVisitors" };
            Console.WriteLine("Outputting scan results to {0}", outputfile);
            using (StreamWriter outfile = new StreamWriter(outputfile))
            {
                outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, outputHeaders)));
                foreach (var item in this.WebScanResults)
                {
                    outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, ToCsv(item.Value.SiteColUrl), ToCsv(item.Value.SiteURL),
                                                                       ToCsv(item.Value.WebTemplate), item.Value.BrokenPermissionInheritance, item.Value.ModernPageWebFeatureDisabled, item.Value.ModernPageFeatureWasEnabledBySPO, item.Value.WebPublishingFeatureEnabled,
                                                                       ToCsv(item.Value.MasterPage), ToCsv(item.Value.CustomMasterPage), ToCsv(item.Value.AlternateCSS), (item.Value.WebUserCustomActions.Count > 0),
                                                                       item.Value.EveryoneClaimsGranted,
                                                                       ToCsv(SiteScanResult.FormatUserList(item.Value.Owners, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim)),
                                                                       ToCsv(SiteScanResult.FormatUserList(item.Value.Members, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim)),
                                                                       ToCsv(SiteScanResult.FormatUserList(item.Value.Visitors, this.EveryoneClaim, this.EveryoneExceptExternalUsersClaim))
                                                                       )));
                }
            }

            outputfile    = string.Format("{0}\\ModernizationUserCustomActionScanResults.csv", this.OutputFolder);
            outputHeaders = new string[] { "SiteCollectionUrl", "SiteUrl",
                                           "Title", "Name", "Location", "RegistrationType", "RegistrationId", "Reason", "CommandAction", "ScriptBlock", "ScriptSrc" };
            Console.WriteLine("Outputting scan results to {0}", outputfile);
            using (StreamWriter outfile = new StreamWriter(outputfile))
            {
                outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, outputHeaders)));
                foreach (var item in this.SiteScanResults)
                {
                    if (item.Value.SiteUserCustomActions == null || item.Value.SiteUserCustomActions.Count == 0)
                    {
                        continue;
                    }

                    foreach (var uca in item.Value.SiteUserCustomActions)
                    {
                        outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, ToCsv(item.Value.SiteColUrl), ToCsv(item.Value.SiteURL),
                                                                           ToCsv(uca.Title), ToCsv(uca.Name), ToCsv(uca.Location), uca.RegistrationType, ToCsv(uca.RegistrationId), ToCsv(uca.Problem), ToCsv(uca.CommandAction), ToCsv(uca.ScriptBlock), ToCsv(uca.ScriptSrc)
                                                                           )));
                    }
                }
                foreach (var item in this.WebScanResults)
                {
                    if (item.Value.WebUserCustomActions == null || item.Value.WebUserCustomActions.Count == 0)
                    {
                        continue;
                    }

                    foreach (var uca in item.Value.WebUserCustomActions)
                    {
                        outfile.Write(string.Format("{0}\r\n", string.Join(this.Separator, ToCsv(item.Value.SiteColUrl), ToCsv(item.Value.SiteURL),
                                                                           ToCsv(uca.Title), ToCsv(uca.Name), ToCsv(uca.Location), uca.RegistrationType, ToCsv(uca.RegistrationId), ToCsv(uca.Problem), ToCsv(uca.CommandAction), ToCsv(uca.ScriptBlock), ToCsv(uca.ScriptSrc)
                                                                           )));
                    }
                }
            }

            if (this.Mode == Mode.Full)
            {
                outputfile    = string.Format("{0}\\PageScanResults.csv", this.OutputFolder);
                outputHeaders = new string[] { "SiteCollectionUrl", "SiteUrl", "PageUrl", "Library", "HomePage",
                                               "Type", "Layout", "Mapping %", "Unmapped web parts", "ModifiedBy", "ModifiedAt",
                                               "ViewsRecent", "ViewsRecentUniqueUsers", "ViewsLifeTime", "ViewsLifeTimeUniqueUsers" };
                Console.WriteLine("Outputting scan results to {0}", outputfile);

                string header1 = string.Join(this.Separator, outputHeaders);
                string header2 = "";
                for (int i = 1; i <= 30; i++)
                {
                    if (ExportWebPartProperties)
                    {
                        header2 = header2 + $"{this.Separator}WPType{i}{this.Separator}WPTitle{i}{this.Separator}WPData{i}";
                    }
                    else
                    {
                        header2 = header2 + $"{this.Separator}WPType{i}{this.Separator}WPTitle{i}";
                    }
                }

                List <string> UniqueWebParts = new List <string>();
                using (StreamWriter outfile = new StreamWriter(outputfile))
                {
                    outfile.Write(string.Format("{0}\r\n", header1 + header2));
                    foreach (var item in this.PageScanResults)
                    {
                        var part1 = string.Join(this.Separator, ToCsv(item.Value.SiteColUrl), ToCsv(item.Value.SiteURL), ToCsv(item.Value.PageUrl), ToCsv(item.Value.Library), item.Value.HomePage,
                                                ToCsv(item.Value.PageType), ToCsv(item.Value.Layout), "{MappingPercentage}", "{UnmappedWebParts}", ToCsv(item.Value.ModifiedBy), item.Value.ModifiedAt,
                                                (SkipUsageInformation ? 0 : item.Value.ViewsRecent), (SkipUsageInformation ? 0 : item.Value.ViewsRecentUniqueUsers), (SkipUsageInformation ? 0 : item.Value.ViewsLifeTime), (SkipUsageInformation ? 0 : item.Value.ViewsLifeTimeUniqueUsers));

                        string part2 = "";
                        if (item.Value.WebParts != null)
                        {
                            int           webPartsOnPage       = item.Value.WebParts.Count();
                            int           webPartsOnPageMapped = 0;
                            List <string> nonMappedWebParts    = new List <string>();
                            foreach (var webPart in item.Value.WebParts.OrderBy(p => p.Row).ThenBy(p => p.Column).ThenBy(p => p.Order))
                            {
                                var found = this.PageTransformation.WebParts.Where(p => p.Type.Equals(webPart.Type, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                                if (found != null && found.Mappings != null)
                                {
                                    webPartsOnPageMapped++;
                                }
                                else
                                {
                                    var t = webPart.Type.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)[0];
                                    if (!nonMappedWebParts.Contains(t))
                                    {
                                        nonMappedWebParts.Add(t);
                                    }
                                }

                                if (ExportWebPartProperties)
                                {
                                    part2 = part2 + $"{this.Separator}{ToCsv(webPart.TypeShort())}{this.Separator}{ToCsv(webPart.Title)}{this.Separator}{ToCsv(webPart.Json())}";
                                }
                                else
                                {
                                    part2 = part2 + $"{this.Separator}{ToCsv(webPart.TypeShort())}{this.Separator}{ToCsv(webPart.Title)}";
                                }

                                if (!UniqueWebParts.Contains(webPart.Type))
                                {
                                    UniqueWebParts.Add(webPart.Type);
                                }
                            }
                            part1 = part1.Replace("{MappingPercentage}", webPartsOnPage == 0 ? "100" : String.Format("{0:0}", (((double)webPartsOnPageMapped / (double)webPartsOnPage) * 100))).Replace("{UnmappedWebParts}", SiteScanResult.FormatList(nonMappedWebParts));
                        }
                        else
                        {
                            part1 = part1.Replace("{MappingPercentage}", "").Replace("{UnmappedWebParts}", "");
                        }

                        outfile.Write(string.Format("{0}\r\n", part1 + (!string.IsNullOrEmpty(part2) ? part2 : "")));
                    }
                }

                outputfile = string.Format("{0}\\UniqueWebParts.csv", this.OutputFolder);
                Console.WriteLine("Outputting scan results to {0}", outputfile);
                using (StreamWriter outfile = new StreamWriter(outputfile))
                {
                    outfile.Write(string.Format("{0}\r\n", $"Type{this.Separator}InMappingFile"));
                    foreach (var type in UniqueWebParts)
                    {
                        var found = this.PageTransformation.WebParts.Where(p => p.Type.Equals(type, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                        outfile.Write(string.Format("{0}\r\n", $"{ToCsv(type)}{this.Separator}{found != null}"));
                    }
                }
            }

            Console.WriteLine("=====================================================");
            Console.WriteLine("All done. Took {0} for {1} sites", (DateTime.Now - start).ToString(), this.ScannedSites);
            Console.WriteLine("=====================================================");

            return(start);
        }
Beispiel #5
0
        /// <summary>
        /// Analyze the site collection
        /// </summary>
        /// <param name="cc">ClientContext of the site to be analyzed</param>
        /// <returns>Duration of the analysis</returns>
        public override TimeSpan Analyze(ClientContext cc)
        {
            try
            {
                base.Analyze(cc);
                Site site = cc.Site;
                site.EnsureProperties(p => p.UserCustomActions, p => p.Features, p => p.Url, p => p.GroupId, p => p.Id);
                Web web = cc.Web;
                cc.Web.EnsureProperties(p => p.WebTemplate, p => p.Configuration);

                if (cc.Web.WebTemplate.Equals("TEAMCHANNEL", StringComparison.InvariantCultureIgnoreCase))
                {
                    return(new TimeSpan((this.StopTime.Subtract(this.StartTime).Ticks)));
                }

                SiteScanResult scanResult = new SiteScanResult()
                {
                    SiteColUrl = this.SiteCollectionUrl,
                    SiteURL    = this.SiteUrl,
                    SiteId     = site.Id.ToString(),
                };

                // Perform specific analysis work

                // Persist web template of the root site
                scanResult.WebTemplate = $"{web.WebTemplate}#{web.Configuration}";

                // Is this the root site collection of the tenant
                scanResult.IsRootSite = new Uri(this.SiteCollectionUrl).PathAndQuery.Equals("/");

                // Is this site group connected
                scanResult.Office365GroupId = site.GroupId;

                if (site.GroupId != Guid.Empty)
                {
                    if (this.ScanJob.TeamifiedSiteCollectionsLoaded)
                    {
                        if (this.ScanJob.TeamifiedSiteCollections.Contains(site.GroupId))
                        {
                            scanResult.HasTeamsTeam = true;
                        }
                        else
                        {
                            scanResult.HasTeamsTeam = false;
                        }
                    }
                    else
                    {
                        // we did not have the needed permissions to load the groups, hence leave the nullable bool null
                    }
                }
                else
                {
                    // We're sure there's no team as there's no group
                    scanResult.HasTeamsTeam = false;
                }

                // Search for site scoped search center url
                if (web.AllProperties.FieldValues.ContainsKey("SRCH_ENH_FTR_URL_SITE"))
                {
                    scanResult.SearchCenterUrl = web.AllProperties.FieldValues["SRCH_ENH_FTR_URL_SITE"] as string;
                }
                else if (web.AllProperties.FieldValues.ContainsKey("SRCH_ENH_FTR_URL_WEB"))
                {
                    scanResult.SearchCenterUrl = web.AllProperties.FieldValues["SRCH_ENH_FTR_URL_WEB"] as string;
                }

                // If no search site override check for a search results page override
                if (string.IsNullOrEmpty(scanResult.SearchCenterUrl))
                {
                    CheckForCustomSearchExperience(web, scanResult, "SRCH_SB_SET_SITE");
                    if (string.IsNullOrEmpty(scanResult.SearchCenterUrl))
                    {
                        CheckForCustomSearchExperience(web, scanResult, "SRCH_SB_SET_WEB");
                    }
                }

                // Get security information for this site
                if (!this.ScanJob.SkipUserInformation)
                {
                    scanResult.Admins   = web.GetAdmins();
                    scanResult.Owners   = web.GetOwners();
                    scanResult.Members  = web.GetMembers();
                    scanResult.Visitors = web.GetVisitors();
                    scanResult.EveryoneClaimsGranted = web.ClaimsHaveRoleAssignment(this.ScanJob.EveryoneClaim, this.ScanJob.EveryoneExceptExternalUsersClaim);
                }

                scanResult.ModernListSiteBlockingFeatureEnabled = site.Features.Where(f => f.DefinitionId == FeatureId_Site_ModernList).Count() > 0;
                scanResult.SitePublishingFeatureEnabled         = site.Features.Where(f => f.DefinitionId == FeatureId_Site_Publishing).Count() > 0;

                // Get site user custom actions
                scanResult.SiteUserCustomActions = site.UserCustomActions.Analyze(this.SiteCollectionUrl, this.SiteUrl);

                if (!this.ScanJob.SkipUsageInformation)
                {
                    // Get site usage information
                    List <string> propertiesToRetrieve = new List <string>
                    {
                        "ViewsRecent",
                        "ViewsRecentUniqueUsers",
                        "ViewsLifeTime",
                        "ViewsLifeTimeUniqueUsers"
                    };

                    var results = this.ScanJob.Search(cc.Web, $"path:{this.SiteCollectionUrl} AND contentclass=STS_Site", propertiesToRetrieve);
                    if (results != null && results.Count == 1)
                    {
                        scanResult.ViewsRecent              = results[0]["ViewsRecent"].ToInt32();
                        scanResult.ViewsRecentUniqueUsers   = results[0]["ViewsRecentUniqueUsers"].ToInt32();
                        scanResult.ViewsLifeTime            = results[0]["ViewsLifeTime"].ToInt32();
                        scanResult.ViewsLifeTimeUniqueUsers = results[0]["ViewsLifeTimeUniqueUsers"].ToInt32();
                    }
                }

                if (!this.ScanJob.AppOnlyHasFullControl)
                {
                    var siteInfo = this.ScanJob.AppOnlyManager.SiteInformation.Where(p => p.SiteUrl.Equals(this.SiteCollectionUrl, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                    if (siteInfo != null && siteInfo.ExternalSharing.HasValue)
                    {
                        if (!siteInfo.ExternalSharing.Value)
                        {
                            scanResult.SharingCapabilities = "Disabled";
                        }
                        else
                        {
                            if (siteInfo.AllowGuestUserSignIn.HasValue && !siteInfo.AllowGuestUserSignIn.Value)
                            {
                                scanResult.SharingCapabilities = "ExternalUserAndGuestSharing";
                            }
                            else
                            {
                                scanResult.SharingCapabilities = "ExternalUserSharingOnly";
                            }
                        }
                    }
                    else
                    {
                        scanResult.SharingCapabilities = "Unknown";
                    }
                }
                else
                {
                    try
                    {
                        // Get tenant information
                        var siteInformation = this.ScanJob.SPOTenant.GetSitePropertiesByUrl(this.SiteCollectionUrl, true);
                        this.ScanJob.SPOTenant.Context.Load(siteInformation);
                        this.ScanJob.SPOTenant.Context.ExecuteQueryRetry();

                        if (!siteInformation.ServerObjectIsNull())
                        {
                            scanResult.SharingCapabilities = siteInformation.SharingCapability.ToString();
                        }
                    }
                    // Eat all exceptions for now
                    // TODO move to single loop after scanning has been done - post processing
                    catch { }
                }

                if (Options.IncludePage(this.ScanJob.Mode))
                {
                    // Use search to retrieve all view information for the indexed webpart/wiki/clientside pages in this site collection
                    // Need to use search inside this site collection?
                    List <string> propertiesToRetrieveForPage = new List <string>
                    {
                        "OriginalPath",
                        "ViewsRecent",
                        "ViewsRecentUniqueUsers",
                        "ViewsLifeTime",
                        "ViewsLifeTimeUniqueUsers"
                    };

                    if (new Uri(this.SiteCollectionUrl).PathAndQuery == "/")
                    {
                        this.PageSearchResults = this.ScanJob.Search(cc.Web, $"path={this.SiteCollectionUrl} AND fileextension=aspx AND (contentclass=STS_ListItem_WebPageLibrary OR contentclass=STS_Site OR contentclass=STS_Web)", propertiesToRetrieveForPage);
                    }
                    else
                    {
                        this.PageSearchResults = this.ScanJob.Search(cc.Web, $"path:{this.SiteCollectionUrl} AND fileextension=aspx AND (contentclass=STS_ListItem_WebPageLibrary OR contentclass=STS_Site OR contentclass=STS_Web)", propertiesToRetrieveForPage);
                    }
                }

                if (!this.ScanJob.SiteScanResults.TryAdd(this.SiteCollectionUrl, scanResult))
                {
                    ScanError error = new ScanError()
                    {
                        Error      = $"Could not add site scan result for {this.SiteUrl}",
                        SiteColUrl = this.SiteCollectionUrl,
                        SiteURL    = this.SiteUrl,
                        Field1     = "SiteAnalyzer",
                    };
                    this.ScanJob.ScanErrors.Push(error);
                }
            }
            finally
            {
                this.StopTime = DateTime.Now;
            }

            // return the duration of this scan
            return(new TimeSpan((this.StopTime.Subtract(this.StartTime).Ticks)));
        }
Beispiel #6
0
        /// <summary>
        /// Analyze the site collection
        /// </summary>
        /// <param name="cc">ClientContext of the site to be analyzed</param>
        /// <returns>Duration of the analysis</returns>
        public override TimeSpan Analyze(ClientContext cc)
        {
            try
            {
                base.Analyze(cc);
                Site site = cc.Site;
                site.EnsureProperties(p => p.UserCustomActions, p => p.Features, p => p.Url, p => p.GroupId);
                Web web = cc.Web;
                cc.Web.EnsureProperties(p => p.WebTemplate, p => p.Configuration);

                // Perform specific analysis work
                SiteScanResult scanResult = new SiteScanResult()
                {
                    SiteColUrl = this.SiteCollectionUrl,
                    SiteURL    = this.SiteUrl,
                };

                // Persist web template of the root site
                scanResult.WebTemplate = $"{web.WebTemplate}#{web.Configuration}";

                // Get security information for this site
                scanResult.Admins                = web.GetAdmins();
                scanResult.Owners                = web.GetOwners();
                scanResult.Members               = web.GetMembers();
                scanResult.Visitors              = web.GetVisitors();
                scanResult.Office365GroupId      = site.GroupId;
                scanResult.EveryoneClaimsGranted = web.ClaimsHaveRoleAssignment(this.ScanJob.EveryoneClaim, this.ScanJob.EveryoneExceptExternalUsersClaim);

                scanResult.ModernListSiteBlockingFeatureEnabled = site.Features.Where(f => f.DefinitionId == FeatureId_Site_ModernList).Count() > 0;
                scanResult.SitePublishingFeatureEnabled         = site.Features.Where(f => f.DefinitionId == FeatureId_Site_Publishing).Count() > 0;

                // Get site user custom actions
                scanResult.SiteUserCustomActions = site.UserCustomActions.Analyze(this.SiteCollectionUrl, this.SiteUrl);

                // Get site usage information
                List <string> propertiesToRetrieve = new List <string>
                {
                    "ViewsRecent",
                    "ViewsRecentUniqueUsers",
                    "ViewsLifeTime",
                    "ViewsLifeTimeUniqueUsers"
                };

                var results = this.ScanJob.Search(cc.Web, $"path:{this.SiteCollectionUrl} AND contentclass=STS_Site", propertiesToRetrieve);
                if (results != null && results.Count == 1)
                {
                    scanResult.ViewsRecent              = results[0]["ViewsRecent"].ToInt32();
                    scanResult.ViewsRecentUniqueUsers   = results[0]["ViewsRecentUniqueUsers"].ToInt32();
                    scanResult.ViewsLifeTime            = results[0]["ViewsLifeTime"].ToInt32();
                    scanResult.ViewsLifeTimeUniqueUsers = results[0]["ViewsLifeTimeUniqueUsers"].ToInt32();
                }

                try
                {
                    // Get tenant information
                    var siteInformation = this.ScanJob.SPOTenant.GetSitePropertiesByUrl(this.SiteCollectionUrl, true);
                    this.ScanJob.SPOTenant.Context.Load(siteInformation);
                    this.ScanJob.SPOTenant.Context.ExecuteQueryRetry();

                    if (!siteInformation.ServerObjectIsNull())
                    {
                        scanResult.SharingCapabilities = siteInformation.SharingCapability.ToString();
                    }
                }
                // Eat all exceptions for now
                // TODO move to single loop after scanning has been done - post processing
                catch { }

                if (this.ScanJob.Mode == Mode.Full)
                {
                    // Use search to retrieve all view information for the indexed webpart/wiki/clientside pages in this site collection
                    // Need to use search inside this site collection?
                    List <string> propertiesToRetrieveForPage = new List <string>
                    {
                        "OriginalPath",
                        "ViewsRecent",
                        "ViewsRecentUniqueUsers",
                        "ViewsLifeTime",
                        "ViewsLifeTimeUniqueUsers"
                    };

                    this.PageSearchResults = this.ScanJob.Search(cc.Web, $"path:{this.SiteCollectionUrl} AND fileextension=aspx AND (contentclass=STS_ListItem_WebPageLibrary OR contentclass=STS_Site OR contentclass=STS_Web)", propertiesToRetrieveForPage);
                }

                if (!this.ScanJob.SiteScanResults.TryAdd(this.SiteCollectionUrl, scanResult))
                {
                    ScanError error = new ScanError()
                    {
                        Error      = $"Could not add site scan result for {this.SiteUrl}",
                        SiteColUrl = this.SiteCollectionUrl,
                        SiteURL    = this.SiteUrl,
                        Field1     = "SiteAnalyzer",
                    };
                    this.ScanJob.ScanErrors.Push(error);
                }
            }
            finally
            {
                this.StopTime = DateTime.Now;
            }

            // return the duration of this scan
            return(new TimeSpan((this.StopTime.Subtract(this.StartTime).Ticks)));
        }