SharePoint Migration: Basic tips and tricks in migration project

No comments

Sometimes while we do the SharePoint content database migration thru the detach and attach method – we may encounter with errors. However, if we open the migrated site still it does open and work. Here, I will explain how we can reduce the possibility of getting the error and some basic tips and tricks in migration project.

End of this article we will learn the below:

  • SharePoint migration project plan
  • Best Practices for a Successful SharePoint Migration or Upgrade
  • Quick Tips for a Successful SharePoint Migration Plan
  • SharePoint server migration steps
  • Step by Step guide to Migrate from SharePoint 2013 to SharePoint 2016
  • SharePoint migration steps
  • SharePoint migration tool troubleshooting
  • SharePoint content database migration checklist
  • How to see all running workflow instances in SharePoint 2013.
  • Find All InfoPath Form Libraries and lists in SharePoint
  • PowerShell script for running Test-SPContentDatabase
  • PowerShell script to remove features by ID
  • SQL query for listing setup file information
  • PowerShell script to remove the webpart by ID
  • SQL query to  list down web part information
  • SQL query to get event receiver information
  • PowerShell script to remove event receiver

 

Descriptions:

Even though we get some error during the database upgrade we may ignore them, as this is generally common behavior in migration project.

Even I had also faced the similar kind of issue and figured this out by doing the proper analysis in the source system. One of the key parameter for succeeding the migration project is proper planning and analyzing the source environment. Try to get an inventory from your source system about all custom solution and where (in which sites) these custom features are activated, I am sure from the inventory report you will find there are many features those are not really being used in the source system. So you can clean those unwanted feature from target environment – after running the Test-SPContentDatabase command.

For cleaning up the the features you may use the below PowerShell script(available in the below link):

https://blogs.technet.microsoft.com/dawiese/2017/05/09/post-upgrade-cleanup-missing-server-side-dependencies/

Sample PowerShell script for running Test-SPContentDatabase:

$wa=Get-SPWebApplication "https://sharepoint.contoso.com"
$outputPath= "\\tools\files\Output\Test_Wss_Content_MissingAssembly_{0}.txt"
-f (Get-Date -Format hhmmss)
$dbName="WSS_Content_MissingAssembly"
$slqServer= "SPSQL"
Test-SPContentDatabase -Name $dbName -WebApplication $wa -ServerInstance $slqServer -ShowLocation:$true -ExtendedCheck:$false | Out-File $outputPath Write-Host "Testresults written to $outputPath"

PowerShell script to remove features by ID:

$featureID = "ed37484a-c496-455b-b083-3fc157b1603c"
$siteID = "108d28e9-dac1-4eea-9566-6591394e6d40"   
 
#Display site information
$site = Get-SPSite $siteID  
Write-Host "Checking Site:" $site.Url
 
#Remove the feature from all subsites
ForEach ($web in $Site.AllWebs)
    {
        If($web.Features[$featureID])
            {
                Write-Host "`nFound Feature $featureID in web:"$Web.Url"`nRemoving feature"
                $web.Features.Remove($featureID, $true)
            }
            else
            {
                Write-Host "`nDid not find feature $featureID in web:" $Web.Url
            }   
    }
 
#Remove the feature from the site collection
If ($Site.Features[$featureID])
    {
        Write-Host "`nFound feature $featureID in site:"$site.Url"`nRemoving Feature"
        $site.Features.Remove($featureID, $true)
    }
    else
    {
        Write-Host "Did not find feature $featureID in site:" $site.Url
    }

SQL sample for listing setup file information:

USE WSS_Content_MissingAssembly_Snapshot
  
SELECT id, SiteID, DirName, LeafName, WebId, ListId
FROM AllDocs (NOLOCK) where SetupPath = 'Features\ContosoLIb_Feature1\DocLib_WP\DocLib_WP.webpart'

PowerShell script to remove setup files by ID:

