Second Life of a Hungarian SharePoint Geek

July 16, 2015

How to process the output of the Test-SPContentDatabase cmdlet

Filed under: PowerShell, Regular expressions, SP 2013 — Tags: , , — Peter Holpar @ 22:07

The Test-SPContentDatabase PowerShell cmdlet is a handy tool if you have to check the healthiness of your web application, for example, if you are preparing an upgrade, or migrating content DBs between servers.

Since its output can be pretty long, its typical usage is to redirect the output to a text file, like:

Test-SPContentDatabase -Name YourContentDB -WebApplication http://YourWebApp > F:\data\pholpar\TestSPContentDB.txt

The problem with this approach is, that the output contains a textural representation of the result. You can browse through the text, but it is problematic, if the output is huge. Furthermore, it is not suitable for direct automation, for example, if you would like to create some kind of report or statistic, or to feed a tool that should fix the issues.

I’ve tried to find the source of the information displayed by the tool in the object model, and found that the text is assembled in the components very deep in the object hierarchy, just above the data access layer, so we can not achieve it via Reflection (for example by calling private methods of internal classes) as well. If you don’t want to tamper wit the database (that is generally not recommended by Microsoft, to say the least), you should find another way.

You can parse out for example the values you need from the text using PowerShell and regular expressions. In my post below I provide you with the scripts you can use to get the information for the four main types of errors retuned by Test-SPContentDatabase: MissingFeature, MissingSetupFile, MissingAssembly and MissingWebPart.

First, instead of the redirection the output to a text file, we store all of the items returned by the Test-SPContentDatabase cmdlet (each item is of type SPContentDatabaseTestResult) in a variable:

$problems = Test-SPContentDatabase -Name YourContentDB -WebApplication http://YourWebApp

The items of category MissingFeature have the following properties.

Category        : MissingFeature
Error           : True
UpgradeBlocking : False
Message         : Database [YourContentDB] has reference(s) to a missing f
                  eature: Id = [75fa102a-b85d-4e7d-bd7f-00101b98e11e].
Remedy          : The feature with Id 75fa102a-b85d-4e7d-bd7f-00101b98e11e is r
                  eferenced in the database [YourContentDB], but is not in
                  stalled on the current farm. The missing feature may cause up
                  grade to fail. Please install any solution which contains the
                   feature and restart upgrade if necessary.

We can use the Message property to parse out the name of the content database and the Id of the feature.

$problems | ? { $_.Category -eq "MissingFeature" } | % {
  $obj = New-Object PSObject
  Add-Member -InputObject $obj -MemberType NoteProperty -Name ContentDb -Value ($_.Message | Select-String -Pattern "Database \[(?<db>[^\[]*)\]" | Select -Expand Matches | % {$_.Groups["db"].Value })
  Add-Member -InputObject $obj -MemberType NoteProperty -Name Feature -Value ($_.Message | Select-String -Pattern "missing feature: Id = \[(?<feature>[^\[]*)\]" | Select -Expand Matches | % {$_.Groups["feature"].Value })
  return $obj
} | % { Write-Host ContentDb: $_.ContentDb`r`nFeature: $_.Feature`r`n`r`n }

Similarly, the items of category MissingSetupFile have this format:

Category        : MissingSetupFile
Error           : True
UpgradeBlocking : False
Message         : File [Features\PublishingLayouts\Images\gr_logo.jpg] is refer
                  enced [1] times in the database [YourContentDB], but is
                  not installed on the current farm. Please install any feature
                  /solution which contains this file.
Remedy          : One or more setup files are referenced in the database [YourC
                  ontentDB], but are not installed on the current farm. Please
                  install any feature or solution which contains these files.

The script for this type of items:

