Friday, February 13, 2015

Fix SharePoint Quick Launch Links using PowerShell

A lot of times when I’m working on an environment for a client, I come across a situation where I’m in need of a way to quickly update links – usually because people have entered them as an absolute URL (e.g. http://intranet/pages/somepage.aspx) instead of a relative URL (e.g. /pages/somepage.aspx).

Usually when I run across a problem like this, I actually get excited – because these are great opportunities to use our buddy PowerShell! Unfortunately, there aren’t many examples out there of how to use PowerShell to manipulate SharePoint Navigation objects. Hopefully this blog post will be helpful for someone looking to do the same thing I needed to do…
Here’s how it all comes together – and if you don’t want to understand how it works just skip to the end and copy/paste the code :).

Getting the Web Object

The first thing we have to do in order to even begin to work on SharePoint Navigation is to retrieve an SPWeb object. To do this, it’s pretty simple – just run the following code, which will store the Microsoft.SharePoint.SPWeb into the $SPWeb variable:
1
$SPWeb = Get-SPWeb $Web

Getting the Web.Navigation.QuickLaunch Object

After we’ve retrieved that object, if you use Get-Member to view the Methods and Properties, you’ll quickly notice that the Navigation Property has a QuickLaunch property within it. This is exactly what we want. We can now start to use the ForEach-Object cmdlet to actually show us everything beneath the SPWeb.Navigation.QuickLaunch. Or more specifically, we can use an IF statement to make sure we only grab the appropriate URLs – that is, only ones matching the string we want to replace. Here’s the code snippet:
1
2
3
4
5
6
7
$SPWeb.Navigation.QuickLaunch | ForEach-Object {
    if($_.Url -match $FindString){
        $linkUrl = $_.Url
        Write-Host "Updating $linkUrl with new URL"
        $_.Url = $_.Url.Replace($FindString,$ReplaceString)
        $_.Update()
    }
Pretty cool, so essentially we just say if the URL matches the string we’re looking for, then go ahead and tell us it’s working on it – then update it, replacing the value of the FindString variable with the value of the ReplaceString variable. Both of these variables are actually mandatory parameters, you’ll see that part at the end… Finally, run the Update() method on each one to actually commit the changes to the server.
All done right? No, we can’t forget about the children!

Fixing the Child links

So far the code we’ve seen will only touch the parent links, but each link also has a Children node. We can simply use the same code as before, except this time we’ll run it against the $_.Children property of each link node.
Here’s how that looks:

1
2
3
4
5
6
7
8
$_.Children | ForEach-Object {
        if($_.Url -match $FindString){
            $linkUrl = $_.Url
            Write-Host "Updating $linkUrl with new URL"
            $_.Url = $_.Url.Replace($FindString,$ReplaceString)
            $_.Update()
        }
    }

And now, if we put it all together, you’ll see that we have a nice, clean function to do a quick find and replace of navigation links on the quick launch of a single SharePoint Web. I’ve called the function Repair-SPLeftNavigation, and it has 3 required parameters – Web, FindString and ReplaceString:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function Repair-SPLeftNavigation {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)][System.String]$Web,
[Parameter(Mandatory=$true)][System.String]$FindString,
[Parameter(Mandatory=$true)][System.String]$ReplaceString
)
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$SPWeb = Get-SPWeb $Web
$SPWeb.Navigation.QuickLaunch | ForEach-Object {
    if($_.Url -match $FindString){
        $linkUrl = $_.Url
        Write-Host "Updating $linkUrl with new URL"
        $_.Url = $_.Url.Replace($FindString,$ReplaceString)
        $_.Update()
    }
    $_.Children | ForEach-Object {
        if($_.Url -match $FindString){
            $linkUrl = $_.Url
            Write-Host "Updating $linkUrl with new URL"
            $_.Url = $_.Url.Replace($FindString,$ReplaceString)
            $_.Update()
        }
    }
}
$SPWeb.Dispose()
}#endFunction

To run this bad boy, simply dot-source the function and then call it like a cmdlet – for example:
1

2
. .\Repair-SPLeftNavigation.ps1
Repair-SPLeftNavigation -Web http://sp2013 -FindString 'http://sp2010' -ReplaceString 'http://sp2013'

If you needed to run this on multiple site collections or even web applications, you could simply use the native ForEach-Object cmdlet in conjunction with this function to accomplish that goal.
Cheers!

Source: http://sharepointryan.com/2013/04/15/fix-sharepoint-quick-launch-links-using-powershell/

No comments:

Post a Comment