#File Information
$setupFileID = "07462F03-A4C6-455C-B383-947DDE85DF36"
$siteID = "108D28E9-DAC1-4EEA-9566-6591394E6D40"
$WebID = "4E068646-2C87-4868-924E-850C31F607DF"
 
#Get file
$site = Get-SPSite -Identity $siteID
$web = Get-SPWeb -Identity $WebID -Site $siteID
$file = $web.GetFile([GUID]$setupFileID)
 
#Report on location
$filelocation = "{0}{1}" -f ($site.WebApplication.Url).TrimEnd("/"), $file.ServerRelativeUrl
Write-Host "Found file location:" $filelocation
 
#Delete the file, the Delete() method bypasses the recycle bin
$file.Delete()
 
$web.dispose()
$site.dispose()

SQL query to list down web part information:

USE WSS_Content_MissingAssembly_Snapshot
  
SELECT WebID, SiteID, DirName, LeafName, tp_WebPartTypeId, tp_WebPartIDProperty
FROM AllDocs WITH (NOLOCK) inner join AllWebParts on AllDocs.Id = AllWebParts.tp_PageUrlID
WHERE AllWebParts.tp_WebPartTypeID = '817a5bd9-0698-4c62-7c51-5c9966468f0d'

PowerShell script to remove the webpart by ID:

$siteID = "108D28E9-DAC1-4EEA-9566-6591394E6D40"
$webID = "4E068646-2C87-4868-924E-850C31F607DF"
$dirName = "sites/lab5-4/SitePages"
$leafName = "Home.aspx"
$webPartID = "g_bb56b03e_b830_4e37_ba16_62250601ac26"
 
#Get Web
$web = Get-SPweb -Identity $webID -Site $siteID
 
#Build page url
$pageURL = "{0}{1}/{2}" -f ($site.WebApplication).url, $dirName, $leafName
 
#Get SPFile
$page = $web.GetFile($pageURL)
 
