Sunday, June 2, 2013

Missing server side dependencies


היי חברים,
ישנה בעיה שעולה מ- Health Analyzer Reports תחת ה- Monitoring :



אז מה בעצם ה-Error אומר , ה-Error מדווח לנו שקיימים רכיבים כגון : WebParts, SetupFile, Assemblies וכו' , שיש עליהם רשומות בבסיסי הנתונים של SP אך הם לאוו דווקא קיימים באתרים עצמם , דוגמא : ישנה רשומה שמפרטת על Feature שקיים ב-DB אך מסריקה של Features בחווה לא ניתן לראות אותו.
כדי להתגבר על הבעיה ניתן לבצע שליפות של כלל הרכיבים מבסיס הנתונים בעזרת קוד PowerShell ולבצע הסרה של הרכיבים בעת הצורך. (לכל רכיב שליפה שונה )

דוגמה :
[MissingWebPart] WebPart class [b751113f-8f0f-d75a-b4bf-fa2ae8a3053d] is referenced [3] times in the database [WSS_Content_pais-portal2010_5], 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_pais-portal2010_5], but are not installed on the current farm. Please install any feature or solution which contains these web parts.

[MissingAssembly] Assembly [OmniReference, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d4b0446e2c1be297] is referenced in the database [WSS_Content_pais-portal2010_2], but is not installed on the current farm. Please install any feature/solution which contains this assembly. One or more assemblies are referenced in the database [WSS_Content_pais-portal2010_2], but are not installed on the current farm. Please install any feature or solution which contains these assemblies.

[MissingFeature] Database [WSS_Content_pais-portal2010_Kehila_SiteCollection] has reference(s) to a missing feature: Id = [700e6c97-c296-46c6-bafd-5838e860daa5]. The feature with Id 700e6c97-c296-46c6-bafd-5838e860daa5 is referenced in the database [WSS_Content_pais-portal2010_Kehila_SiteCollection], but is not installed on the current farm. The missing feature may cause upgrade to fail. Please install any solution which contains the feature and restart upgrade if necessary.


[MissingSetupFile] File [Features\ExcelServerSite\Microsoft.Office.Excel.WebUI.dwp] is referenced [1] times in the database [WSS_Content_pais-portal2010_3], but is not installed on the current farm. Please install any feature/solution which contains this file. One or more setup files are referenced in the database [WSS_Content_pais-portal2010_3], but are not installed on the current farm. Please install any feature or solution which contains these files.





כדי לגשת לנתונים בעזרת קוד ב-  PowerShell  יש להעתיק את הפונקציות ל-  Management Shell:

שלב ראשון 

בדיקה על  Features :
function Remove-SPFeatureFromContentDB($ContentDb, $FeatureId, [switch]$ReportOnly)
{
    $db = Get-SPDatabase | where { $_.Name -eq $ContentDb }
    [bool]$report = $false
    if ($ReportOnly) { $report = $true }
    
    $db.Sites | ForEach-Object {
        
        Remove-SPFeature -obj $_ -objName "site collection" -featId $FeatureId -report $report
                
        $_ | Get-SPWeb -Limit all | ForEach-Object {
            
            Remove-SPFeature -obj $_ -objName "site" -featId $FeatureId -report $report
        }
    }
}
function Remove-SPFeature($obj, $objName, $featId, [bool]$report)
{
    $feature = $obj.Features[$featId]
    
    if ($feature -ne $null) {
        if ($report) {
            write-host "Feature found in" $objName ":" $obj.Url -foregroundcolor Red
        }
        else
        {
            try {
                $obj.Features.Remove($feature.DefinitionId, $true)
                write-host "Feature successfully removed from" $objName ":" $obj.Url -foregroundcolor Red
            }
            catch {
                write-host "There has been an error trying to remove the feature:" $_
            }
        }
    }
    else {
        #write-host "Feature ID specified does not exist in" $objName ":" $obj.Url
    }
}


בדיקה על  WebParts/SetupFile/Assemblies  :
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]
}



השלב השני הוא להריץ שאילתה ולצפות בפלט, על סמך הנתונים נדע איפה הבעיה מתרחשת.

דוגמה לשימוש בפונקציה על Features:

Remove-SPFeatureFromContentDB -ContentDB "SharePoint_Content_Portal" -FeatureId "8096285f-1463-42c7-82b7-f745e5bacf29" –ReportOnly
הפלט יהיה כל האתרים בהם ה-Feature מופיע 
 כדי להסיר את ה-Feature מהאתרים אלו יש לרשום את אותה הפקודה ללא הפרמטר
-ReportOnly

