SharePoint 2013: Resolving Missing server side dependencies in farm admin content database
Introduction
This posting presents the method used to resolve a Missing server side dependencies rule violation that was presented in the farm's health analyzer report.
I had previously removed the PDF Share Forms Enterprise solution from a SharePoint 2013 development farm. Several days later, I found the Missing server side dependencies rule violation appearing in the farm health report, and it listed a MissingFeature and several MissingSetupFile missing dependencies associated with the PDF Share Forms Enterprise solution that were referenced in the farm's administration content database but no longer installed to the farm.
Method
I employed several common tools to resolve this problem, including:
- SQL Server Management Studio
- SharePoint Management Shell
- Microsoft Excel
- T SQL
- PowerShell
Since this was a development farm, I executed SQL queries directly against the admin content database. Had this problem occurred for a production farm admin content database, I would have executed the SQL queries against a copy of the database mounted separately. Only READ queries are executed directly against the content database. Any modifications to the database are performed through the SharePoint API via appropriate PowerShell commands.
Analyzing the problem report found the following critical details necessary for identifying which content database needed to be queried and which missing dependencies we needed information for:
- Content Database Name:
- WSS_Admin_f12a613c-a43b-45a3-b797-7c79f5f010f9
- Missing Feature IDs:
- 8149e9b3-9c71-4397-880e-136c577f22df
- Missing Setup Files:
- Features\PDFForms.Services_PDFFormsCAFeature\PDFShareFormsInternal\ErrorTemplate.html
- Features\PDFForms.Services_PDFFormsCAFeature\PDFShareFormsInternal\SuccessTemplate.html
- Features\PDFForms.Services_PDFFormsCAFeature\PDFShareFormsInternal\SuccessTemplate.pdf
The MissingFeature ID was needed for querying the Features table to discover in what webs and site collections the MissingFeature were referenced and obtain the GUIDs associated with those site collections and webs. The GUIDs in turn would enable appropriate spsite or spweb (or both) objects to be instantiated and the MissingFeature removed from the spsite or spweb object's Features collection using its Remove method. Here's the SQL script that was used:
USE [MyContentDatabaseName] SELECT SiteID,WebID,FeatureID FROM Features WITH (NoLOCK) WHERE FeatureID IN ('MyFeatureID')
And here's the PowerShell script that was used once the site and web GUIDs were obtained
$web = Get-SPWeb -Identity "MyWebID" -Site "MySiteID" $web.Features.Remove("MyFeatureID", $True)
The MissingSetupFile names were needed for querying the AllDocs table to discover the GUIDs of these missing setup files and the GUIDs of the site collections and webs that they are referenced in. These GUIDs in turn would enable instances of these file objects to be obtained using the web object's GetFile method and then to remove the file reference using the GetFile's Delete method. Here's the SQL script that was used for this:
USE [MyContentDatabaseName] SELECT id, SiteID, DirName, LeafName, WebId, ListId FROM AllDocs WITH (NOLOCK) WHERE SetupPath IN ('MissingSetupFileName1', 'MissingSetupFileName2', 'MissingSetupFileName3')
In this case, since there were several missing setup file references, it was convenient to use spreadsheet techniques to quickly and accurately create all of the necessary PowerShell delete statements. The basic statement that would be executed was the following
(Get-SPWeb -Identity "MyWebID" -Site "MySiteID").GetFile([GUID]"MyMissingSetupFileID").Delete()
The spreadsheet technique was accomplished by first copying and pasting the SQL query results into a spreadsheet; then entering the following function into the first vacant column cell to the right of the second row (the first row contains column headers):
=CONCAT("(Get-SPWeb -Identity """,E2,""" -Site """,B2,""").GetFile([GUID]""",A2,""").Delete()")
And then finally dragging the cell downward to create all of the delete statements necessary quickly and accurately.
Once the PowerShell statements were developed, they were executed in an elevated SharePoint Management Shell and the Missing server-side dependencies health analyzer rule was re-analyzed.
Results
The SQL queries were executed without issue against the farm admin content database. With respect to the MissingFeature, the SQL query results were corroborated by data in the EnumAllWebs report. SetupFile IDs are not provided in the EnumAllWebs report, and so the query results were corroborated by examining the results and comparing them against the missing server side dependencies report (e.g., comparing SQL result LeafNames with MissingSetupFile names); and they were found to be consistent. All PowerShell statements completed successfully without errors. Re-analyzing the Missing server side dependencies health rule found the issue resolved after executing the PowerShell statements.
References
- Post Upgrade Cleanup – Missing Server Side Dependencies
- SharePoint Health Analyzer rules reference for SharePoint Server
- SharePoint 2010: Case Study on How to Remove Project-related Missing Dependencies when Upgrading to 2013
- SharePoint 2010: a spreadsheet method for quickly resolving missing non-upgrade-blocking dependencies
- SharePoint Upgrade: Simple OOTB Inventory Methods Useful for Resolving Missing Dependencies
- SharePoint 2010: Case Study on How to Resolve Missing PDF Forms Dependencies when Upgrading to SharePoint 2013
- PDF Share Forms
- Support for changes to the databases that are used by Office server products and by Windows SharePoint Services
Notes
Brackets "[]" are needed around the SQL content database name, when executing the SQL script, if the name contains hyphens "-". The farm admin content database will contain a GUID if it is created using default methods.
The SiteIDs and WebIDs can also be obtained from the STSADM's EnumAllWebs operation. After generating the report, just search through the report for the MyFeatureID that is presented in the health rule violation report, and then walk back the tree to find the WebID and then the SiteID. Run this script in an elevated DOS Shell to get the EnumAllWebs report on a SharePoint 2013 farm:
CD C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\BIN\
echo ^<?xml version="1.0" encoding="ISO-8859-1"?^> > "D:\EnumAllWebs.xml"
stsadm -o enumallwebs -databasename "MyContentDBName" -includefeatures -includeeventreceivers -includesetupfiles >> "D:\EnumAllWebs.xml"
tbd