Programmatically update embded hyperlink on a document on SP document library , with PowerShell
August 30, 2013 Leave a comment
I worked on a migration project where content for MS word document also needed to be changed after migration.
In a nutshell in my old SharePoint I had a Library which all word documents had embedded hyperlinks which linked to the Version History of items on SharePoint and labelled as Version History.
So after the migration I have to find a way to replace http://OLDSERVENAME/Site/MyLibaray/MyItem/VersionHistory to http://SERVERNAME/site/MyLibrary/Myitem/VersionHistory for these hyperlinks embedded on the word documents.
So the world of Word Automation with PowerShell came to rescue me. Note that you need to have word dll install on your server before running this scripts. See the link below for more information:
The basic principle of my scripts was: first check the approval status. If published only change the hyper link and save the document without changing the version number. If it was draft the scripts still change the hyperlink but I was not interested the version number to be changes or not.
Here is my scripts:
# add SharePoint snap in
If ((Get-PSSnapIn -Name Microsoft.SharePoint.PowerShell ) -eq $null )
{ Add-PSSnapIn -Name Microsoft.SharePoint.PowerShell } Write-Output “”
add-type -AssemblyName “Microsoft.Office.Interop.Word”
$wdunits = “Microsoft.Office.Interop.Word.wdunits” -as [type]
$donotsave = “Microsoft.Office.Interop.Word.wdDoNotSaveChanges” -as [type]
$save = “Microsoft.Office.Interop.Word.wdSaveChanges” -as [type]
$application = New-Object -ComObject word.application
$application.Visible = $false
$OldServerName = “OLDSERVERNAME”
# go to the destination site
$SPWeb = Get-SPWeb “http://SERVERNAME/site/subsite”
$SPwebURL = $SPWeb.URL
# get number of items on my library
$Output = “There are ” + $SPWeb.Lists.Count + ” lists”
#write-Output $Output
$Mylist = $SPWeb.Lists[“MyLibraryName”]
$Output = “I am ” + $Mylist.Title
write-Output $Output
# get list GUID
$ListGUID = $MYlist.ID
$Output = “I have ” + $Mlist.ItemCount + ” items.”
write-Output $Output
$MyItems = $Mylist.Items
foreach ($Item in $MyItems| where {$_.Name -match “.doc”}) # to filter based on a column name category you can use {$_.Properties.Category -match “Document”}
{
$Output = $Item.name + ” is ” + $Item.level
Write-Output $Output
# get document’s approval status; we are only interested on a published documents.
$modeinfo = $Item.ModerationInformation
$status = $Item.ModerationInformation.Status
$Output = $Item.name + ” is ” + $status
Write-Output $Output
$DocumentLocation = $SPwebURL + “/”+ $Item.URL
$Output = $DocumentLocation + ” about to be opened”
Write-Output $Output
$document = $application.Documents.Open($DocumentLocation)
$DocURLs = $Document.Hyperlinks
$needToSave = $False
$URLsToChange = $False
$NeedToPublish = $False
$NeedToUnPublish = $False
# First we see if there is anything to do
foreach ($URL in $DocURLs | where {$_.Address -match $OldServerName})
{
$URLsToChange = $True
$NeedToSave = $True
if ($Item.level -eq “Published”)
{
$NeedToUnPublish = $True
$NeedToPublish = $true
}
}
if ($NeedToUnPublish -eq $True)
{
$Item.File.UnPublish(” “)
$Item.File.Update();
$Output = $Item.name + ” has been unpublished and updated”
Write-Output $Output
}
if ($URLsToChange -eq $True)
{
foreach ($URL in $DocURLs | where {$_.Address -match $OldServerName})
{
# We only want to do this if the title text we are looking exist (eg. version history )
if ($URl.TextToDisplay -match “Version”)
{
$NewAddress = $SPwebURL + “/_layouts/Versions.aspx?list={” + $ListGUID + “}&ID=” + $Item.ID
$URl.Address = $NewAddress
$NeedToSave = $true
Write-Output “Version history link has been updated”
}
# If not version history but has a reference to oldserver
if ($URl.Address -match $OldServerName)
{
# Replace server name and replace the GUID of the list
$URl.Address = ” “
$NeedToSave = $true
$Output = “The URL ” + $url.TextToDisplay + ” has been updated”
Write-Output $Output
}
} #end foreach
}
if ($needToSave -eq $true)
{
$document.save()
$document.close([Ref]$donotsave)
$output = $item.name + ” — successfully saved —“
Write-Output $output
#get the status again
$modeinfo = $Item.ModerationInformation
$status = $Item.ModerationInformation.Status
$output = $item.name + ” has been saved”
Write-Output $output
if ($NeedToPublish -eq $true)
{
$output = $item.name + ” is being Published”
Write-Output $output
$Item.File.Publish(“Published by System”)
$Item.File.Approve(“Approved by System”)
$Item.File.Update();
$output = $item.name + ” processing completed”
Write-Output $output
}
}
else
{
$document.close([Ref]$donotsave)
$output = $item.name + ” — No changes required —“
Write-Output $output
}
}
$application.quit()
$SPWeb.Dispose()
Hope you find this useful.
Recent Comments