Tuesday 23 August 2011

Extending STSADM commands in Sharepoint 2007


Hi,
STSADM commands are a rich set of tools to carry out various administrative tasks in any sharepoint environment. Microsoft provides various out of box commands to carry out such tasks. This can be referred at :
However what to do if we need to carry out some task which is not provided by these out of box STSADM commands. In this article I will show you how to create your own STSADM commands. These are very simple to create and deploy. We will create a STSADM command that will provide us webTemplate and webTemplate used by a site, our command will look like STSADM –o getwebtemplate –url . Lets start doing this by creating a .Net assembly project in C# I am using visual studio here. When the project is ready to be worked on follow these steps:
1. Add a reference to Microsoft.SharePoint.dll this can be located here C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\ISAPI
2. Add these references in your code:
using Microsoft.SharePoint;
using Microsoft.SharePoint.StsAdmin;
using System.Collections.Specialized;
We will use SPWeb and SPSite objects in our code hence the first refernce is required. We will extend an interface
[SharePointPermissionAttribute(SecurityAction.InheritanceDemand, ObjectModel = true)]
[SharePointPermissionAttribute(SecurityAction.LinkDemand, ObjectModel = true)]
public interface ISPStsadmCommand

You can get more information about this interface here:
Hence to extend this interface we need to use the second reference using Microsoft.SharePoint.StsAdmin;

We have included using System.Collections.Specialized because we are going to use StringDictionary.
Now here is our entire code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.StsAdmin;
using System.Collections.Specialized;

namespace RahulSTSADM
{
    public class RahulSTSADM :ISPStsadmCommand
    {
        protected string GetHelpMessage(string message)
        {
            return "-url <The full url of the site whose tempalte details you want to know>" ;

        }
        protected int Run(string command, StringDictionary keys, out string result)
        {
            if (!keys.ContainsKey("url"))
            {
                throw new InvalidOperationException("The url of the site is not provided");
            }
            string url = keys["url"];

            try
            {
                using (SPSite site = new SPSite(url))
                {
                    SPWeb web = site.OpenWeb();
                    string webTemplate = web.WebTemplate;
                    int webTemplateID = web.WebTemplateId;
                    web = null;
                    result = "The site at the url " + url + " is using the template " + webTemplate + " and the template ID is " + webTemplateID.ToString();

                }
                return 0;
            }
            catch (Exception e)
            {
                throw new InvalidOperationException(e.Message);
            }}

string ISPStsadmCommand.GetHelpMessage(string command)
{
return this.GetHelpMessage(command);
}
int ISPStsadmCommand.Run(string command, StringDictionary keyValues, out string
output)
{
return this.Run(command, keyValues, out output);
}

        }

      
    }

Now we will go through the code.
I have written this method:
        protected string GetHelpMessage(string message)
        {
            return "-url <The full url of the site whose tempalte details you want to know>" ;

        }
This is used by the STSADM command line utility to provie help message about the operation. If you execute STSADM –help getwebtemplate you will get the output as -url <The full url of the site whose tempalte details you want to know> . Hence this method is used to return the help text that is being return by the STSADM utility.
Now the next method is very important where real action takes place. Have a look at the syntax:
protected int Run(string command, StringDictionary keys, out string result)
In the above method the StringDictionary object is very important this stores the values of all parameters we supply in the command. Hence in the next section of this mehod we first verify whether it contains the necessary parameter or not. If not we are throwing an exception that will halt the execution of this command. The result is the string message that we provide once the command execution is completed.
No once the parameters are verified we are moving to the try block where I have placed the logic to get the webtemplate of the site. We have wrapped this in try catch block to show exception to the command window if anything goes wrong.
No this assembly needs to be signed and then should be deployed to the GAC. Now to use this as a STSADM command we need to create an xml file. The contents should be like this:
<?xml version="1.0" encoding="utf-8" ?>
<commands>
<command
name="getwebtemplate"
class="RahulSTSADM.RahulSTSADM, RahulSTSADM, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=f7d7392d7f65f4ef" />
</commands>
Now this should be saved at this location C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\CONFIG. The filename should be stsadmcommands.getwebtemplate.
Now you are ready to go with it.
I hope this will help you out.
Thanks,
Rahul Rashu

Friday 12 August 2011

