New DFSR Data Restoration Script

New DFSR Data Restoration Script

  • Comments 44
  • Likes

Hi, Ned here. Just a quick heads up - there is a new DFSR data recovery script posted below. This allows you to restore data from the ConflictAndDeleted or PreExisting folders within DFSR, primarily during disaster recovery. As always, we prefer you use your backup system to do this, as the script is 'at your own risk' and unsupported.

Updated 10/15/10

The latest script is now hosted on Code Gallery: http://code.msdn.microsoft.com/restoredfsr

Update 6/12/14

Well that gallery is kaput. Now hosted from here.

This old script is really gross, I recommend instead using our new Windows PowerShell cmdlet Restore-DfsrPreservedFiles instead. You can restore from 8.1 client if you install RSAT, or from a WS2012 R2 server. Can either run locally or just map a drive to \\dfsrserver\h$ or whatever the root drive is, then restore.

Take a look at http://blogs.technet.com/b/filecab/archive/2013/08/23/dfs-replication-in-windows-server-2012-r2-restoring-conflicted-deleted-and-preexisting-files-with-windows-powershell.aspx for steps on using this cmdlet.

-----------------------------------------------

Remember, this script must be run from a CMD prompt using cscript. Don't just double-click it.

CSCRIPT.EXE RESTOREDFSR.VBS

The script also requires to edit three paths (your source files, a new destination path, and the XML manifest you are calling) . If you fail to edit those the script will exit with an error:


'=======================================================================
' Section must be operator-edited to provide valid paths
'=======================================================================

' Change path to specify location of XML Manifest
' Example 1: "C:\Data\DfsrPrivate\ConflictAndDeletedManifest.xml"
' Example 2: "C:\Data\DfsrPrivate\preexistingManifest.xml"

objXMLDoc.load("C:\your_replicated_folder\DfsrPrivate\ConflictAndDeletedManifest.xml")

' Change path to specify location of source files

' Example 1: "C:\data\DfsrPrivate\ConflictAndDeleted"
' Example 2: "C:\data\DfsrPrivate\preexisting"

SourceFolder = ("C:\your_replicated_folder\DfsrPrivate\ConflictAndDeleted")

' Change path to specify output folder

OutputFolder = ("c:\your_dfsr_repair_tree")

'========================================================================

