Hi I am trying to use the CSOM to remove a quick link from the left hand navigation as I am using SP Online, I was able to add one with no issues by using the script in this stackexchange question, Now I would like to try and remove it.

I have found this site which shows you how to remove a quick link via powershell but it is for SharePoint on prem.

This is the script I have so far but I keep getting the error -

An error occurred while enumerating through a collection: The collection has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.. At line:4 char:13 + $ql.Delete($dn) + ~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (Microsoft.Share...NavigationNode]:d__0) [], RuntimeException + FullyQualifiedErrorId : BadEnumeration

    $url= "SITEURL"
    $person = "ADMINUSERNAME"
    $Password = Read-Host -Prompt "Please enter your PASSWORD" -AsSecureString
    $clientCtx = New-Object Microsoft.SharePoint.Client.ClientContext($url)
    $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($person,$Password)
    $clientCtx.Credentials = $credentials

    $web = $clientCtx.Web
    $ql = $web.Navigation.QuickLaunch 
    $node = $web.Navigation.QuickLaunch | where { $_.Title -eq "Documents" }

3 Answers 3


The error is related to the fact that you need to tell the context which objects you actually want to load before calling execute.

$web = $clientContext.Web
$ql = $web.Navigation.QuickLaunch 
$node = $web.Navigation.QuickLaunch | where { $_.Title -eq "someheading" }

The above works, though the item i'm deleting hints at the complexity here. The quicklaunch has both headings and links within the headings in the "children" property of the heading. The above deletes the heading. If you need to delete a link, you may need to first connect to the right heading, and then delete the link within it.

edit: I don't think I explained that well. You're calling delete on the ql object, but the ql object hasn't been loaded yet. So load it and execute the query to get access to the $ql object, which then allows you to pipe it to the where command as well as call deleteobject on it. Then run the execute again to carry out the delete.

  • Thank you for the detailed response, it helped me understand a lot better!
    – Jamie_lee
    Commented May 4, 2017 at 12:28

why you don't use PnP-PowerShell it've a magnificent Commands among other you found this one

Remove-PnPNavigationNode -Title Recent -Location QuickLaunch
  • As much as I would love to I am not allowed to use PnP within the organisation I am working in. But thanks for the tip
    – Jamie_lee
    Commented May 3, 2017 at 10:35

Here is working snippet tested with our test environment

Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll" 
$siteUrl = "SITE URL" 
$username = "user name"
$password = Read-Host -Prompt "Enter password" -AsSecureString
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl)
$credentials = New-Object
Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $password)
$ctx.Credentials = $credentials
$rootWeb = $ctx.Web 
$ql = $rootWeb.Navigation.QuickLaunch
$node = $ql | where { $_.Title -eq "LiveTiles" }
Write-Host $node.Title

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.