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
- Post Upgrade Cleanup – Missing Server Side Dependencies
- SharePoint 2010: a spreadsheet method for quickly resolving missing non-upgrade-blocking dependencies
- Inconvenient SPWeb.GetFile(string)
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.