Question

We need to change the root of our SharePoint 2013 Document Management site collection due to a company ownership change from Sharepoint.acb.net to Sharepoint.xyz.net. I configured everything using the "alternate access mappings" and SharePoint now work perfectly with both address.

Before decommissioning the Sharepoint.acb.net DNS, we need to update literally thousands of documents that have links to others SharePoint documents. Those documents are mostly Word document (.docx), but we also have some Excel (.xlsx).

I'm hoping I could batch update the URLs inside of those Office Documents without manually opening them to change all the links, maybe something with powershell?

Bonus point for batch updating the corporate logo's URL in the 300 content type document templates.

Was it helpful?

Solution

I found a way of doing this by accessing the library files in file explorer.

The idea is to connect to the SharePoint server via the \\MYSERVERNAME\DavWWWRoot\

Documents were easy to update via the .Hyperlinks collection, but the corporate logo was in a linkedImage buried in the header. The path to reach it is Document.Sections(i).headers(j).Range.InlineShapes(k).SourceFullName

All our document come from document types, so template are in Template are in the \MYSERVERNAME\DavWWWRoot\Library\Forms\DocumentTypes

We will do this Site by site because we have to re-approve all documents manually via the official workflow, but must of the job is done.

The script must be run by a site admin on a computer where Word and Excel is installed.

Here my power-shell script, if it could help someone :

[String]$SharePointPath = "\\MYSERVERNAME\DavWWWRoot\Library"
[String[]]$OldsDomains = "Sharepoint.acb.net","Sharepoint.acb.com"
[String]$NewDomain = "Sharepoint.xyz.net"
[String[]]$NotALibrary = "Documents","Documents partages","images","Lists","m","Pages","PublishingImages","SiteAssets","SitePages","Workflows","WorkflowTasks"


function UpdateExcelFileLinks($File, [String[]]$OldsDomains, [String]$NewDomain){
    $Excel = New-Object -ComObject excel.application
    $Excel.Visible = $false

    #"Opening Excel file: {0}" -f $File.FullName
    $ExcelWorkbook = $Excel.Workbooks.open($File.FullName)
    #"Processing file: {0}" -f $ExcelWorkbook.FullName
    $somethingChanged = $FALSE;

    #"Processing Hyperlinks of : {0}" -f $ExcelWorkbook.FullName
    foreach ($Worksheet in $ExcelWorkbook.Worksheets){
        foreach ($Link in $Worksheet.Hyperlinks){
            #"link {0}" -f $Link.Address
            foreach ($OldDomain in $OldsDomains){
                if ($Link.Address -like "http://$OldDomain/*") {
                    $NewAddress = $Link.Address -Replace $OldDomain,$NewDomain
                    "Updating {0}" -f $Link.Address
                    "      to {0}" -f $NewAddress
                    $Link.Address = $NewAddress
                    $somethingChanged = $TRUE
                }
            }
        }
    }


    if ($somethingChanged -eq $TRUE) {
        "Saving changes to {0}" -f $ExcelWorkbook.Fullname
        $ExcelWorkbook.Save() 
    }
    #"Completed processing of {0} `r`n" -f $ExcelWorkbook.Fullname
    $ExcelWorkbook.Close($FALSE)
    $Excel.Quit()
}


