The SharePoint Health Analyzer checks for and reports on various SharePoint issues. One of these issues is categorized as a configuration problem and named "Missing server side dependencies". When reviewing the problem, [MissingFeature] and [MissingSetupFile] are noted in the explanation. This article will discuss how to find missing setup files with PowerShell.
The missing setup file problems are generally created by third party solutions that don't clean themselves up gracefully during an upgrade or removal. In the case of web parts, there may be web pages with references to the web parts that have since been removed.
The following script can be used to locate the missing setup files in the SQL content database and then present the applicable web site items that are referencing them.
# Title: FindMissingSetupFile.ps1 # Version: 1.0, 11 NOV 2021 # Author: James Sanders # Purpose: Find missing setup files to resolve Health Analyzer issues Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue Function Run-SQLScript($SQLServer, $SQLDatabase, $SQLQuery) { $ConnectionString = "Server =" + $SQLServer + "; Database =" + $SQLDatabase + "; Integrated Security = True" $Connection = new-object system.data.SqlClient.SQLConnection($ConnectionString) $Command = new-object system.data.sqlclient.sqlcommand($SQLQuery,$Connection) $Connection.Open() $Adapter = New-Object System.Data.sqlclient.sqlDataAdapter $Command $Dataset = New-Object System.Data.DataSet $Adapter.Fill($Dataset) $Connection.Close() $Dataset.Tables[0] } # Define configuration parameters $Server="YOUR_SQL_SERVER\INSTANCE" $Database="YOUR_CONTENT_DB" $SetupFile="Features\ShareKnowledge.Lms.Certificate\DocumentLibrary\Default\Template.docx" # Query SQL Server content database to get information about the missing files $Query = "SELECT * from AllDocs where SetupPath like '"+$SetupFile+"'" $QueryResults = @(Run-SQLScript -SQLServer $Server -SQLDatabase $Database -SQLQuery $Query | select Id, SiteId, WebId) # Iterate through results ForEach ($Result in $QueryResults) { If ($Result.id -ne $Null) { $Site = Get-SPSite -Limit all | where { $_.Id -eq $Result.SiteId } $Web = $Site | Get-SPWeb -Limit all | where { $_.Id -eq $Result.WebId } #Get the URL of the file which is referring the feature $File = $web.GetFile([Guid]$Result.Id) write-host "$($Web.URL)/$($File.Url)" -foregroundcolor green #$File.delete() } }