How to copy lists greater than 10 MB containing attachments in sharepoint 2007

Hi,

I have seen people struggling to copy lists among different sites because their size is more than 10 MB and it contains attachments. This 10MB size is a hard limitation for creating list templates, hence list templates can not be created with data in such cases.There is an option of create a blank template and once restored to the destination site as list use spreadsheet views to transfer the data, however this can not be done with the list containing attachments since attachments can not be copied through spreadsheet. So to copy such lists we can follow these steps:

1. If the list is to copied in any site within the same site collection:
a) Save the list as a template without data.
b)Create a list at the destination site using this template.
c) Use site manager to copy the data. To do this add _layouts/sitemanager.aspx to the URL of your source site.
d) This will open up the site manager(Manage content and structure).Now in the left panel you will find t\a node in the broken site representing your site. You need to reach to your list in this panel and once you reach there click on it.
e) This will now show up your list items in the right panel. Now you can select these items and then you can go to action --> Copy.
f) Now a pop up window will open that will again enlist nodes of all sites in the site collection. You need to reach the site where your destination blank list is created and also to the destination blank list.
g) Once you reach there click on it and allow this pop up to reload.
h) Then you need to click on OK and done.

2. When you are copying the list between 2 sites in different site collection:
a) In this case some additional steps needs to be done.
b) Take STSADM export of the source site. Refer this:http://technet.microsoft.com/en-us/library/cc262759(office.12).aspx
c) Now import this in somewhere in the destination site location:
You can refer this http://social.technet.microsoft.com/wiki/contents/articles/copy-site-content-between-2-sites-based-on-different-templates.aspx
d) Now you can follow the steps for copying as described in the first step.
e) Once you are completed you can delete this copied site.

I hope this will help you out.

Thanks,
Rahul Rashu


Thursday 11 August 2011

Apply custom mater pages to all subsites in a site collection in sharepoint 2007

Hi,

I have seen people trying to find out the ways to apply custom master pages created in all sites in a site collection.

This many ways like a feature can be defined at site collection level that will apply the pages to all subsites in the site collection when activated or a console application can be designed that will carry out the changes. Here I am sharing my code to do the same via a console application. This code can be used in feature receiver as well with some minor changes. This takes the site collection URL as input and changes the master page accordingly.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;

namespace ApplySameMasterpage
{
    class Program
    {
        static void Main(string[] args)
        {
            String siteUrl = Console.ReadLine();
            using (SPSite site = new SPSite(siteUrl))
            {

                foreach (SPWeb web in site.AllWebs)
                {
                    //The below line is to update site master page
                    web.CustomMasterUrl = "/_catalogs/masterpage/YourMasterPage.master";
                    //The below line is to update system master page
                    web.MasterUrl = "/_catalogs/masterpage/YourMasterPage.master";
                    web.Update();
                }

            }
        }
    }
}

I hope this will help you out.

Thanks,
Rahul Rashu

Wednesday 10 August 2011

List of all site administrators in a sharepoint 2007 farm

Hi All,

I have seen people trying to find out a way to enlist all site administrators of all subsites in their environment.
There is no out of box solution to achieve this. This is a very easy task to be done via object model of sharepoint.