כלומר :
Remove-SPFeatureFromContentDB -ContentDB "SharePoint_Content_Portal" -FeatureId "8096285f-1463-42c7-82b7-f745e5bacf29"




דוגמה לשימוש בפונקציה על SetupFile:

כדי למצוא את ה- SetupFile באתר הרלוונטי יש להריץ את הפקודה הבאה :
Run-SQLQuery -SqlServer "SQLSERVER" -SqlDatabase "DataBaseName" -SqlQuery "SELECT * from AllDocs where SetupPath = 'SetupFile Path'" | select Id, SiteId, DirName, LeafName, WebId, ListId | Format-List
התוצאה שנקבל :
Id       : f5fc66e7-920a-4b44-9e3d-3a5ab825093f
SiteId   : 7b4d043c-8bbe-4068-ad91-3c270dfae151
DirName  : subsite/Workflows/Review Page
LeafName : Review Page.xoml
WebId    : 1876be06-419f-46fb-a942-a15e510f1a70
ListId   : a04dda01-a52d-4d5b-b3b4-fcd70a05e4ba

כדי להבין מאיזה אתר אב / אתר בן השגיאה נזרקת נרשום את הפקודה הבאה על סמך הפלט שקיבלנו :
$site = Get-SPSite -Limit all | where { $_.Id -eq "7b4d043c-8bbe-4068-ad91-3c270dfae151" }
$web = $site | Get-SPWeb -Limit all | where { $_.Id -eq "1876be06-419f-46fb-a942-a15e510f1a70" }
$web.Url

כל מה שנותר הוא למחוק את הקובץ מהנתיב הרלוונטי בעזרת SPDesigner או דרךך ממשק המשתמש.
שים לב !  אם אתה מחליט למחוק את הקובץ מהאתר, זכור להסיר את הקובץ מסל המיחזור של האתר וסל המיחזור של אוסף אתרים כדי להבטיח שהקובץ הוסר מאתר התוכן. אם לא, ייתכן שהשגיאה לא תיעלם מ - Health Analyzer Reports


דוגמה לשימוש בפונקציה על WebPart :  

Run-SQLQuery -SqlServer "SQLSERVER" -SqlDatabase "DataBaseName" -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

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 :

כדי למצוא את ה-URL של אוסף האתרים באמצעות המידע שהתקבל בפלט, הקלד את הפקודה הבאה:
$site = Get-SPSite -Limit all | where {$_.Id -eq "337c5721-5050-46ce-b112-083ac52f7f26"}
$site.Url
כדי להגיעה למקום בו קוראת השגיאה ניתן להיעזר בנתיב הרלטיבי מהפלט (DirName) לרשום את ה-URL ולהוסיף את הפרמטר Content=1.
דוגמה : http://portal/news/pages/articlelist.aspx?contents=1
הדף שיפתח יציג את ה-WebPart עם הבעייתי תחת " ErrorWebPart" , תוכלו לבחור בו ולמחוק אותו.




בהצלחה!
רון נס.


 ============================================================================================================================================================================================


Hi Friends,
There is a problem that comes from Health Analyzer Reports under the Monitoring:


So what the Error says ... The Error reports about components such as: WebParts, SetupFile, Assemblies etc, that are registered in the database of the SP but  Not actually existing on-site, an example: There is record that a feature exists on DB but when we scanning the farm, We can't see the Features.
To overcome this problem you can make Queriesfrom the database using PowerShell code and to remove components when needed. (Different for each component retrieval)

Example:

[MissingWebPart] WebPart class [b751113f-8f0f-d75a-b4bf-fa2ae8a3053d] is referenced [3] times in the database [WSS_Content_pais-portal2010_5], 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_pais-portal2010_5], but are not installed on the current farm. Please install any feature or solution which contains these web parts.

[MissingAssembly] Assembly [OmniReference, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = d4b0446e2c1be297] is referenced in the database [WSS_Content_pais-portal2010_2], but is not installed on the current farm. Please install any feature / solution which contains this assembly. One or more assemblies are referenced in the database [WSS_Content_pais-portal2010_2], but are not installed on the current farm. Please install any feature or solution which contains these assemblies.

[MissingFeature] Database [WSS_Content_pais-portal2010_Kehila_SiteCollection] has reference (s) to a missing 
feature: Id = [700e6c97-c296-46c6-bafd-5838e860daa5]. The feature with Id 700e6c97-c296-46c6-bafd-5838e860daa5 is referenced in the database [WSS_Content_pais-portal2010_Kehila_SiteCollection], but is not installed on the current farm. The missing feature may cause upgrade to fail. Please install any solution which contains the feature and restart upgrade if necessary.


