Showing posts with label Backup. Show all posts
Showing posts with label Backup. Show all posts

Monday, November 18, 2013

How to restore site collection from higher Sharepoint version

Sometimes you may face with situation that bug is only reproducibly on production, but not e.g. on QA or on your local development environment. Such problems are much harder to troubleshoot. Often they are caused by the content which exist only on production. And if troubleshooting directly on production is problematic (e.g. if you don’t have remote desktop access to it), you should get backup of site collection or whole content database, restore it on local dev env and try to reproduce bug here. But what to do if you have lower Sharepoint version on you local environment, than on production? Of course it is better to have the same versions, but world is not ideal and sometimes we may face with such situation. In this post I will show the trick of how to restore site collection from the higher Sharepoint version. Before to start I need to warn that this is actually a hack and you should not rely on it. There is no guarantee that it will work in your particular case, because new Sharepoint version may have different schema, incompatible with previous one (that’s why standard way is not allowed).

Ok, suppose that we have site collection backup, which is created with Backup-SPSite cmdlet:

Backup-SPSite http://example1.com -Path C:\Backup\example1.bak

We copied it on local environment and want to restore it with Restore-SPSite:

Restore-SPSite http://example2.com -Path C:\Backup\example1.bak –Confirm:$false

(Here I intentionally used different urls for source and target sites in order to show that it is possible to restore site collection to the different url). If we have lower Sharepoint version on the local environment we will get unclear nativehr exception, which won’t say anything. But if we will make our logging verbose and check Sharepoint logs, we will find the following error:

Could not deserialize site from C:\Backup\example1.bak. Microsoft.SharePoint.SPException: Schema version of backup 15.0.4505.1005 does not match current schema version 15.0.4420.1017.

(Exact version number is not important. For this post it is only important that source version 15.0.4505.1005 is higher than target version 15.0.4420.1017).

What to do in this case? Mount-SPContentDatabase also won’t work because of the same reason, i.e. content database backup also won’t work. In this case we can either update our environment (and you should consider this option as basic) or go by non-standard way.

For non-standard way we will need hex editor. At first I thought that site collection backup is regular .cab file, so it will be possible to uncompress it, edit text files inside it and compress back (I described this trick in this post: Retain object identity during export and import of subsites in Sharepoint into different site collection hierarchy location), but this is not the case with site collection backups made with mentioned cmdlets. They look like regular binary files. So we will need some hex editor for modifying it. I used HxD hexeditor, but you can use any other as well.

If we will open backup file in it and will try to find the version, which we got from error message from the log, we will find that it is located in the beginning of the file:

image

The good thing is that version is stored only once. So we will change source version to the target in the hex editor now:

image

Now save it and run Restore-SPSite again. This time restore should work. Hope that this trick will help someone. But remember that it is hack and use it carefully.

Saturday, April 13, 2013

Script for copying and archiving files to zip for making regular backups in cloud using built-in Windows features

Often we need to backup some files on the servers on regular basis. There are 2 important things about backups which you should keep in mind and use:

  • store backups on another server (not on the same where files are located);
  • test restore scenario.

In order to store backups on another servers you may use online storages, like box.com, dropbox, Google drive, MS SkyDrive and others. Also many cloud hosting providers have own backup solutions, for example Rackspace Cloud Backup, which requires installation of additional backup agent on the server (it is free). It is really convenient solution, because you don’t need to have separate server image which is not cheap. However cloud storages are also not free and in most cases you have to pay as much as many megabytes you use. So in order to reduce costs at first you need to take care about deleting old backups from the cloud. Some cloud providers have own solutions for it. E.g. currently Rackspace Cloud Storage contains 3 options to delete old backups:

  • store backups 30 days;
  • store backups 60 days;
  • store backups infinitely.

Also some backups software have option to delete files from backups using configurable rules. At second you need to decrease file size which is stored in the cloud storage. Many backup programs also can do that, but it can be done only by using Windows built-in features. In order to do it you may use simple cmd script which copies original file from its folder to folder for backup (in order to not affect work of the programs which use this file) and archives it to zip:

   1: xcopy C:\source_folder\source_file.dat C:\target_backup_folder\temp /y
   2: CScript zip.vbs C:\target_backup_folder\temp C:\target_backup_folder\backup.zip

As you can see it copies file using xcopy command (line 1) and then packages it to zip archive (line 2) using second script zip.vbs. If you will google for this script you will find many references, however not all of them work. Here is the script which works for me:

   1: Set Args = Wscript.Arguments
   2: source = Args(0)
   3: target = Args(1)
   4:  
   5: ' make sure source folder has \ at end
   6: If Right(source, 1) <> "\" Then
   7:     source = source & "\"
   8: End If
   9:  
  10: Set objFSO = CreateObject("Scripting.FileSystemObject")
  11: Set zip = objFSO.OpenTextFile(target, 2, vbtrue)
  12: ' this is the header to designate a file as a zip
  13: zip.Write "PK" & Chr(5) & Chr(6) & String( 18, Chr(0) )
  14: zip.Close
  15: Set zip = nothing
  16:  
  17: wscript.sleep 500
  18:  
  19: Set objApp = CreateObject( "Shell.Application" )
  20: intSkipped = 0
  21:  
  22: ' Loop over items within folder and use CopyHere to put them into the zip folder
  23: For Each objItem in objApp.NameSpace( source ).Items
  24:     If objItem.IsFolder Then
  25:         Set objFolder = objFSO.GetFolder( objItem.Path )
  26:         ' if this folder is empty, then skip it as it can't compress empty folders
  27:         If objFolder.Files.Count + objFolder.SubFolders.Count = 0 Then
  28:             intSkipped = intSkipped + 1
  29:         Else
  30:             objApp.NameSpace( target ).CopyHere objItem
  31:         End If
  32:     Else
  33:         objApp.NameSpace( target ).CopyHere objItem
  34:     End If
  35: Next
  36:  
  37: intSrcItems = objApp.NameSpace( source ).Items.Count
  38: wscript.sleep 250
  39:  
  40: ' delay until at least items at the top level are available
  41: Do Until objApp.NameSpace( target ).Items.Count + intSkipped = intSrcItems
  42:     wscript.sleep 200
  43: Loop
  44:  
  45: 'cleanup
  46: Set objItem = nothing
  47: Set objFolder = nothing
  48: Set objApp = nothing
  49: Set objFSO = nothing

It has 2 parameters: first is folder which has to be archived and second is path to output zip file. Unfortunately I found it quite long time ago and can’t provide the link to the original site, where I found it. But all credits goes to its author.

After that you need to setup scheduler task which will run this cmd script by schedule, e.g. daily. And the remaining thing is to setup copy of zip archive to your cloud storage. Using this technique you will be able to reduce the costs which you have to pay for storing backups in the cloud.