In this article I am going to
focus on MissingWebPart and MissingAssembly errors. As stated in
previous articles, there is no silver bullet to solving these errors in
all cases, but the scripts offered here will allow you troubleshoot the
errors further to find exactly where they are happening in the content
database. Once you know this, you have a fighting chance of being able
to solve the problem.
MissingWebPart Error
In
this example, I have received the following error whilst running a
Test-SPContentDatabase operation after a content database migration from
SharePoint 2007 to 2010. It also appears in the SharePoint Health
Analyzer under the “Configuration” category with the title “Missing
server side dependencies”:
Category : MissingWebPart
Error : True
UpgradeBlocking : False
Message
: WebPart class [4575ceaf-0d5e-4174-a3a1-1a623faa919a] is referenced
[2] times in the database [SP2010_Content], but is not installed on the
current farm. Please install any feature/solution which contains this
web part.
Remedy : One or more web parts are referenced in
the database [SP2010_Content], but are not installed on the current
farm. Please install any feature or solution which contains these web
parts.
As you can see, the error gives you a “WebPart
class” GUID, the name of the content database, and how many times it is
referenced in the database, but little else. What we need to find out
here is either the name of the web part or on which pages it is
referenced in the database.
For this I am going to reuse the Run-SQLQuery PowerShell script that I introduced in my article on MissingSetupFile errors:
function Run-SQLQuery ($SqlServer, $SqlDatabase, $SqlQuery)
{
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server =" + $SqlServer + "; Database =" + $SqlDatabase + "; Integrated Security = True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$SqlConnection.Close()
$DataSet.Tables[0]
}
Once
you have loaded the function in a PowerShell console, you can run it by
using the Run-SQLQuery command with the options relevant to your
deployment. For [MissingWebPart] errors, you need to run a SQL SELECT
query on the “AllDocs” table in the content database exhibiting the
problem, joining to the “AllWebParts” table in order to find details
about the missing web part. For example, you would type the following
command to find details of the web part with the class ID
“4575ceaf-0d5e-4174-a3a1-1a623faa919a”, as reported in the error above:
Run-SQLQuery
-SqlServer "SQLSERVER" -SqlDatabase "SP2010_Content" -SqlQuery "SELECT *
from AllDocs inner join AllWebParts on AllDocs.Id =
AllWebParts.tp_PageUrlID where AllWebParts.tp_WebPartTypeID =
'4575ceaf-0d5e-4174-a3a1-1a623faa919a'" | select Id, SiteId, DirName,
LeafName, WebId, ListId, tp_ZoneID, tp_DisplayName | Format-List
Yes, it is a pretty long command, but it will produce a very useful output, as shown in this example:
Id : 6ab5e70b-60d8-4ddf-93cb-6a93fbc410be
SiteId : 337c5721-5050-46ce-b112-083ac52f7f26
DirName : News/Pages
LeafName : ArticleList.aspx
WebId : dcc93f3e-437a-4fae-acea-bb15d5c4ea7d
ListId : 7e13fe6c-3670-4d46-9601-832e3eb6a1e4
tp_ZoneID : Body
tp_DisplayName :
Id : b3fcfcd2-2f02-4fe9-93e4-9c9b5ecddf5b
SiteId : 337c5721-5050-46ce-b112-083ac52f7f26
DirName : Pages
LeafName : Welcome.aspx
WebId : 2ae0de59-a008-4244-aa66-d8f76c79f1ad
ListId : d8f083f0-16b9-43d0-9aaf-4e9fffecd6cc
tp_ZoneID : RightColumnZone
tp_DisplayName :
This
tells us that the web part has been found on two pages (the references
mentioned in the MissingWebPart error). SiteId tells us the site
collection and WebId the site where the pages are located. We also have a
DirName showing the relative path and the page name itself against the
LeafName property. If you’re lucky, you might get the display name of
the web part against the tp_DisplayName property, but if not, you should
at least be able to tell which zone the web part has been added to by
looking at the tp_ZoneID property.
Easily the best way of
resolving these issues is to do as the error suggests and install the
missing feature or solution containing the web part, but if this is not
possible or feasible to do in your scenario, we can discover the site
collection URL from the GUIDs using PowerShell and then remove the
offending web parts from the pages specified.
To find the site collection URL using the information output from the query, type the following command:
$site = Get-SPSite -Limit all | where {$_.Id -eq "337c5721-5050-46ce-b112-083ac52f7f26"}
$site.Url
One
you have the site collection URL, you can use the relative path
specified by the DirName property to find the location of the file. To
remove the web part from the page, type the page URL in the browser and
add ?contents=1 to the end of it. For example, to open the web part
maintenance page for the ArticleList.aspx page specified in the output,
type the following URL in the browser:
http://portal/news/pages/articlelist.aspx?contents=1
You
can then highlight the offending web part (normally called ErrorWebPart
for MissingWebPart errors) by ticking the box and clicking
Delete.
The screenshot below shows a web part maintenance page to give you an
idea of the UI, but not an example of an ErrorWebPart as I had already
removed them!
Note:
If you remove an ErrorWebPart from a publishing page with versioning
switched on, you may have to delete all earlier versions of the page
before the error disappears from the SharePoint Health Analyzer or
Test-SPContentDatabase report. This is because the web part will still
be referenced from these versions, even though you removed it from the
currently published page.
MissingAssembly Error
MissingAssembly errors look similar to this one:
Category : MissingAssembly
Error : True
UpgradeBlocking : False
Message
: Assembly [PAC.SharePoint.Tagging, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=b504d4b6c1e1a6e5] is referenced in the database
[SP2010_Content], but is not installed on the current farm. Please
install any feature/solution which contains this assembly.
Remedy
: One or more assemblies are referenced in the database
[SP2010_Content], but are not installed on the current farm. Please
install any feature or solution which contains these assemblies.
I
normally find MissingAssembly errors appear as the result of an event
receiver, which is still registered on a list or library but part of a
feature/solution no longer present on the farm.
In most cases,
you may be able to look at the assembly name reported in this error and
know what the problem is straight away. As before, the best way of
resolving this is to reinstall the missing solution file. However, if
you are not able to install the solution (e.g., maybe it only works in
SharePoint 2007 and not 2010), then you may want to find the lists where
the event receiver is installed and either remove the event receiver
from the lists or delete the lists themselves.
To troubleshoot
this issue we can re-use the Run-SQLQuery function used to help find
missing web parts above. The table we need to look at this time though
is called “EventReceivers”. For example, you would type the following
command to find details of the assembly called “PAC.SharePoint.Tagging,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=b504d4b6c1e1a6e5”, as
reported in the error above:
Run-SQLQuery
-SqlServer "SQLSERVER" -SqlDatabase "SP2010_Content" -SqlQuery "SELECT *
from EventReceivers where Assembly = ‘PAC.SharePoint.Tagging,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=b504d4b6c1e1a6e5'" |
select Id, Name, SiteId, WebId, HostId, HostType | Format-List
This will produce an output similar to the following:
Id : 657a472f-e51d-428c-ab98-502358d87612
Name :
SiteId : 337c5721-5050-46ce-b112-083ac52f7f26
WebId : 2ae0de59-a008-4244-aa66-d8f76c79f1ad
HostId : 09308020-45a8-41e4-bbc0-7c8d8cd54132
HostType : 2
Id : 0f660612-6be0-401e-aa1d-0ede7a9af8da
Name :
SiteId : 337c5721-5050-46ce-b112-083ac52f7f26
WebId : 2ae0de59-a008-4244-aa66-d8f76c79f1ad
HostId : 09308020-45a8-41e4-bbc0-7c8d8cd54132
HostType : 2
As
with the MissingWebPart error before, we can use these GUIDs to get the
site collection and site hosting the list with the missing event
receiver, as follows:
$site = Get-SPSite -Limit all | where {$_.Id -eq "337c5721-5050-46ce-b112-083ac52f7f26"}
$web = $site | Get-SPWeb -Limit all | where {$_.Id -eq "2ae0de59-a008-4244-aa66-d8f76c79f1ad"}
$web.Url
The
HostId property is the GUID of the object containing the event
receiver. The HostType is the object type – in this case, HostType “2”
means the event receiver host is a list. You can look at the other host
types by checking this article on MSDN:
http://msdn.microsoft.com/en-us/library/ee394866(v=prot.13).aspx.
Now we know the GUID refers to a list, we can get it using PowerShell with this command:
$list = $web.Lists | where {$_.Id -eq "09308020-45a8-41e4-bbc0-7c8d8cd54132"}
To remove the list completely, type the following command:
$list.Delete()
To
keep the list intact and just remove the offending event receiver, copy
the Id property from the Run-SQLQuery output into this command:
$er = $list.EventReceivers | where {$_.Id -eq "657a472f-e51d-428c-ab98-502358d87612"}
$er.Delete()
If you do decide to delete the list completely, ensure you also remove it from the site Recycle Bin
and
Site Collection Recycle Bin to ensure the file is removed from the
content database. If not, the error may not disappear from the Health
Analyzer or Test-SPContentDatabase operation.
http://get-spscripts.com/2011/08/diagnose-missingwebpart-and.html