Thursday, November 21, 2013

#SharePoint | Site timeout and navigation issues

Problem:
SharePoint site is taking about one minute to load and most times ends up timing out.
If we try to open the navigation settings, we will be given this specific output:
"An unexpected error occurred while manipulating the navigational structure of this Web."

Solution:
The problem is that the navigation for the root site or one of its subsites is problematic.
According to MSDN, there is a cumulative update that can solve this.
It is possible that after a new page has been published, this can happen, for unknown reasons.

Some people stated that subsites or published pages may have caused this so deleting them (can be recovered later in the Recycle Bin) will fix it.

In my case I make a listing of all my topnavigation links and found out that I had 800+ repeated nodes.

So I just removed all of them with PowerShell.

The below script will allow you to - just by setting up a web application url - reset the top navigation items on all site collections.
There are functions to enable list, delete and add of navigational items to SharePoint sites.


#navigation reset by tiago duarte
#11:46 21/11/2013

#summary
#this script takes a web application url, iterates through all existing site collections
#and optionally REMOVEs, ADDs, or LISTs existing Top Navigation nodes

# TODO: set value of $webAppUrl
# TODO: set navigation items (for ADD operation)
# TODO: uncomment any of the three function calls


#go to me
$currentFolder = Get-Location -PSProvider FileSystem
$invokedFolder = [regex]::Replace($MyInvocation.MyCommand.Definition, "\\resetNavigation.ps1", "")
if($invokedFolder -ne $currentFolder){ cd $invokedFolder }

#enable sp snappin
If ((Get-PsSnapin |?{$_.Name -eq "Microsoft.SharePoint.PowerShell"})-eq $null)
{
 Write-Host
 Write-Host -ForegroundColor White " - Loading SharePoint Powershell Snapin"
 $PSSnapin = Add-PsSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue | Out-Null
 Write-Host
}

#variables
$webAppUrl = "http://localhost"

#my navigation items
#using array of arrays instead of hash table due to hash order control issues
$links = @()
$links += ,@("Home", "/")
$links += ,@("Contact", "/Pages/Contact.aspx")

#see all existing links
function seeLinks($navigationNodes)
{
 Write-Host "Found"$navigationNodes.Count"items" in $site.Url
  
 if ($navigationNodes -ne $null)
    {
  #we need to reverse lookup or trying to remove parent with children will cause an exception
  for ($i=$navigationNodes.Count-1; $i -ge 0; $i-=1)
        {
   Write-Host $navigationNodes[$i].Url
        }
    }
 else
 {
  Write-Host "no navigation items!"
 }
}

#add defined links
function addLinks($navigationNodes)
{
 Write-Host "Found"$navigationNodes.Count"items" in $site.Url
 
 #$topLinks.GetEnumerator() | Sort-Object { $_.Index.SortOrder } | % {
 foreach($link in $links)
 {
  #$newLink = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode -ArgumentList  @($_.Key, $_.Value, $true);
  #$navigationNodes.AddAsLast($newLink)
  
  $destinationUrl = $link[1]
  if($destinationUrl -notmatch "http")
  {
   $destinationUrl = $webAppUrl + $destinationUrl
  }
  
  Write-Host "Adding new Navigation Item:"
  Write-Host $link[0]
  Write-Host $destinationUrl
  
  $newLink = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode -ArgumentList  @($link[0], $destinationUrl, $true);
  $navigationNodes.AddAsLast($newLink)
 }
 Write-Warning "All navigation nodes created sucessfully!"
}

#remove existing links
function removeLinks($navigationNodes)
{
  Write-Host "Found"$navigationNodes.Count"items" in $site.Url
  
  if ($navigationNodes -ne $null)
     {
   #we need to reverse lookup or trying to remove parent with children will cause an exception
   for ($i=$navigationNodes.Count-1; $i -ge 0; $i-=1)
         {
    if($navigationNodes[$i].Url -eq "/Pages/myPage.aspx")
    {
     $navigationNodes[$i].Delete()
    }
         }
     }
  else
  {
   Write-Host "no navigation items!"
  }
}

#set web application
$webApp = get-spwebapplication $webAppUrl

##for each existing site collection, delete all navigation items first
#foreach($site in $webApp.Sites)
#{
# #remove url condition in order to customize all!
# if(($site.Url.ToLower() -eq "http://localhost") -and ($site.Url.ToLower() -notmatch "\/sites\/"))
# {
#  removeLinks($site.RootWeb.Navigation.TopNavigationBar)
# }
#    $site.Dispose()
#}

#then add the new navigation items
#foreach($site in $webApp.Sites)
#{ 
# if(($site.Url.ToLower() -eq "http://localhost") -and ($site.Url.ToLower() -match "\/sites\/"))
# {
#  addLinks($site.RootWeb.Navigation.TopNavigationBar)
# }
#    $site.Dispose()
#}

#foreach($site in $webApp.Sites)
#{ 
# if(($site.Url.ToLower() -eq "http://localhost") -and ($site.Url.ToLower() -notmatch "\/sites\/"))
# {
#  seeLinks($site.RootWeb.Navigation.TopNavigationBar)
# }
#    $site.Dispose()
#}

Write-Host "SCRIPT COMPLETE!"

No comments:

Post a Comment