evont-software.com
Our goal is a complete setup for a test site collection with managed metadata navigation and existing pages with different levels. The challenge is the correct configuration for the site with powershell and also create the correct terms. With the script you can set the amount of navigation entries.
We use SharePoint PnP Powershell Package to get help with some tasks.
The Invoke-SetupFeatures enables needed features for publishing, what is the requirement.
The Invoke-SetupTermSet creates your termset and Invoke-SetupNavigation enables navigation features. We also use Invoke-EnableTagging to allow tagging, that means we also override the default permission behaviour. (Metadata navigation is not visible to users with read permissions) more information.
Furthermore we collect the page layout item Get-PageLayoutItem and create our terms Invoke-CreateTerms. For each term we create also first a new site page Add-PublishingPageWithContent and connect this page with the new created term.
The Invoke-UpdateTaxonomyCache checks changes for taxonomy and avoids save conflicts.
We also had some issues to crawl a big amount (over 3000) of friendly pages from search. That means you can create the pages, but the search index does not collect it any more - at least the friendly url version.
The official limit for "Number of terms in managed navigation term set" from Microsoft is at 2000.
After some research, on a full crawl for example the complete termset is crawled with all pages. That leads to a timeout. You can override this in search central administration here. We had to set it to a high value, the crawl tooks over 12 minutes - so that is maybe in some cases no optimal solution.
1# -------------------------------------------------------------------------------------2# Configuration3# -------------------------------------------------------------------------------------4$siteurl = "https://contoso.com/sites/sitecollection1"5$termSetName = "GlobalNav"67# -------------------------------------------------------------------------------------8# Functions9# -------------------------------------------------------------------------------------10function Invoke-CreateTerms($context, $PublishingWeb, $PageLayoutItem, $termStore, $termObject, $path, $level, $maxlevel, $maxItemsPerLevel, $overallMax) {1112 $max = $maxItemsPerLevel13 $level = $level + 11415 for ($i = 1; $i -lt $max + 1; $i++) {16 if ($global:countTerms -lt $overallMax) {17 if ($path -eq "") {18 $newPath = "$i"19 }20 else {21 $newPath = "$($path)_$($i)"22 }2324 $termName = "Term$newPath"2526 $newpage = Add-PublishingPageWithContent $context $PublishingWeb $PageLayoutItem "$($termName).aspx" $termName $termName27 $url = $newpage["FileRef"]28 $global:countTerms++29 Write-Host "Create term $($termName) - $($global:countTerms)/$overallMax..." -f Yellow -NoNewline30 $newTerm = $termObject.CreateTerm($termName, 1033, [System.Guid]::NewGuid().toString())31 $newTerm.SetLocalCustomProperty('_Sys_Nav_TargetUrl', $url)32 Write-Host "Done" -f Green3334 if ($level -lt $maxlevel ) {35 Invoke-CreateTerms $context $PublishingWeb $PageLayoutItem $termStore $newTerm $newPath $level $maxlevel $maxItemsPerLevel $overallMax36 }37 }38 }39 $termStore.CommitAll()40 Invoke-PnPQuery4142}43function Get-PageLayoutItem($PageLayoutName) {44 $Ctx = Get-PnPContext45 Write-host -f Yellow "Getting Page Layout..." -NoNewline46 #Get the Page Layout47 $RootWeb = $Ctx.Site.RootWeb48 $MasterPageList = $RootWeb.Lists.GetByTitle('Master Page Gallery')49 $CAMLQuery = New-Object Microsoft.SharePoint.Client.CamlQuery50 $CAMLQuery.ViewXml = "<View><Query><Where><Eq><FieldRef Name='FileLeafRef' /><Value Type='Text'>$PageLayoutName</Value></Eq></Where></Query></View>"51 $PageLayouts = $MasterPageList.GetItems($CAMLQuery)52 $Ctx.Load($PageLayouts)53 $Ctx.ExecuteQuery()5455 $PageLayoutItem = $PageLayouts[0]56 $Ctx.Load($PageLayoutItem)57 $Ctx.ExecuteQuery()58 Write-host -f Green "Done"59 return $PageLayoutItem60}61function Add-PublishingPageWithContent($Ctx, $PublishingWeb , $PageLayoutItem , $PageName, $PageTitle, $PageContent) {626364 #Create Publishing page65 Write-host -f Yellow "Creating New Page $PageName ..." -NoNewline66 $PageInfo = New-Object Microsoft.SharePoint.Client.Publishing.PublishingPageInformation67 $PageInfo.Name = $PageName68 $PageInfo.PageLayoutListItem = $PageLayoutItem69 $Page = $PublishingWeb.AddPublishingPage($PageInfo)70 $Ctx.ExecuteQuery()7172 $ListItem = $Page.ListItem73 $Ctx.Load($ListItem)74 $Ctx.ExecuteQuery()7576 #Update Page Contents77 $ListItem["Title"] = $PageTitle78 $ListItem["PublishingPageContent"] = $PageContent79 $ListItem.Update()80 $Ctx.ExecuteQuery()818283 #Publish the page8485 $ListItem.File.CheckIn([string]::Empty, [Microsoft.SharePoint.Client.CheckinType]::MajorCheckIn)86 $ListItem.File.Publish([string]::Empty)87 $Ctx.ExecuteQuery()88 Write-host -f Green "Done"899091 return $ListItem92}93function Invoke-SetupFeatures() {9495 #publihsing Infrastructure site feature check96 $FeaturePublishingInfraSiteId = "f6924d36-2fa8-4f0b-b16d-06b7250180fa" #Site Scoped Publishing Feature97 $Feature = Get-PnPFeature -Scope Site -Identity $FeaturePublishingInfraSiteId98 If ($null -eq $Feature.DefinitionId) {99 Write-host -f Yellow "Activating Publishing Infrastructure Site Feature..." -NoNewline100 Enable-PnPFeature -Scope Site -Identity $FeaturePublishingInfraSiteId -Force101 Write-host -f Green "Done"102 }103 Else {104 Write-host -f Yellow "Publishing Infrastructure Site Feature already activated..." -NoNewline105 Write-host -f Green "Done"106 }107108 #publishing Infrastructure web feature check109 $FeaturePublishingInfraWebId = "94c94ca6-b32f-4da9-a9e3-1f3d343d7ecb"110 $Feature = Get-PnPFeature -Scope Web -Identity $FeaturePublishingInfraWebId111 If ($null -eq $Feature.DefinitionId) {112 Write-host -f Yellow "Activating Publishing Infrastructure Web Feature..."113 Enable-PnPFeature -Scope Web -Identity $FeaturePublishingInfraWebId -Force114 Write-host -f Green "Done"115 }116 Else {117 Write-host -f Yellow "Publishing Infrastructure Web Feature already activated..." -NoNewline118 Write-host -f Green "Done"119 }120121 #Wait complete all122 Start-Sleep -Seconds 10123}124function Invoke-SetupTermSet($termSetName) {125126 $context = Get-PnPContext127 $CurrentSite = Get-PnPSite128 $taxonomySession = [Microsoft.SharePoint.Client.Taxonomy.TaxonomySession]::GetTaxonomySession($context)129 $TermStore = $taxonomySession.GetDefaultSiteCollectionTermStore();130 $SiteCollectionTermGroup = $TermStore.GetSiteCollectionGroup($CurrentSite, $false)131 $context.Load($taxonomySession)132 $context.Load($SiteCollectionTermGroup)133 $context.Load($TermStore)134 Invoke-PnPQuery135 $termgroupname = $SiteCollectionTermGroup.Name136137 $termSets = Get-PnPTermSet -TermGroup $termgroupname138 $exists = ($termSets | Where-Object { $_.Name -eq $termSetName } | Measure-Object).Count -gt 0139 if ($exists -eq $false ) {140 Write-Host "Created termset $termSetName ..." -f Yellow -NoNewline141 $termSet = New-PnPTermSet -Name $termSetName -TermGroup $SiteCollectionTermGroup -Lcid 1033 -IsOpenForTermCreation142 $TermStore.CommitAll()143 Write-Host "Done" -f Green144 }145 else {146147 Start-Sleep -Seconds 5148 Write-Host "Termset already exists $($termSet.Name)" -f Yellow -NoNewline149 $termSet = Get-PnPTermSet -Identity $termSetName -TermGroup $termgroupname150 Write-Host "Done" -f Green151 }152153}154function Invoke-SetupNavigation($termSetName) {155156 Write-Host "Reset Navigation..." -f Yellow -NoNewline157 $context = Get-PnPContext158 $CurrentSite = Get-PnPSite159 $taxonomySession = [Microsoft.SharePoint.Client.Taxonomy.TaxonomySession]::GetTaxonomySession($context)160161 $TermStore = $taxonomySession.GetDefaultSiteCollectionTermStore();162 $SiteCollectionTermGroup = $TermStore.GetSiteCollectionGroup($CurrentSite, $false)163 $termsets = $SiteCollectionTermGroup.TermSets164 $context.Load($taxonomySession)165 $context.Load($SiteCollectionTermGroup)166 $context.Load($termsets)167 $context.Load($TermStore)168 Invoke-PnPQuery169170 $navigationTermSet = $termsets | Where-Object { $_.Name -eq $termSetName }171172 $context.Load($navigationTermSet)173 Invoke-PnPQuery174 Write-Host "Done" -f Green175176 Write-Host "Set taxonomy navigation..." -f Yellow -NoNewline177 $context = Get-PnPContext178 $Web = Get-PnPWeb179 $navigationSettings = New-Object Microsoft.SharePoint.Client.Publishing.Navigation.WebNavigationSettings $context, $Web180 $navigationSettings.ResetToDefaults()181 $navigationSettings.GlobalNavigation.Source = 1182 $navigationSettings.CurrentNavigation.Source = 1183 $navigationSettings.Update($taxonomySession)184 Invoke-PnPQuery185 Start-Sleep -Seconds 2186187188 $context = Get-PnPContext189 $Web = Get-PnPWeb190 $navigationSettings = New-Object Microsoft.SharePoint.Client.Publishing.Navigation.WebNavigationSettings $context, $Web191 $navigationSettings.CurrentNavigation.Source = "taxonomyProvider"192 $navigationSettings.CurrentNavigation.TermStoreId = $TermStore.Id193 $navigationSettings.CurrentNavigation.TermSetId = $navigationTermSet.Id194 $navigationSettings.GlobalNavigation.Source = "taxonomyProvider"195 $navigationSettings.GlobalNavigation.TermStoreId = $TermStore.Id196 $navigationSettings.GlobalNavigation.TermSetId = $navigationTermSet.Id197 $navigationSettings.Update($taxonomySession)198199 $Web.AllProperties["__IncludeSubSitesInNavigation"] = $True200 #Show pages in global navigation201 $Web.AllProperties["__IncludePagesInNavigation"] = $False202203 #Update Settings204 $Web.Update()205 $TermStore.CommitAll()206 Invoke-PnPQuery207208 Write-Host "Done" -f Green209210}211function Invoke-UpdateTaxonomyCache() {212 $context = Get-PnPContext213 Write-Host "Update taxonomy cache..." -f Yellow -NoNewline214 $TaxonomySession = Get-PnPTaxonomySession215 $TaxonomySession.UpdateCache()216 $context.Load($TaxonomySession)217 Invoke-PnPQuery218 Write-Host "Done" -f Green219}220function Invoke-EnableTagging($termSetName) {221222 Write-Host "Enable tagging for termset..." -f Yellow -NoNewline223 Start-Sleep -Seconds 5224 $context = Get-PnPContext225 $CurrentSite = Get-PnPSite226 $taxonomySession = [Microsoft.SharePoint.Client.Taxonomy.TaxonomySession]::GetTaxonomySession($context)227 $TermStore = $taxonomySession.GetDefaultSiteCollectionTermStore();228 $SiteCollectionTermGroup = $TermStore.GetSiteCollectionGroup($CurrentSite, $false)229 $termsets = $SiteCollectionTermGroup.TermSets230 $context.Load($taxonomySession)231 $context.Load($SiteCollectionTermGroup)232 $context.Load($termsets)233 $context.Load($TermStore)234 Invoke-PnPQuery235236 $navigationTermSet = $termsets | Where-Object { $_.Name -eq $termSetName }237238 $context.Load($navigationTermSet)239 Invoke-PnPQuery240241 $navigationTermSet.IsOpenForTermCreation = $true242 $navigationTermSet.IsAvailableForTagging = $true243 $TermStore.CommitAll()244245 Start-Sleep -Seconds 2246 Write-Host "Done" -f Green247}248249function Invoke-LoadPnp() {250 Write-Host "Load Libraries..." -f Yellow -NoNewline251252 $rootpath = $PSScriptRoot253 $path = Join-Path -Path $rootpath -ChildPath "SharePointPnPPowerShell2019\3.29.2101.0\"254 $sharepointPowershellModulePath = Join-Path -Path $path -ChildPath "SharePointPnPPowerShell2019.psd1"255 if ($null -eq (Get-Module -Name "SharePointPnPPowerShell2019")) {256 Import-Module $sharepointPowershellModulePath -DisableNameChecking257 Disable-PnPPowerShellTelemetry -Force | Out-Null258 }259 #Load SharePoint CSOM Assemblies260 Add-Type -Path "$path\Microsoft.SharePoint.Client.dll"261 Add-Type -Path "$path\Microsoft.SharePoint.Client.Runtime.dll"262 Add-Type -Path "$path\Microsoft.SharePoint.Client.Taxonomy.dll"263 Add-Type -Path "$path\Microsoft.SharePoint.Client.Publishing.dll"264 Write-Host "Done" -f Green265}266267# -------------------------------------------------------------------------------------268# Load PnP and Client Libraries269# -------------------------------------------------------------------------------------270Invoke-LoadPnp271# -------------------------------------------------------------------------------------272# Connect273# -------------------------------------------------------------------------------------274$global:countTerms = 0275276Connect-PnPOnline -Url $siteurl -CurrentCredentials277$Web = Get-PnPWeb -Includes Title, WebTemplate, Configuration278279# -------------------------------------------------------------------------------------280# Test Template281# -------------------------------------------------------------------------------------282Write-Host "Site $($Web.Title): $($Web.WebTemplate)#$($Web.Configuration) it should be STS#0"283if ($Web.WebTemplate -ne "STS" -and $Web.Configuration -ne 0) {284 Write-Host "Wrong template" -ForegroundColor Red285}286287# -------------------------------------------------------------------------------------288# Setup Features289# -------------------------------------------------------------------------------------290Invoke-SetupFeatures291292# -------------------------------------------------------------------------------------293# Setup Termset294# -------------------------------------------------------------------------------------295Invoke-SetupTermSet $termSetName296Invoke-UpdateTaxonomyCache297# -------------------------------------------------------------------------------------298# Setup Navigation299# -------------------------------------------------------------------------------------300Invoke-SetupNavigation $termSetName301Invoke-UpdateTaxonomyCache302303# -------------------------------------------------------------------------------------304# Setup Tagging305# -------------------------------------------------------------------------------------306Invoke-EnableTagging $termSetName307308# -------------------------------------------------------------------------------------309# Create Content310# -------------------------------------------------------------------------------------311$Ctx = Get-PnPContext312$PublishingWeb = [Microsoft.SharePoint.Client.Publishing.PublishingWeb]::GetPublishingWeb($Ctx, $Ctx.Web)313$Ctx.Load($PublishingWeb)314$Ctx.ExecuteQuery()315$PageLayoutItem = Get-PageLayoutItem 'ArticleLeft.aspx'316$context = Get-PnPContext317$CurrentSite = Get-PnPSite318$taxonomySession = [Microsoft.SharePoint.Client.Taxonomy.TaxonomySession]::GetTaxonomySession($context)319320$termStore = $taxonomySession.GetDefaultSiteCollectionTermStore();321$SiteCollectionTermGroup = $TermStore.GetSiteCollectionGroup($CurrentSite, $false)322$termsets = $SiteCollectionTermGroup.TermSets323$context.Load($taxonomySession)324$context.Load($SiteCollectionTermGroup)325$context.Load($termsets)326$context.Load($TermStore)327Invoke-PnPQuery328329$termSet = $termsets | Where-Object { $_.Name -eq $termSetName }330331$context.Load($termSet)332Invoke-PnPQuery333Invoke-CreateTerms -context $context -PublishingWeb $PublishingWeb -PageLayoutItem $PageLayoutItem -termStore $termStore -termObject $termSet -path "" -level 0 -maxlevel 3 -maxItemsPerLevel 30 -overallMax 3300334335Invoke-UpdateTaxonomyCache