SharePoint 2016 Case Study: Resolving Post-Upgrade and Migration Missing Webpart Dependencies

Introduction

This posting presents a case study on resolving missing web part dependencies associated with a subsite that appeared in the farm health report after upgrading and migrating the site collection hosting the subsite from SharePoint 2010 to SharePoint 2016. The missing web part dependencies did not appear in the previous test upgrade reports.

This posting begins at the point where a copy of the full backup has been restored and mounted to the development SharePoint 2016 farm.

Procedure

01) List and review the missing webpart dependency messages in the farm health report

Missing Webpart Dependencies
[MissingWebPart] WebPart class [7b2d7450-5d92-767e-a544-4196ca5bd141] is referenced [3] times in the database [WSS_Content], but is not installed on the current farm. Please install any feature/solution which contains this web part. One or more web parts are referenced in the database [WSS_Content], but are not installed on the current farm. Please install any feature or solution which contains these web parts.
[MissingWebPart] WebPart class [dc8d37bf-5afb-657e-e673-6c9328f9c912] (class [Microsoft.SharePoint.WebPartPages.BlogYearArchive] from assembly [Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c]) is referenced [1] times in the database [WSS_Content], but is not installed on the current farm. Please install any feature/solution which contains this web part. One or more web parts are referenced in the database [WSS_Content], but are not installed on the current farm. Please install any feature or solution which contains these web parts.
[MissingWebPart] WebPart class [7919f194-1a06-0aff-3d2a-f44a5bc2e217] is referenced [3] times in the database [WSS_Content], but is not installed on the current farm. Please install any feature/solution which contains this web part. One or more web parts are referenced in the database [WSS_Content], but are not installed on the current farm. Please install any feature or solution which contains these web parts.

02) Build the SQL script

This SQL script will be used to query a copy of the content database, WSS_Content, mounted to a 2016 development farm, to obtain key information needed to in turn build the PowerShell scripts that will actually remove the missing webpart dependencies. This SQL script is only executed against a copy of the content database mounted to a development web application on the 2016 development farm.

USE WSS_Content
SELECT SiteID, WebID, DirName, LeafName, tp_WebPartTypeId, tp_WebPartIDProperty
FROM AllDocs WITH (NOLOCK) inner join AllWebParts on AllDocs.Id = AllWebParts.tp_PageUrlID
WHERE AllWebParts.tp_WebPartTypeID IN 
     ('7b2d7450-5d92-767e-a544-4196ca5bd141',
    'dc8d37bf-5afb-657e-e673-6c9328f9c912',
    '7919f194-1a06-0aff-3d2a-f44a5bc2e217')

03) Review the results

All results had the same SiteID and WebID. These results show that missing web parts occurred on three different pages all associated with the same subsite, a blog subsite. The fact that the tp_WebPartIDProperty property is not NULL indicates that these missing web parts are associated with the current versions of these pages and not earlier versions.

DirName LeafName tp_WebPartTypeID tp_WebPartIDProperty
.../Lists/Posts Date.aspx 7B2D7450-5D92-767E-A544-4196CA5BD141 g_c4555eab_87ed_42f7_9aea_73f0a232dfa5
.../Lists/Posts Date.aspx 7919F194-1A06-0AFF-3D2A-F44A5BC2E217 g_954ddee1_99ca_44a0_a586_8bc58208d7b3
.../Lists/Posts MonthlyArchive.aspx DC8D37BF-5AFB-657E-E673-6C9328F9C912 g_7fb6cc72_c96a_4b09_853a_e857ab7a83dd
.../Lists/Posts MonthlyArchive.aspx 7B2D7450-5D92-767E-A544-4196CA5BD141 g_72e0c2fd_cc42_4cb8_b0f0_eaf1219014d2
.../Lists/Posts MonthlyArchive.aspx 7919F194-1A06-0AFF-3D2A-F44A5BC2E217 g_e12c566c_30a0_4087_86a7_1e5c78be37c1
.../Lists/Categories Category.aspx 7B2D7450-5D92-767E-A544-4196CA5BD141 g_4824990b_d079_43ed_b720_2bcc5a5ff460
.../Lists/Categories Category.aspx 7919F194-1A06-0AFF-3D2A-F44A5BC2E217 g_516e0c65_40dc_44ac_a608_5099d0e471c4

04) Review the web pages

Navigate to each of the pages identified in the list to confirm the missing web part presents as an error.

05) Build the PowerShell scripts

These PowerShell scripts will be used to actually remove the missing dependencies and will be executed on the production farm. There are three groupings of these statements, each group associated with the missing web parts for a particular page. The SiteID and WebID do not change for any groupings and so these are defined first:

$siteID = "[siteid]"
$webID = "[webid]"