I am sharing my code of a console application that will do the same. This just needs to be executed and no inputs  are required to be provided


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
namespace YourNameSpace
{
    class Yourclassname
    {
        static void Main(string[] args)
        {
            SPFarm farm = SPFarm.Local;
            SPWebService webService = farm.Services.GetValue<SPWebService>("");
            foreach (SPWebApplication webApplication in webService.WebApplications)
            {
                foreach (SPSite site in webApplication.Sites)
                {
                    Console.WriteLine("The Site Owner for the Site Collection " + site.Url + " is" + site.Owner.LoginName +"\n");

                    using (site)
                    {
                        foreach (SPWeb web in site.AllWebs)
                        {
                            SPUserCollection webAdministrators = web.SiteAdministrators;
                            Console.WriteLine("Now processing the site named " + web.Title + " at the URL " + web.Url);
                            foreach (SPUser user in webAdministrators)
                            {
                                Console.WriteLine(user.LoginName + "\n");
                            }

                        }
                    }
                }
            }
            Console.ReadLine();


        }
    }
I hope this will help you out.
Thanks,
Rahul Rashu

Tuesday 9 August 2011

Site content copying between 2 sites based on different templates

Hi All,

I have seen people troubling for copying content from a site to another site when both the sites are based on different templates. This is not possible with STSADM export/import command since it requires source and destination sites to be based on same template.

I will explain a workaround that will require some extra effort but will work for you. I will explain this with this example:

I have two site collections A and B both have subsites A1 and B1 respectively. As per the requirement A1 and B1 are based on different templates and I want to copy data from A1 to B1. I will follow these steps:

1. I will export the contents from site A1 by suing STSADM export. I will use this for reference http://technet.microsoft.com/en-us/library/cc262759(office.12).aspx
2. I will import this content to some site under site collection B say B2 by following command:
STSADM -o import -URL http://B/B2 -filename ExportFileFullLocation
Note:- For the execution of this command there is no requirement for the site B2 to be available at the destination location during the execution it will be created automatically.
3. I will use site manager now to copy the lists, libraries etc from B2 to B1. Once completed I will delete B2 site.

This will solve this issue.

I hope this will help you out.

Thanks,
Rahul Rashu

Wednesday 3 August 2011

Site copying approaches using STSADM commands and site manager in sharepoint 2007

Hi,

Often I have seen people trying to find the correct copying approaches to be used to sites from one location to other in Sharepoint 2007.


1. Use site manager to copy down the site from one location to other. This process can be used only if the source and destination sites are in the same site collection
Process:
a) Type this in the URL of your subsite's URL  /_layouts/sitemanager.aspx. For example if I have the subsite URL as http://rahulsite/subsite/Pages/default.aspx it should be http://rahulsite/subsite/_layouts/sitemanager.aspx .

b) There will two panels in this result page the left panel and the right panel. The left panel will be consisting of   nodes representing sites and the contents within them. You will find the node of the subsite in the previous step is selected. Just click on that and select copy option this will open up a dialog box where you need to select the location where you want the site to be copied. For example if you want your site to be copied at http://rahulsite/subsite1/subsite then you need to select the node of the site http://rahulsite/subsite1 .

c) Once you have selected the node wait for the dialog box to reload itself. Do not do anything till it reloads completely.

d) Now simply click on OK and then your site will be copied over to the next location.

The advantage of this approach is that the lists column data "Created By", "Modified By","Created date" etc remains intact and does not show the values as if they are just created. The disadvantage is that using sitemanager  creates long running queries and can cause performance issues, hence it should be carried out during off business hours only. The detailed logs of these operations can be obtained from Long running operations status list created at the top level site of the site collection. This list is a hidden list and you can reach out to this by directly typing the name in the URL. For example if my top level site is http://rahulsite/top I will enter as http://rahulsite/top/long running operation status.

2. Use STSADM export/import commands for copying of the site: This is a really very good method since it does not copy down the GUIDs and it creates new GUIDs after import. The syntax can be referred at

http://technet.microsoft.com/en-us/library/cc262759(office.12).aspx
http://technet.microsoft.com/en-us/library/cc261866(office.12).aspx

This method can be applied to copy the entire site collection as well as subsite.
There is a limitation in this method such that the template used by the source and destination site must be same. However while copying subsite if the destination site does not exist then during import command it creates the subsite automatically. However this is not the case when importing a site collection, henec in thie case an empty site collection has to be created first, this can be done via STSADM createsite refer the syntax at http://technet.microsoft.com/en-us/library/cc262594(office.12).aspx
Do not use template flag in the command. After this import can be carried out in the created site collection.

3. STSADM backup/restore operation:
This method can be only applied at the site collection level. This can not be used to copy subsites.
This command has a limitation of copying only 25 GB of data hence it is not suitable for huge site collections and can cause timeout errors. Another disadvantage is that while  taking the backup it puts read only lock to the site collection hence this operation must be carried out during non business hours. The another disadvantage is that during backup it also takes the GUIDs of all items and same is applied to the destination site, hence there are always chances of errors coming during user operations. Application pool recycle is a temporary solution for these errors. The syntax of these commands can be referred at

http://technet.microsoft.com/en-us/library/cc263441(office.12).aspx
http://technet.microsoft.com/en-us/library/cc262087(office.12).aspx

Thanks,
Rahul Rashu