2

I am stuck on a PowerShell V3.0 problem for programmatically adding Child Links to the Global Navigation bar in our Online SharePoint 2013 (Office 365-Azure) site.

I have found code that works for me to add Headers, to my top link global navigation bar, but I cannot find anywhere, how to add children links (such as Child1 in my attached photo) under a given header (such as Hello1 in image) on the global navigation bar. I am using CSOM libraries to do this.

I have been Googling for days on this, and cannot find anything that shows me what to do with the code to make the child links. Everything I have found either uses PS snapins from Sharepoint 2010 (which I cannot download and use in Sharepoint 2013 Online – unless someone knows of a way to do that), or is written in C# or VB and I am unable translate the code into PowerShell.

Is there any chance that someone would know how or be able to point me to a resource that would help me solve this issue? The following code snippets work well to add the top level links/headers to the global navigation bar for me but how to add sub links under these headers, programmatically using PowerShell v3.0?

I put the following in a foreach-object loop reading the information from an XML file…this all works well, for adding top level headers/links. I believe I just need to make slight alterations to this code to add sub-links under my global nav headings, but cannot figure out how:

$siteUrl = $_.Url
$siteTitle = $_.Title
$context = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl) 
$context.Credentials = $credentials 
$context.RequestTimeOut = 5000 * 60 * 10; 
$web = $context.Web 
$site = $context.Site 
$context.Load($web) 
$context.Load($site) 
$context.ExecuteQuery()  

$NavBar = $context.Web.Navigation.TopNavigationBar 
$NavigationNode = New-Object Microsoft.SharePoint.Client.NavigationNodeCreationInformation
$NavigationNode.Title = $ItemName
$NavigationNode.Url = $ItemUrlPath
$NavigationNode.AsLastNode = $true           
$context.Load($NavBar.Add($NavigationNode)) 
$context.ExecuteQuery()   

enter image description here

1 Answer 1

3

You were very close, since navigation has a hierarchical structure in order to create a child node the parent node should be determined first.

The following example demonstrates how to create a child (Link) node under Heading node in Global navigation:

Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"


Function Get-SPOContext([string]$Url,[string]$UserName,[string]$Password)
{
   $context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
   $SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force
   $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)
   $context.Credentials = $credentials
   return $context
}


Function FindNavigationNodeByTitle([Microsoft.SharePoint.Client.NavigationNodeCollection]$Nodes,[string]$Title)
{
      $context = $Nodes.Context
      $context.Load($Nodes)
      $context.ExecuteQuery()
      $node = $Nodes | Where-Object { $_.Title -eq $Title }
      return $node
} 


Function AddNavigationNode([Microsoft.SharePoint.Client.NavigationNode]$ParentNode,[string]$Title,[string]$Url){
   $context = $ParentNode.Context
   $Node = New-Object Microsoft.SharePoint.Client.NavigationNodeCreationInformation 
   $Node.Title = $Title
   $Node.Url = $Url 
   $Node.AsLastNode = $true
   $context.Load($ParentNode.Children.Add($Node))
   $context.ExecuteQuery()
}


$tenantUrl = "https://tenant.sharepoint.com/"
$userName = "[email protected]" 
$password = "password"

$Context = Get-SPOContext -Url $tenantUrl -UserName $userName -Password $password

$NavBar = $Context.Web.Navigation.TopNavigationBar 
$Context.Load($NavBar)
$Context.ExecuteQuery()


$parentNode = FindNavigationNodeByTitle -Nodes $NavBar -Title "Hello"
if($parentNode) {
   AddNavigationNode -ParentNode $parentNode -Title "Tasks" -Url "/sites/news/Lists/Tasks/AllItems.aspx"
}


$Context.Dispose()

Result

enter image description here

2
  • 1
    Thank you very much for the coding solution! I cannot get it to work in my environment, however. Using your code nearly explicitly, I get the error message "The collection has not been initialized. etc." on the $Context.Load($parentNode.Children) line. Any suggestions for what is missing? Commented Jan 25, 2016 at 16:47
  • Originally I've tested the script against PS V4 but since PS support for generic methods varies between versions the specified error occurs. Just updated example to make it compatible with V3 Commented Jan 26, 2016 at 8:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.