#Delete the web part on the current published page
$webPartManager = $page.GetLimitedWebPartManager([System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
 
#Delete web part by ID
$webPart = $webPartManager.WebParts[$webPartID]
$webPartManager.DeleteWebPart($webPart)
$web.Dispose()

SQL query to get event receiver information:

USE WSS_Content_MissingAssembly_Snapshot
  
Select Id, SiteID, WebID, HostType, hostId 
FROM EventReceivers (NOLOCK) where Assembly = 'ContosoLIb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1b7baa1677de7aa0'

PowerShell script to remove event receiver:

#Variables
$hostType = "0"
$siteID = "108D28E9-DAC1-4EEA-9566-6591394E6D40"
$webID = "00000000-0000-0000-0000-000000000000"
$hostID = "108D28E9-DAC1-4EEA-9566-6591394E6D40"
$assemblyID = "80A9D912-768A-4289-91AB-9BF368922F8F"
 
 
#Perform cleanup
 
if ($hostType -eq "0")
    {
        $site = GEt-SPSite -limit all -Identity $siteID
        ($site.EventReceivers | ?{$_.id -eq $assemblyID}).delete()
        $site.dispose()
    }
    elseif ($hostype -eq "1")
    {
        $web = Get-SPWeb -Identity $webID -Site $siteID
        ($web.EventReceivers | ?{$_.id -eq $assemblyID}).delete()
        $web.dispose()
    }
    elseif ($hostype -eq "2")
    {
        $web = Get-SPWeb -Identity $webID -Site $siteID
        $list = $web.lists | ?{$_.id -eq $hostID}
        ($list.EventReceivers | ?{$_.id -eq $assemblyID}).delete()
        $web.dispose()
    }

Above code reference URL:

https://blogs.technet.microsoft.com/dawiese/2017/05/09/post-upgrade-cleanup-missing-server-side-dependencies/

For planing and preparing the check list for content DB migration – you may refer the below content:

The basic steps are as below: 

  • Prepare detailed inventory of environment
    Clean up old environment
  • Test content
  • Prepare destination environment and analyze new environment configurations
    Communicate with users
  • Start migration
  • Read only mode until migration completes
  • Post migration, third party tools and resources

Reference URL:

  • https://www.advaiya.com/blog/sharepoint-2016-migration-checklist/
  • https://docs.microsoft.com/en-us/sharepoint/upgrade-and-update/checklist-for-database-attach-upgrade-sharepoint-2013

SharePoint content database migration – SharePoint migration steps:

Here based on my personal experience I have listed out the SharePoint content database migration steps in high level:

  1. Create a new SQL server with SQL high availability group and configure SQL listener.
  2. Create a new SharePoint farm.
  3. Configure the service application whatever you had in the previous farm.
  4. Try to migrate the service application data like Manage metadata service, search service etc..otherwise create these services get those service application data thru database migration.
  5. Create all new web application in the target farm as many you had in the previous farm.
  6. Deploy all custom solutions if you have, from previous environment to new environment.
  7. Configure the alternate access mapping for the all the web applications in the new farm.
  8. Verify the central administration settings for all pages from CA – by comparing old CA and new CA.
  9. Verify each web application settings from new CA – by comparing old CA and new CA.
  10. Verify web config files for each web application from new environment – by comparing old web.config file and new web.config file.
  11. Verify the IIS settings of each web application by comparing old IIS settings.
  12. Prepare an inventory for all running all workflows.
  13. Good to complete all running workflows.
  14. Prepare an inventory for all infopath forms in source SharePoint.
  15. Prepare an inventory for all data connection used in the infopath forms.
  16. Plan the migration over the weekend.
  17. Announce the users about the down time of the SharePoint.
  18. While declaring downtime estimate at least 20 percent buffer time for any uncertainty.
  19.  Plan for any other dependent teams like – SQL, networking for their availability.
  20. Make old farm read only ( all web applications).
  21. Take all content database backup from old database server and restore in new SQL server thru backup restore or detach and attach process.
  22. Once confidence with all these verification – start the mounting of content database in the new application.
  23. During mounting the database we might get some errors some we might ignore, but some errors we might to fix.
  24. After migrating to new SharePoint environment immediately change the infopoath data connection URL to new URL(target SharePoint data connection URL).
  25. Then open all the infopath forms which we have generated from source SharePoint.
  26. Access the sites – and perform all basic testing – do not forget to test permissions.
  27. If all well – finally change the DNS for all the URLS from new environment – so that it will continue to work with the old same URLS only – in the backend just we need to map the DNS to the new server what we have created.
  28. Declare go live – I have followed the same steps and it was successful.

Notes:

  • Sometimes, even though we change the data connection correctly from the new SharePoint environment, still we will get the data connection error. Then we need to disable the loopback in the registry. And also we need to verify the layout path in the target SharePoint data connection because layout path in source and target are  different. Example: SharePoint 2013 and SharePoint 2016.
  • Need to be calm and cool : If we face some uncertain issue which is show-stopper for the migration, we should not be tensed. Generally, when we do the migration within the given down time, people get tensed to deal with troubleshooting. So need to relax and work. 🙂

How to get all infopath forms and workflows from SharePoint web application?

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null 
 
function global:Get-SPSite($url)
{ 
 
    return new-Object Microsoft.SharePoint.SPSite($url) 
 
} 
 
#Get the web application 
 
$WebAppURL= "<Web Application URL>" 
 
$SiteColletion = Get-SPSite($WebAppURL) 
 
$WebApp = $SiteColletion.WebApplication 
 
  
 
#Write the CSV header 
 
"Site Collection `t Site `t List Name `t List Url `t Docs Count `t Last Modified `t WF Count `t Live WF `t Live WF Names `t Form Template" > c:\temp\InfoPathLibs.csv 
 
  
 
#Loop through all site collections of the web app 
 
    foreach ($site in $WebApp.Sites)  
    { 
 
       # get the collection of webs 
 
       foreach($web in $site.AllWebs)  
        { 
 
            write-host "Scaning Site" $web.title "@" $web.URL 
 
               foreach($list in $web.lists)  
               { 
 
                if( $list.BaseType -eq "DocumentLibrary" -and $list.BaseTemplate -eq "XMLForm") 
		{ 
 
			$listModDate = $list.LastItemModifiedDate.ToShortDateString() 
			$listTemplate = $list.ServerRelativeDocumentTemplateUrl 
			$listWorkflowCount = $list.WorkflowAssociations.Count  
			$listLiveWorkflowCount = 0  
			$listLiveWorkflows = "" 
         
 
			foreach ($wf in $list.WorkflowAssociations)  
			{ 
 
			 if ($wf.Enabled) 
			 { 
 
			 $listLiveWorkflowCount++ 	 
			 if ($listLiveWorkflows.Length -gt 0)  
			 {  
			 $listLiveWorkflows = "$listLiveWorkflows, $($wf.Name)" 
 			}  
			else  
			{  
			$listLiveWorkflows = $wf.Name 
 			} 
 
                     }  
                 } 
 
					#Write data to CSV File  
                   $site.RootWeb.Title +"`t" + $web.Title +"`t" + $list.title +"`t" + $Web.Url + "/" + $List.RootFolder.Url  +"`t" + $list.ItemCount +"`t" + $listModDate +"`t"  
 
+ $listWorkflowCount +"`t" + $listLiveWorkflowCount +"`t" + $listLiveWorkflows +"`t" + $listTemplate >> c:\temp\InfoPathLibs.csv 
 
             } 
 
           } 
 
        } 
 
    }  
  
 
#Dispose of the site object 
 
$siteColletion.Dispose()  
Write-host  "Report Generated at c:\temp\InfoPathLibs.csv" -foregroundcolor green 

 

Reference URL:

https://gallery.technet.microsoft.com/office/Find-all-lists-that-have-dc9a0420

Various types of issues and their descriptions with fixes during running the Test-SPContentDatabase :

SharePoint Content Database Migration

Notes:

  1. You may ignore the error or exception from Test-SPContentDatabase command, still your Mount-SPContentDatabase will work.
  2. While running the Mount-SPContentDatabase for certain content database – if you get an exception or up to some extend some errors, you can ignore those and continue in further migration, still your migrated site will work fine and in these scenario if you see database upgrade status from central admin, we can see upgrade completed with errors status but we can live with this.
  3. After content db migration thru database detach and attach approach – we may see some issues in the migrated master page, css and java script code as a result we may expect some differences in the migrated site look and feel and other css and scripting related issue – this is a general behavior which we need to fix manually even though it is time consuming.

 

Key takeaways from this article:

  • SharePoint migration project plan.
  • Best Practices for a Successful SharePoint Migration or Upgrade.
  • Quick Tips for a Successful SharePoint Migration Plan.
  • SharePoint server migration steps.
  • Step by Step guide to Migrate from SharePoint 2013 to SharePoint 2016.
  • SharePoint migration steps.
  • SharePoint migration tool troubleshooting.
  • SharePoint content database migration checklist.
  • How to see all running workflow instances in SharePoint 2013.
  • Find All InfoPath Form Libraries and lists in SharePoint.
  • PowerShell script for running Test-SPContentDatabase.
  • PowerShell script to remove features by ID.
  • SQL query for listing setup file information.
  • PowerShell script to remove the webpart by ID.
  • SQL query to  list down web part information.
  • SQL query to get event receiver information.
  • PowerShell script to remove event receiver.

 

References:

  • https://blogs.technet.microsoft.com/dawiese/2017/05/09/post-upgrade-cleanup-missing-server-side-dependencies/
  • https://www.advaiya.com/blog/sharepoint-2016-migration-checklist/
  • https://docs.microsoft.com/en-us/sharepoint/upgrade-and-update/checklist-for-database-attach-upgrade-sharepoint-2013
  • https://sharegate.com/blog/sharepoint-content-database-migration-monitoring