This first grouping is to remove the missing web part dependencies from the Date.aspx page:

$dirName = ".../blogsite/Lists/Posts"
$leafName = "Date.aspx"
$site = Get-SPSite -Identity $siteID
$web = Get-SPweb -Identity $webID -Site $siteID
$pageURL = "{0}{1}/{2}" -f ($site.WebApplication).url, $dirName, $leafName
$page = $web.GetFile($pageURL)
$webPartManager = $page.GetLimitedWebPartManager([System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)

$webPartID1 = "g_c4555eab_87ed_42f7_9aea_73f0a232dfa5"
$webPart = $webPartManager.WebParts[$webPartID1]
$webPartManager.DeleteWebPart($webPart)
$web.Dispose()

$webPartID2 = "g_954ddee1_99ca_44a0_a586_8bc58208d7b3"
$webPart = $webPartManager.WebParts[$webPartID2]
$webPartManager.DeleteWebPart($webPart)
$web.Dispose()

The second grouping is for removing them from the MonthlyArchive.aspx page:

$dirName = ".../blogsite/Lists/Posts"
$leafName = "MonthlyArchive.aspx"
$site = Get-SPSite -Identity $siteID
$web = Get-SPweb -Identity $webID -Site $siteID
$pageURL = "{0}{1}/{2}" -f ($site.WebApplication).url, $dirName, $leafName
$page = $web.GetFile($pageURL)
$webPartManager = $page.GetLimitedWebPartManager([System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)

$webPartID1 = "g_7fb6cc72_c96a_4b09_853a_e857ab7a83dd"
$webPart = $webPartManager.WebParts[$webPartID1]
$webPartManager.DeleteWebPart($webPart)
$web.Dispose()

$webPartID2 = "g_72e0c2fd_cc42_4cb8_b0f0_eaf1219014d2"
$webPart = $webPartManager.WebParts[$webPartID2]
$webPartManager.DeleteWebPart($webPart)
$web.Dispose()

$webPartID3 = "g_e12c566c_30a0_4087_86a7_1e5c78be37c1"
$webPart = $webPartManager.WebParts[$webPartID3]
$webPartManager.DeleteWebPart($webPart)
$web.Dispose()

The third and last grouping is for removing them from the Category.aspx page:

$dirName = ".../blogsite/Lists/Categories"
$leafName = "Category.aspx"
$site = Get-SPSite -Identity $siteID
$web = Get-SPweb -Identity $webID -Site $siteID
$pageURL = "{0}{1}/{2}" -f ($site.WebApplication).url, $dirName, $leafName
$page = $web.GetFile($pageURL)
$webPartManager = $page.GetLimitedWebPartManager([System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)

$webPartID1 = "g_4824990b_d079_43ed_b720_2bcc5a5ff460"
$webPart = $webPartManager.WebParts[$webPartID1]
$webPartManager.DeleteWebPart($webPart)
$web.Dispose()

$webPartID2 = "g_516e0c65_40dc_44ac_a608_5099d0e471c4"
$webPart = $webPartManager.WebParts[$webPartID2]
$webPartManager.DeleteWebPart($webPart)
$web.Dispose()

06) Re-analyze the Missing server side dependencies health rule

Re-analyze the rule to verify that the missing web part dependencies were removed.

Summary

This posting presented one method for resolving post-upgrade and migration missing webpart dependencies that subsequently appear in the farm's health report. A copy of the contenting database hosting the subsite was mounted to a web application on a development farm so that it could be queried without impacting Microsoft Support requirements associated with SharePoint databases. Once key information was extracted from the content database, this information was used to build the PowerShell scripts that were then executed on the production farm to actually remove the missing webpart dependencies. The entire process, not including copying the content database to the development farm SQL Server and attaching it and then mounting it to a SharePoint web application, took about three hours.

References

Notes

  • The missing web parts were associated with a subsite of a site collection that was originally migrated from 2007 to 2010 using ShareGate Desktop. The subsite was then exported to another, temporary site collection hosted in a dedicated content database, and then this content database was upgraded through 2016. A second export was then performed to move the subsite from the temporary site collection to its final destination site collection.
  • In this particular instance, the subsite had not been modified in several years. Since these pages only presented content and did not contain original content, they could just as easily been deleted without adversely impacting content. Therefore, this problem could have been resolved by deleting three pages rather than removing seven missing web part dependencies.  I've taken this approach with some site collections and webs in the past, with approval from the site collection or web owner.  Note that if taking this approach, the deleted page must also be flushed from the first and second stage recycle bins or it will still appear as a missing webpart dependency.
  • HELP: I deleted the item but the missing dependency still appears in the Test-SPContentDatabase Report! Check the site collection's first and second stage recycle bins and ensure that the item is completely deleted from these too.