[MissingSetupFile] File [Features \ ExcelServerSite \ Microsoft.Office.Excel.WebUI.dwp] is referenced [1] times in the database [WSS_Content_pais-portal2010_3], but is not installed on the current farm. Please install any feature / solution which contains this file. One or more setup files are referenced in the database [WSS_Content_pais-portal2010_3], but are not installed on the current farm. Please install any feature or solution which contains these files.



To access the data with the code on PowerShell copy the functions to Management Shell:

Step 1

Features:

function Remove-SPFeatureFromContentDB ($ ContentDb, $ FeatureId, [switch] $ ReportOnly)
{
    $ Db = Get-SPDatabase | where {$ _.Name-eq $ ContentDb}
    [Bool] $ report = $ false
    if ($ ReportOnly) {$ report = $ true}
    
    $ Db.Sites | ForEach-Object {
        
        Remove-SPFeature-obj $ _-objName "site collection"-featId $ FeatureId-report $ report
                
        $ _ | Get-SPWeb-Limit all | ForEach-Object {
            
            Remove-SPFeature-obj $ _-objName "site"-featId $ FeatureId-report $ report
        }
    }
}
function Remove-SPFeature ($ obj, $ objName, $ featId, [bool] $ report)
{
    $ Feature = $ obj.Features [$ featId]
    
    if ($ feature-ne $ null) {
        if ($ report) {
            write-host "Feature found in" $ objName ":" $ obj.Url-foregroundcolor Red
        }
        else
        {
            try {
                $ Obj.Features.Remove ($ feature.DefinitionId, $ true)
                write-host "Feature successfully removed from" $ objName ":" $ obj.Url-foregroundcolor Red
            }
            catch {
                write-host "There has been an error trying to remove the feature:" $ _
            }
        }
    }
    else {
        # Write-host "Feature ID specified does not exist in" $ objName ":" $ obj.Url
    }
}


WebParts / SetupFile / Assemblies:

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]
}

The second step is to run a query and view the output, based on the data we know where the problem occurs.

Example of using the function Features:

Remove-SPFeatureFromContentDB -ContentDB "SharePoint_Content_Portal" -FeatureId "8096285f-1463-42c7-82b7-f745e5bacf29" -ReportOnly

This query Will output all the sites where the feature appears
 To remove the feature in these sites you can use the  same command without parameter -ReportOnly

Namely:
Remove-SPFeatureFromContentDB -ContentDB "SharePoint_Content_Portal" -FeatureId "8096285f-1463-42c7-82b7-f745e5bacf29"

Example of using the function SetupFile:

To find the relevant site that the SetupFile,  run the following command:

Run-SQLQuery-SqlServer "SQLSERVER"-SqlDatabase "DataBaseName"-SqlQuery "SELECT * from AllDocs where SetupPath = 'SetupFile Path'" | select Id, SiteId, DirName, LeafName, WebId, ListId | Format-List

The result we get:

Id: f5fc66e7-920a-4b44-9e3d-3a5ab825093f
SiteId: 7b4d043c-8bbe-4068-ad91-3c270dfae151
DirName: subsite / Workflows / Review Page
LeafName: Review Page.xoml
WebId: 1876be06-419f-46fb-a942-a15e510f1a70
ListId: a04dda01-a52d-4d5b-b3b4-fcd70a05e4ba

To understand on which SiteCollection / SubSites  the error thrown write the following command based on the output we received:

$ Site = Get-SPSite-Limit all | where {$ _.Id-eq "7b4d043c-8bbe-4068-ad91-3c270dfae151"}
$ Web = $ site | Get-SPWeb-Limit all | where {$ _.Id-eq "1876be06-419f-46fb-a942-a15e510f1a70"}
$ Web.Url

All that remains is to delete the relevant file path using SPDesigner or SP user interface.

Note! If you decide to delete the file from the site, remember to remove the file from the recycle bin recycle bin site of a site collection to ensure that the file is removed from the content. If not, the error might not disappear from Health Analyzer Reports


Example of using the function on WebPart:

Run-SQLQuery-SqlServer "SQLSERVER"-SqlDatabase "DataBaseName"-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

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:

To find the URL of the site collection use the information from the output, type the following command:

$ Site = Get-SPSite-Limit all | where {$ _.Id-eq "337c5721-5050-46ce-b112-083ac52f7f26"}
$ Site.Url

To get  the place in the site that the error occurred you need to use Relative path (DirName) enter the URL and add the parameter Content = 1.
Example: http://portal/news/pages/articlelist.aspx?contents=1
Page will open the WebPart with problematic under "ErrorWebPart", you can select it and delete it





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 "DataBaseName -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.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.



Good Luck :)
Ron Ness.

No comments:

Post a Comment