$problems | ? { $_.Category -eq "MissingSetupFile" } | % {
  $obj = New-Object PSObject
  Add-Member -InputObject $obj -MemberType NoteProperty -Name ContentDb -Value ($_.Message | Select-String -Pattern "in the database \[(?<db>[^\[]*)\]" | Select -Expand Matches | % {$_.Groups["db"].Value })
  Add-Member -InputObject $obj -MemberType NoteProperty -Name RefCount -Value ($_.Message | Select-String -Pattern "is referenced \[(?<refcount>[^\[]*)\]" | Select -Expand Matches | % {$_.Groups["refcount"].Value })
  Add-Member -InputObject $obj -MemberType NoteProperty -Name File -Value ($_.Message | Select-String -Pattern "File \[(?<filename>[^\[]*)\]" | Select -Expand Matches | % {$_.Groups["filename"].Value })
  return $obj
} | % { Write-Host ContentDb: $_.ContentDb`r`nReference count: $_.RefCount`r`nFile: $_.File`r`n`r`n }

The items of category MissingAssembly have this format:

Category        : MissingAssembly
Error           : True
UpgradeBlocking : False
Message         : Assembly [YourComp.Custom.EventReceiver, Version=1.0.0.0,
                   Culture=neutral, PublicKeyToken=8ffc7db3dc6d3b89] is referen
                  ced in the database [YourContentDB], but is not installe
                  d on the current farm. Please install any feature/solution wh
                  ich contains this assembly.
Remedy          : One or more assemblies are referenced in the database [YourCo
                  ntentDB], but are not installed on the current farm. Please i
                  nstall any feature or solution which contains these asse
                  mblies.

The script for this type of items:

$problems | ? { $_.Category -eq "MissingAssembly" } | % {
  $obj = New-Object PSObject
  Add-Member -InputObject $obj -MemberType NoteProperty -Name ContentDb -Value ($_.Message | Select-String -Pattern "in the database \[(?<db>[^\[]*)\]" | Select -Expand Matches | % {$_.Groups["db"].Value })
  Add-Member -InputObject $obj -MemberType NoteProperty -Name Assembly -Value ($_.Message | Select-String -Pattern "Assembly \[(?<assembly>[^\[]*)\]" | Select -Expand Matches | % {$_.Groups["assembly"].Value })
  return $obj
} | % { Write-Host ContentDb: $_.ContentDb`r`nAssembly: $_.Assembly`r`n`r`n }

Finally, he items of category MissingWebPart have the format:

Category        : MissingWebPart
Error           : True
UpgradeBlocking : False
Message         : WebPart class [9c7d980e-6470-94d9-db54-419b27d03880] is refer
                  enced [3] times in the database [YourContentDB], 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 [YourCon
                  tentDB], but are not installed on the current farm. Please in
                  stall any feature or solution which contains these web parts.

And the important attributes of these items can be parsed out via this script:

$problems | ? { $_.Category -eq "MissingWebPart" } | % {
  $obj = New-Object PSObject
  Add-Member -InputObject $obj -MemberType NoteProperty -Name ContentDb -Value ($_.Message | Select-String -Pattern "in the database \[(?<db>[^\[]*)\]" | Select -Expand Matches | % {$_.Groups["db"].Value })
  Add-Member -InputObject $obj -MemberType NoteProperty -Name RefCount -Value ($_.Message | Select-String -Pattern "is referenced \[(?<refcount>[^\[]*)\]" | Select -Expand Matches | % {$_.Groups["refcount"].Value })
  Add-Member -InputObject $obj -MemberType NoteProperty -Name Id -Value ($_.Message | Select-String -Pattern "WebPart class \[(?<id>[^\[]*)\]" | Select -Expand Matches | % {$_.Groups["id"].Value })
  Add-Member -InputObject $obj -MemberType NoteProperty -Name Class -Value ($_.Message | Select-String -Pattern " \(class \[(?<class>[^\[]*)\]" | Select -Expand Matches | % {$_.Groups["class"].Value })
  Add-Member -InputObject $obj -MemberType NoteProperty -Name Assembly -Value ($_.Message | Select-String -Pattern "from assembly \[(?<assembly>[^\[]*)\]" | Select -Expand Matches | % {$_.Groups["assembly"].Value })
  return $obj
} | % { Write-Host ContentDb: $_.ContentDb`r`nReference count: $_.RefCount`r`nId: $_.Id`r`nClass: $_.Class`r`nAssembly: $_.Assembly`r`n`r`n }

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: