Migrating Wiki Pages Remotely – Part 01

I was doing some work recently where I needed to move a large volume (thousands) of Wiki Pages from one server to another. The problem was that while if I begged and pleaded, I probably could have gotten local admin access to the farms, I didn’t really want to go through that if I didn’t have to. I wanted to be able to manage the relocation of my Wiki Libraries from my client machine and not have to touch the server locally if I could help it. How do you do this kind of thing? Web Services of course… sounds simple right? Well, that’s what I thought until I gave it a try. As it turns out, it is very easy to use lists.asmx to pull all the data you want. You can do it for Wiki Libraries just like you would for any other list type.

In case you didn’t already figure this out, lucky you, I’ve done all the work for you already. If you are an adventurous or savvy developer, you could stop reading right here and go give it a shot. Otherwise keep reading and see how I made this all go. I have split up a much longer document into a series of posts where I will step through the different parts of the code and talk about the logic/etc behind them. I did this so that I was more reasonable on your RSS readers (my docx is 19 pages long). I will finish the final piece with a single post providing all of the code together.

I will say that some of the scenarios I had to deal with are not ones that I would expect many people to encounter. Some of the source servers I was working with had databases that had been around since Beta, even Alpha stages of SharePoint 2007. This situation led to a few things that just wouldn’t work using conventional methods. I don’t expect many readers will have to deal with these same things I ran into that I had to code around. I’ll be the first to say it—my code is a bit bloated as a result. However, I did want to share it in its entirety so you could benefit from seeing how I dealt with various problems. I would encourage you to hunt and peck my code any try the different code paths separately in your environment until you find what works for you instead of throwing everything at it at once.

Before I dig in, here are a few notes you should know and a screenshot of my final UI so that some of the object names will make a little more sense:

Note 1: I only cared about the current version of the Wiki Pages—so none of my code or methodologies will include handling history. This should be accessible though, and I see no reason why wouldn’t be able to migrate if you felt like writing the extra code.

Note 2: I was too lazy It was out of spec 🙂 to make this a multithreaded application, so I put all my logging on the TraceListener. You can use DbgView from sysinternals to watch the Trace.Write statement output fly by.

Note 3: When I use the lists.asmx GetListItems method, I am passing in the value in txtNumberRows because, otherwise we will use the number of rows configured in the view on the list. By default this is 100. If you have less than 100 Wiki Pages, this isn’t a problem. Otherwise it is. A workaround would be to alter the default view to return more rows and continue to pass null instead of txtNumberRows value.

Note 4: In the posts with commentary, I’ve removed all the action in the catch blocks—if you want to see my error tracing/etc, you can look in the final post. You also may notice that most of these code snippets aren’t full methods and don’t close out all of the braces/etc.

Note 5: Server1WS points to lists.asmx. Server1CopyWS points to copy.asmx. I created separate Server2 versions of these because at times I was using multiple at the same time and wanted them to be separate live objects in memory. This could be cleaned up—I thought it made it easier to follow the code if you were seeing it for the first time.

Note 6: Just as a generic disclaimer, as you might imagine this code and resulting tool is not considered production worthy. It was not tested and as a tool would be “unsupported” by Microsoft Product Support. I am sharing it simply to help save you some time in your own development efforts.


We will dive into some of the code with the next post.

Part 02:

Comments (19)

  1. nektioan says:

    Good timing! I was just looking to migrate a wiki from one sharepoint to another. I’ve tried the tool and it works great!

    You mentioned wiki page history. How complicated is it to also migrate this information? Is this history stored in another wiki field, or is it necessary to parse the ows_MetaInfo?

  2. dwinter says:

    As I recall, it wasn’t directly exposed in what was returned by the web service–however, much like what was recorded as <#ID>.000, versions would be maintained in the same fashion.  .000 internally referring to the first, .001 the second/etc.  The webservice was returning the current (latest) version in the WikiField, but if you targetted a specific version, I think you could get it.  It definately would be accessibly via local OM code, unfortunately–not everything is accessible via Web Services and I didn’t fully bake that part of the idea (recall my notes on the first post).  None-the-less, based on how this is structured, I think the bigger challenge would be finding what the current version number is and determining if we have storage of x number of past edits available.  I’m sorry I can’t give a more clear answer right now–but I am travelling.  If you can wait ~1 week, I’ll dig in a little further.

  3. I&#39;ve known Dan Winter for years now, back when I was a Microsoft Rapid Response Engineer I would

  4. pettan7514 says:


    Great tool! No doubt. However, I have run into a problem. I’m getting:

    Item z:row Exception: Object reference not set to an instance of an object.

    Do you have any idea what could be wrong?

    I’m running WSS 3.0 SP1

    Thanks Peter

  5. dwinter says:

    Can you provide some more detail on what you had filled out, what is actually at those locations (what kind of site/list), and perhaps the callstack from the error?

  6. udhakal says:

    I tried running this I am getting this error;

    Item z:row Exception: Object reference not set to an instance of an object.

    Copy routine completed, but without success.

    Do you have any idea what could be wrong?

    My source add is :


    Destination address is:


    I tried creating a wiki in destination address too  and made that wiki empty

    But still i get that error

    Any Idea:

    I am looking for another tool which can be used to migrate Twiki Sites to Sharepoint Wiki If you know anything about these please i would be very happy to hear that

  7. Mihail Stacanov says:

    Thanks a lot for this great utility. I've tried to find a solution for migrating wiki from one site collection to another and your solution saved my time.