Sometimes we need to process all webs in a site collection, as you want to do some quick fixes in the web. Few weeks back my manager asked me to do some fixes in the list items exists in all the webs in the site collection. There were about 30,000 webs in the site collection and I was looking for some kind of script that will be efficient. The usual way of looping through all webs might be using some recursive way, as shown below.

//Starting point  public void ProcessAllWeb(SPSite site)  {      using (var web = site.RootWeb)      {          ProcessWebRecursive(web);      }    }    //Recursive method  private static void ProcessWebRecursive(SPWeb web)  {      //do some processing      //web.Lists["listName"].ItemCount        foreach (SPWeb subWeb in web.Webs)      {          using (subWeb)          {              ProcessWebRecursive(subWeb);                      }      }    }

Code Snippet 1: Recursive way of processing all webs in the site collection (Not optimized)

In the recursive way of processing all webs, there will be more than one SPWeb instance alive in memory. In the above code snippet, when the method ProcessAllWeb is invoked it’ll call the recursive method ProcessWebRecursive. The recursive method will keep calling the subwebs while keeping the parent web alive.


While I was writing the code, I was wonder if there’s any way of processing only one web non-recursively. So my intention was to open only one web in memory at once. And then I found it. You can get all web Url(including all subwebs at all level) using SPSite.AllWebs.Names. The following code snippet shows the efficient way of processing all webs in the site collection:

public void ProcessAllWeb(SPSite site)  {      string[] allWebUrls = site.AllWebs.Names;      foreach (string webUrl in allWebUrls)      {          using (SPWeb web = site.OpenWeb(webUrl))          {              //process web          }      }  }

Code Snippet 2: Process all webs one by one (Optimized for large number of webs)

Using the code snippet shown in figure 2, you just open one web at a time in memory for processing. The trick here is ‘SPSite.AllWebs.Names’ which will return all the (I mean it!) subwebs (including children and their children and so on) as a result. If you have thousands of webs under a site collection (and if it’s production), you should care about performance issue.

Posted by Sohel Rana at 5:39 AM 2 comments

Please follow and like us: