1

Database migration resulted in some Documents being corrupted and unable to Open. Now I need to find where these Documents resides.

My plan is to use a PowerShell script to iterate through all Document Libraries on all Webs but I am not sure how to check if a document is corrupt or not.

SOLVED: I have created a script iterating through all Document Libraries checking for difference in filesize between what SharePoint thinks and how big the file in the Database really is. Im also doing a try/catch so make sure I don't miss any totally corrupt files. Im running this on the server right now but it will take some time to finish.

Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue
[Microsoft.SharePoint.SPSecurity]::RunWithElevatedPrivileges(
{

 $corruptCount = 0;
 $OutputFile = $path + "D:\Installation\Tools\CorruptDocuments.csv"
 "FileUrl`tSPFileSize`tDataBaseFileSize`tFileType`tException" | Out-file $OutputFile -append

 $SPWebApp = Get-SPWebApplication http://portal.com

 foreach ($SPSite in $SPWebApp.Sites)
 {
  foreach($web in $SPSite.AllWebs) {
    foreach($list in $web.Lists) {
    if($list.BaseType -eq "DocumentLibrary") {

        foreach($SPfile in $list.items)
       {

      Try
              {
                $SPFileSize = $SPfile.File.Length
                $systemFile= $web.GetFile($SPfile.Url)
                $bytes = $systemFile.OpenBinary();
                Write-Host "SharePoint Filesize is: "$SPFileSize
                Write-Host "System Filesize is:     "$bytes.Length

   if($SPFileSize % $bytes.Length -ne 0 )
               {
               "$($web.Url+"/"+$SPfile.Url)`t$($SPFileSize)`t$($bytes.Length)`t$($SPfile.file.item.ContentType.Name)" | Out-file $OutputFile -append

                 }
            }
            Catch
            {
                "$($web.Url+"/"+$SPfile.Url)`t$($SPFileSize)`t$($bytes.Length)`t$($SPfile.file.item.ContentType.Name)`t$($_.Exception.Message)" | Out-file $OutputFile -append
            }
    }
    }
  }
  $web.Dispose();
}
$SPSite.Dispose();
}
})

When running this script I found documents that threw exception.

"Exception calling "OpenBinary" with "0" argument(s): "Exception of type 'Cobalt.ErrorException' was thrown.""

These documents were corrupted and could not be opened or even downloaded from the Document Library.

  • 1
    You mentioned end-users being unable to open corrupted documents; is there an error in the UI? Better still, is there any kind of stack trace you can traverse? Are you able to open the same documents via PowerShell or a console application? At what point does accessing the file fail, exactly? Getting the bytes? Could be a simple pathing issue, too. – nsturdivant Jun 4 '15 at 18:23
  • The end-users are prompted with a UI-error from the different Office programs stating that the document is corrupt. I have no known corrupt files at this time to try to open trough powershell to test. My plan is to use some kind of script to find them. – Skaft Jun 5 '15 at 5:36
2

skaft, find one document manually which is corrupted and access it with powershell and compare the properties with healthy file in powershell. It will give you a direction how to check if the file is corrupted. You may want to convert the file into some bytes stream to confirm if the file is healthy.

  • Simple solution. Right now im stuck as I don't know which documents are corrupt and the site contains thousands of documents. If I find out I will try your solution but until then I need to find another way. – Skaft Jun 4 '15 at 12:53
  • As soon as customer finds corrupted documents they replace it with an old functional backuped version. So there are no known corrupt documents at this time. – Skaft Jun 4 '15 at 13:25
  • 1
    That's rough. To Naveen's point, having a "before and after" of the document properties would be good. Can you restore a post-migration backup, perhaps? Or maybe rerun the migration in a test environment in order to recreate the corrupted files? – nsturdivant Jun 4 '15 at 18:38
2

I have created a script iterating through all Document Libraries checking for difference in filesize between what SharePoint thinks and how big the file in the Database really is. Im also doing a try/catch so make sure I don't miss any totally corrupt files.

  Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue
[Microsoft.SharePoint.SPSecurity]::RunWithElevatedPrivileges(
{

 $corruptCount = 0;
 $OutputFile = $path + "D:\Installation\Tools\CorruptDocuments.csv"
 "FileUrl`tSPFileSize`tDataBaseFileSize`tFileType`tException" | Out-file $OutputFile -append

 $SPWebApp = Get-SPWebApplication http://portal.com

 foreach ($SPSite in $SPWebApp.Sites)
 {
  foreach($web in $SPSite.AllWebs) {
    foreach($list in $web.Lists) {
    if($list.BaseType -eq "DocumentLibrary") {

        foreach($SPfile in $list.items)
       {

      Try
              {
                $SPFileSize = $SPfile.File.Length
                $systemFile= $web.GetFile($SPfile.Url)
                $bytes = $systemFile.OpenBinary();
                Write-Host "SharePoint Filesize is: "$SPFileSize
                Write-Host "System Filesize is:     "$bytes.Length

   if($SPFileSize % $bytes.Length -ne 0 )
               {

               "$($web.Url+"/"+$SPfile.Url)`t$($SPFileSize)`t$($bytes.Length)`t$($SPfile.file.item.ContentType.Name)" | Out-file $OutputFile -append

                 }
            }
            Catch
            {
                "$($web.Url+"/"+$SPfile.Url)`t$($SPFileSize)`t$($bytes.Length)`t$($SPfile.file.item.ContentType.Name)`t$($_.Exception.Message)" | Out-file $OutputFile -append
            }
    }
    }
  }
  $web.Dispose();
}
$SPSite.Dispose();
}
})

When running this script I found documents that threw exception.

"Exception calling "OpenBinary" with "0" argument(s): "Exception of type 'Cobalt.ErrorException' was thrown.""

This Exception was thrown while OpenBinary method was running, which is a good implication that the document is corrupt as the method has trouble reading the binary code of the database item. These documents could not be opened manually in the Document library or downloaded. When trying to open the corrupt documents SharePoint gave the false error message that "This document has not been shared with you", even though we were using an Admin account with full permissions.

Some documents could be downloaded manually but could not be opened with their native application, stating that "the document were corrupt or damaged".

1

This will be a tedious task.

Since there are many file types, validating each one requires custom coding for specific type of files. For example to validate Word documents you need to use Office InterOp or OpenXML SDK. For PDF you need to use ADOBE or other available API's.

I would recommend doing another migration.

If you only want to do basic validation, then you can read the File Signatures and compare it with pre-defined bytes

For example PDF files uses signature 25 50 44 46 - For more http://www.garykessler.net/library/file_sigs.html

  • Sadly, customer will not do another migration. When they find corrupted documents they replace it with a old back up. – Skaft Jun 4 '15 at 13:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.