function UpdateWordFileLinks($File, [String[]]$OldsDomains, [String]$NewDomain){
    $Word = New-Object -ComObject word.application
    $Word.Visible = $false

    #"Opening WORD file: {0}" -f $File.FullName
    $WordDocument = $Word.documents.open($File.FullName)
    #"Processing file: {0}" -f $WordDocument.FullName
    $somethingChanged = $FALSE;


    #"Processing headers of : {0}" -f $WordDocument.FullName
    foreach ($section in $WordDocument.Sections) {
        #"section.headers.count: {0}" -f $section.headers.count
        foreach ($header in $section.headers) {
            #"header.Range.InlineShapes: {0}" -f $header.Range.InlineShapes.count
            foreach ($inlineShape in $header.Range.InlineShapes) {
                # 4 = wdInlineShapeLinkedPicture    4   Linked picture.
                #"image.Type: {0}" -f $image.Type
                if ($inlineShape.Type -eq 4){
                    foreach ($OldDomain in $OldsDomains){
                        if ($inlineShape.LinkFormat.SourceFullName  -like "http://$OldDomain/*") {
                            $NewAddress = $inlineShape.LinkFormat.SourceFullName -Replace $OldDomain,$NewDomain
                            "Updating {0}" -f $inlineShape.LinkFormat.SourceFullName
                            "      to {0}" -f $NewAddress
                            $inlineShape.LinkFormat.SourceFullName = $NewAddress
                            $inlineShape.AlternativeText = $NewAddress
                            $somethingChanged = $TRUE
                        }
                    }
                }

            }
        }
    }
    #"Processing Hyperlinks of : {0}" -f $WordDocument.FullName
    foreach ($Link in $WordDocument.Hyperlinks){
        foreach ($OldDomain in $OldsDomains){
            if ($Link.Address -like "http://$OldDomain/*") {
                $NewAddress = $Link.Address -Replace $OldDomain,$NewDomain
                "Updating {0}" -f $Link.Address
                "      to {0}" -f $NewAddress
                $Link.Address = $NewAddress
                $somethingChanged = $TRUE
            }
        }
    }

    if ($somethingChanged -eq $TRUE) {
        "Saving changes to {0}" -f $WordDocument.Fullname
        $WordDocument.Save() 
    }
    #"Completed processing of {0} `r`n" -f $WordDocument.Fullname
    $WordDocument.Close($FALSE)
    $Word.Quit()
}

function UpdateFileLinks($File, [String[]]$OldsDomains, [String]$NewDomain){
    $FileExt = $File.Name.Split(".")[-1]
    switch ($FileExt)
    {
        docx {
                UpdateWordFileLinks -File $File -OldsDomains $OldsDomains -NewDomain $NewDomain
                }
        dotx {
                UpdateWordFileLinks -File $File -OldsDomains $OldsDomains -NewDomain $NewDomain
                }
        xlsx {
                UpdateExcelFileLinks -File $File -OldsDomains $OldsDomains -NewDomain $NewDomain
                }
        xltx {
                UpdateExcelFileLinks -File $File -OldsDomains $OldsDomains -NewDomain $NewDomain
                }
        default {
            #"unsuported file extention {0} `r`n" -f $FileExt
            }
    }
}

function UpdateLibraryLinks([String]$LibraryPath, [String[]]$OldsDomains, [String]$NewDomain){
    "Processing Library '{0}' `r`n" -f $LibraryPath
    $Files = Get-ChildItem -Path $LibraryPath -File 
    foreach ($File in $Files){
        UpdateFileLinks -File $File -OldsDomains $OldsDomains -NewDomain $NewDomain
    }
    $DocumentTypesPath = $LibraryPath + "/Forms"
    $DocumentTypes = Get-ChildItem -Path $DocumentTypesPath -Directory
    foreach ($DocumentType in $DocumentTypes){
        $Templates = Get-ChildItem -Path $DocumentType.Fullname -File 
        foreach ($Template in $Templates){
            #"Template '{0}' `r`n" -f $Template.Fullname 
            UpdateFileLinks -File $Template -OldsDomains $OldsDomains -NewDomain $NewDomain
        }
    }
}


function UpdateLibrariesLinks([String]$SitePath, [String[]]$OldsDomains, [String]$NewDomain){
    [String[]] $LibrariesPath 
    "Processing Site '{0}'" -f $SitePath
    $Libraries = Get-ChildItem -Path $SitePath -Directory
    foreach ($Library in $Libraries){
        if ($NotALibrary -notcontains $Library.name) {
            UpdateLibraryLinks -LibraryPath  $Library.Fullname -OldsDomains $OldsDomains -NewDomain $NewDomain
        } 
    }
}

#Sites = Get-ChildItem -Path $SharePointPath -Directory
UpdateLibrariesLinks -SitePath $SharePointPath -OldsDomains $OldsDomains -NewDomain $NewDomain
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top