- Ned Pyle

  • PingBack from http://geeklectures.info/2008/01/04/new-dfsr-data-restoration-script/

  • I know the script is unsupported, but I'm hoping someone might be able to help me work out why I get the following error when I run the script

    Line 88

    Char 1

    Error Object required: 'objXMLDoc.documentElement'

    Code: 800A01A8

    Source: Microsoft VBScript runtime error

  • Hi,

    Can you paste in this section from your script:

    '=======================================================================

    ' Section must be operator-edited to provide valid paths

    '=======================================================================

    ' Change path to specify location of XML Manifest

    ' Example 1: "C:\Data\DfsrPrivate\ConflictAndDeletedManifest.xml"

    ' Example 2: "C:\Data\DfsrPrivate\preexistingManifest.xml"

    objXMLDoc.load("C:\your_replicated_folder\DfsrPrivate\yourManifest.xml")

    ' Change path to specify location of source files

    ' Example 1: "C:\data\DfsrPrivate\ConflictAndDeleted\"

    ' Example 2: "C:\data\DfsrPrivate\preexisting\"

    SourceFolder = ("C:\your_replicated_folder\DfsrPrivate\preexisting\")

    ' Change path to specify output folder

    OutputFolder = ("c:\dfsr_repair_tree")

    '========================================================================

  • Hi,

    Thanks for your prompt response.  Below is the section copied from my script.  I have previously double checked all the paths, and they all work fine if copied into the run box.

    '=======================================================================

    ' Section must be operator-edited to provide valid paths

    '=======================================================================

    ' Change path to specify location of XML Manifest

    ' Example 1: "C:\Data\DfsrPrivate\ConflictAndDeletedManifest.xml"

    ' Example 2: "C:\Data\DfsrPrivate\preexistingManifest.xml"

    objXMLDoc.load("D:\Data\New Document Structure\DfsrPrivate\ConflictAndDeletedManifest.xml")

    ' Change path to specify location of source files

    ' Example 1: "C:\data\DfsrPrivate\ConflictAndDeleted\"

    ' Example 2: "C:\data\DfsrPrivate\preexisting\"

    SourceFolder = ("D:\Data\New Document Structure\DfsrPrivate\ConflictAndDeleted\")

    ' Change path to specify output folder

    OutputFolder = ("D:\Data\Restored Files")

    '========================================================================

  • Your script entries looked perfect - the only other time I've seen this error is when the XML file itself is damaged.

    A couple questions:

    1. How big is your conflictanddeletedmanifest.xml?

    2. Will it load into Internet Explorer with no errors?

  • Hi,

    It's 11 mb in size.

    It opens into IE without any errors, but IE does freeze up for 5-10 seconds immediately after I open it, before it renders the page.

  • That's very odd. Can you create a simple test RG/RF, add some data, delete the data on one server, go to the other server, modify the restore script to point to your test paths, and attempt to restore?

  • I created a new namespace, added some data, deleted one of the files and then changed the script and ran it.  It reads the XML file correctly and restored the file correctly.

    I was just browsing through the XML file and noticed when rendered in IE that it displays the following info at the bottom

    "The XML page cannot be displayed

    Cannot view XML input using XSL style sheet

    End tag 'ConflictAndDeletedManifest' does not match the start tag 'path'. Error processing resource"

    If I open it in firefox it says "XML Parsing Error: not well-formed"

    So I guess the problem was the XML file after all.  I'll have a play around and see if I can get it working.  Thanks for your help.

  • Thanks for the script.  I understand that it is not supported, "As Is", but I ran the script and seemed to get some of the folders back, but none of the documents.  Is there something I'm doing wrong? My script is below.

    ********************

    '==========================================================================

    '

    '

    ' NAME: RestoreDFSR.VBS

    '

    '  AUTHOR: NedPyle, EPS, Microsoft Corporation

    '

    '

    '  COMMENT: Disaster Recovery script for pulling DFSR data out of 'ConflictAndDeleted'

    '    or 'PreExisting' folders and putting it back into a usable directory tree,

    '    preserving paths, names, and security descriptor info.

    '

    '  USAGE: Replace the 3 variables in the "operator-edited" section below

    '         with valid paths. The Script will copy the contents of the source folder

    '         to a specified path, returning files to original names and adding back

    '         their folder structure at the time of deletion.

    '

    '         It is important to note that duplicate conflicts (i.e. multiple versions of

    '  the same file that were conflicted) will be restored with only the latest version.

    '

    '         Finally: this tool can only copy files that were preserved in ConflictAndDeleted

    '         by quota (by default, 660MB). If the quota prevented all files from being saved

    '         this script is not going to help for those that were trimmed out. The PreExisting

    '  folder does not have a quota so all data should be restorable.

    '

    '  VERSION HISTORY:

    '

    '  2.00 / 12/17/07 -

    '  Coalesced restoreconflicted.vbs and restorepreexisting.vbs into single script

    '      Multiple bugfixes, improved folder restore logic

    '

    '  1.01 / 09/25/06 -

    '         Whitespace bug fixed

    '

    '  1.00 / 08/25/06 -

    '  First working version

    '

    '  KNOWN ISSUES:

    '

    '  If the script halts processing with errors, there are typically two possible issues:

    '

    '  1) Your paths are incorrect in the "operator-edited" section

    '  2) Your XML file is corrupt and unreadable (We've seen this after disk failures)

    '

    '

    ' This script is provided "AS IS" with no warranties, and confers no rights.

    ' For more information please visit

    ' http://www.microsoft.com/info/cpyright.mspx to find terms of use.

    '

    '==========================================================================

    Dim Source

    Dim Dest

    Const quote = """"

    ' Startup XML

    Set objXMLDoc = CreateObject("Microsoft.XMLDOM")

    objXMLDoc.async = False

    ' Set File Move Environment

    Set objShell = WScript.CreateObject("WScript.Shell")

    '=======================================================================

    ' Section must be operator-edited to provide valid paths

    '=======================================================================

    ' Change path to specify location of XML Manifest

    ' Example 1: "C:\Data\DfsrPrivate\ConflictAndDeletedManifest.xml"

    ' Example 2: "C:\Data\DfsrPrivate\preexistingManifest.xml"

    objXMLDoc.load("e:\Shares\AGB\DfsrPrivate\ConflictAndDeletedManifest.xml")

    ' Change path to specify location of source files

    ' Example 1: "C:\data\DfsrPrivate\ConflictAndDeleted\"

    ' Example 2: "C:\data\DfsrPrivate\preexisting\"

    SourceFolder = ("e:\shares\AGB\DfsrPrivate\ConflictedAndDeleted\")

    ' Change path to specify output folder

    OutputFolder = ("e:\shares\AGB\")

    '========================================================================

    set objRootNodes = objXMLDoc.documentElement.ChildNodes

    For Each objRootNode In objRootNodes

     Set objChildNodes = objRootNode.ChildNodes

     For Each objChildNode in objChildNodes

          If objChildNode.nodeName = "Path" then

     StrFullPath = objChildNode.firstChild.nodeValue

          end if

          If objChildNode.nodeName = "Attributes" then

     FileorFolder = objChildNode.firstChild.nodeValue

          end if

          If objChildNode.nodeName = "NewName" then

     GuidName = objChildNode.firstChild.nodeValue

             If GuidName <> "" then

                 Length = Len(StrFullPath)

                 StrExtract = Mid(strFullPath, 7, Length-6)

                 Source = SourceFolder & GuidName

                 Dest = OutputFolder & strExtract

    if FileorFolder = 10 then

      ' It's a folder

              wscript.echo "CMD /C XCOPY " & quote & Source & quote & " " & quote & Dest & quote & " " & "/Q /H /R /X /Y /E /I /C"

      objShell.Run "CMD /C XCOPY " & quote & Source & quote & " " & quote & Dest & quote & " " & "/Q /H /R /X /Y /E /I /C /F",0,TRUE

    elseif FileorFolder = 30 then

      ' It's a folder

              wscript.echo "CMD /C XCOPY " & quote & Source & quote & " " & quote & Dest & quote & " " & "/Q /H /R /X /Y /E /I /C"

      objShell.Run "CMD /C XCOPY " & quote & Source & quote & " " & quote & Dest & quote & " " & "/Q /H /R /X /Y /E /I /C /F",0,TRUE

    else

      ' It's a file

              wscript.echo "CMD /C XCOPY " & quote & Source & quote & " " & quote & Dest & quote & " " & "/Q /H /R /X /C /Y"

      objShell.Run "CMD /C ECHO F | XCOPY " & quote & Source & quote & " " & quote & Dest & quote & " " & "/Q /H /R /X /F /Y",0,TRUE

    end if

             end if

          end if

     Next

    Next

    ***********

  • Thanks for the script.  I understand that it is not supported, "As Is", but I ran the script and seemed to get some of the folders back, but none of the documents.  Is there something I'm doing wrong? My script is below.

    ********************

    '==========================================================================

    '

    '

    ' NAME: RestoreDFSR.VBS

    '

    '  AUTHOR: NedPyle, EPS, Microsoft Corporation

    '

    '

    '  COMMENT: Disaster Recovery script for pulling DFSR data out of 'ConflictAndDeleted'

    '    or 'PreExisting' folders and putting it back into a usable directory tree,

    '    preserving paths, names, and security descriptor info.

    '

    '  USAGE: Replace the 3 variables in the "operator-edited" section below

    '         with valid paths. The Script will copy the contents of the source folder

    '         to a specified path, returning files to original names and adding back

    '         their folder structure at the time of deletion.

    '

    '         It is important to note that duplicate conflicts (i.e. multiple versions of

    '  the same file that were conflicted) will be restored with only the latest version.

    '

    '         Finally: this tool can only copy files that were preserved in ConflictAndDeleted

    '         by quota (by default, 660MB). If the quota prevented all files from being saved

    '         this script is not going to help for those that were trimmed out. The PreExisting

    '  folder does not have a quota so all data should be restorable.

    '

    '  VERSION HISTORY:

    '

    '  2.00 / 12/17/07 -

    '  Coalesced restoreconflicted.vbs and restorepreexisting.vbs into single script

    '      Multiple bugfixes, improved folder restore logic

    '

    '  1.01 / 09/25/06 -

    '         Whitespace bug fixed

    '

    '  1.00 / 08/25/06 -

    '  First working version

    '

    '  KNOWN ISSUES:

    '

    '  If the script halts processing with errors, there are typically two possible issues:

    '

    '  1) Your paths are incorrect in the "operator-edited" section

    '  2) Your XML file is corrupt and unreadable (We've seen this after disk failures)

    '

    '

    ' This script is provided "AS IS" with no warranties, and confers no rights.

    ' For more information please visit

    ' http://www.microsoft.com/info/cpyright.mspx to find terms of use.

    '

    '==========================================================================

    Dim Source

    Dim Dest

    Const quote = """"

    ' Startup XML

    Set objXMLDoc = CreateObject("Microsoft.XMLDOM")

    objXMLDoc.async = False

    ' Set File Move Environment

    Set objShell = WScript.CreateObject("WScript.Shell")

    '=======================================================================

    ' Section must be operator-edited to provide valid paths

    '=======================================================================

    ' Change path to specify location of XML Manifest

    ' Example 1: "C:\Data\DfsrPrivate\ConflictAndDeletedManifest.xml"

    ' Example 2: "C:\Data\DfsrPrivate\preexistingManifest.xml"

    objXMLDoc.load("e:\Shares\AGB\DfsrPrivate\ConflictAndDeletedManifest.xml")

    ' Change path to specify location of source files

    ' Example 1: "C:\data\DfsrPrivate\ConflictAndDeleted\"

    ' Example 2: "C:\data\DfsrPrivate\preexisting\"

    SourceFolder = ("e:\shares\AGB\DfsrPrivate\ConflictedAndDeleted\")

    ' Change path to specify output folder

    OutputFolder = ("e:\shares\AGB\")

    '========================================================================

    set objRootNodes = objXMLDoc.documentElement.ChildNodes

    For Each objRootNode In objRootNodes

     Set objChildNodes = objRootNode.ChildNodes

     For Each objChildNode in objChildNodes

          If objChildNode.nodeName = "Path" then

     StrFullPath = objChildNode.firstChild.nodeValue

          end if

          If objChildNode.nodeName = "Attributes" then

     FileorFolder = objChildNode.firstChild.nodeValue

          end if

          If objChildNode.nodeName = "NewName" then

     GuidName = objChildNode.firstChild.nodeValue

             If GuidName <> "" then

                 Length = Len(StrFullPath)

                 StrExtract = Mid(strFullPath, 7, Length-6)

                 Source = SourceFolder & GuidName

                 Dest = OutputFolder & strExtract

    if FileorFolder = 10 then

      ' It's a folder

              wscript.echo "CMD /C XCOPY " & quote & Source & quote & " " & quote & Dest & quote & " " & "/Q /H /R /X /Y /E /I /C"

      objShell.Run "CMD /C XCOPY " & quote & Source & quote & " " & quote & Dest & quote & " " & "/Q /H /R /X /Y /E /I /C /F",0,TRUE

    elseif FileorFolder = 30 then

      ' It's a folder

              wscript.echo "CMD /C XCOPY " & quote & Source & quote & " " & quote & Dest & quote & " " & "/Q /H /R /X /Y /E /I /C"

      objShell.Run "CMD /C XCOPY " & quote & Source & quote & " " & quote & Dest & quote & " " & "/Q /H /R /X /Y /E /I /C /F",0,TRUE

    else

      ' It's a file

              wscript.echo "CMD /C XCOPY " & quote & Source & quote & " " & quote & Dest & quote & " " & "/Q /H /R /X /C /Y"

      objShell.Run "CMD /C ECHO F | XCOPY " & quote & Source & quote & " " & quote & Dest & quote & " " & "/Q /H /R /X /F /Y",0,TRUE

    end if

             end if

          end if

     Next

    Next

    ***********

  • Hi,

    Do you have the issue if you remove the trailing backslash from

    OutputFolder = ("e:\shares\AGB\")

    So that it's instead:

    OutputFolder = ("e:\shares\AGB")

  • Thank you for the quick response and I apologize for the duplicate post.  And yes, I get folders, but no documents.

  • In the midst of the script there is a comment "NtFS_Pre-existing_See_Event_Log_" then the file name, is that relevant?

  • @ mdabney - you mean as it's running you see that? Sounds like you used to replicate data with FRS and someone deleted that folder within DFSR?

    If you actually look in the conflict manifest XML files, do you see any files, or is it just folders listed?

  • Yes, and you are probably correct about the deletion. Our network admin attempted to change the topology remotely while it was running and the .xml file does have files.