By: Robert Christ
This post is part 1 of a 2 part series
Part 2 can be found at: http://www.thesharepointblog.net/Lists/Posts/Post.aspx?ID=75 and takes this example, and implements it in a program called “Update All Site Collection Administrators In Farm.”
Traditional Manners of Manipulating and configuring SharePoint
When it comes to configuring a SharePoint farm or solution, there are a number of tools available to the modern SharePoint developer, each of which has its own strengths and weaknesses.
· The UI – Great for simple tasks, and giving visual context to the SharePoint task
· Stsadm – Well tested tool for manipulating SharePoint configurations one at a time, or through bat files.
· PowerShell – A great improvement over stsadm, allows for a much larger degree of flexibility and complexity
· SharePoint COM (Client Object Model) – Allows code manipulation of the farm from an external machine.
Today I would like to remind the SharePoint community of a fifth option:
· Manipulating SharePoint directly through a Console Application
Why would I bother with this option?
As developers, we like to reuse code whenever available. Tasks that are complicated, repetitive, or time consuming should be automated to save users, and developers’ time.
Of the first 4 options, if you have a complicated task, your best bet would be to write a reusable PowerShell script. This is a great option, and something the SharePoint community has embraced as a whole.
What I haven’t seen much of however, is the alternative option of directly manipulating SharePoint through the use of Console Applications. While it is possible this is generally taken as a given by the SharePoint community, I thought that perhaps creating a brief tutorial might be helpful for some of you out there. Unlike PowerShell, even the most basic SharePoint developer most likely has an intimate knowledge of the SharePoint object model, making this an easy option.
Far more importantly, this technique can be used as a test harness for any and all workflow, event handler, or timer job code, as it will directly interact with SharePoint, but without the (often considerable) extra lag time involved with debugging directly in or debug/deploying to SharePoint!
How to Manipulate SharePoint using the Object Model from a Console Application
Hopefully I will be able to load a pre-made project to this site for you to download, but just in case, I’ve listed the steps to create this project below. You should only ever have to do this once, as it will always be the same. Simply change the method call exampleMethod() to whatever you will use to manipulate SharePoint normally.
First, open up Visual Studio, and create a new Console Application Project using .Net 3.5.

Next, click Project in the Visual Studio drop down menus, and choose “Your Console Application’s Name Here” Properties.

Be sure to set the Build Platform Target to x64. Failure to do this step will, of course, result in an immediate error upon program launch on your x64 SharePoint server.
Next, right click References in the Solution Menu, and Add a reference to Microsoft.SharePoint , as you would to use the SharePoint Object Model in a workflow or event receiver.

Now open Program.cs, and add the following statements to the top of the file:
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Reflection;
Coding using the Object Model from a Local Console Application
In your main method, the very first thing you want to call is
static void Main(string[] args)
{
Assembly SharePoint;
bool correctMachine = checkSharePointComputer(out SharePoint);
if (!correctMachine)
return;
runSharePointScriptWithElevatedPrivliges();
}
Where checkSharePointComputer(out SharePoint) is defined as:
/// <summary>
/// Determines if SharePoint 2010 is installed on this computer
/// </summary>
/// <param name="SharePoint">The DLL file for Microsoft.SharePoint</param>
/// <returns>True or false depending on whether Microsoft.SharePoint was
/// found on the computer</returns>
private static bool checkSharePointComputer(out Assembly SharePoint)
{
try
{
SharePoint = Assembly.Load("Microsoft.SharePoint, Version=14.0.0.0, Culture=Neutral, PublicKeyToken=71e9bce111e9429c");
return true;
}
catch
{
Console.WriteLine("Unfortunately, SharePoint 2010 is not installed on "
+ "this machine.");
Console.WriteLine("This program must be run on a x64 OS with "
+ "SharePoint Server 2010 installed.");
Console.WriteLine("Enter any key to now quit.");
Console.ReadLine();
SharePoint = null;
return false;
}
}
Hopefully this function is self-explanatory, but just in case, checkSharePoitnComputer will search the local computer for a reference to Microsoft.SharePoint. Normally when running an application, if at runtime the computer cannot find the reference to Microsoft.SharePoint, the application will fail due to missing dependencies. By including this method in our project however, we simultaneously ensure that the console application will only be run on the computers with SharePoint installed (the machine to manipulate), and that it will fail gracefully if a user accidentally attempts to run it elsewhere.
Similarly, runSharePointScriptWithElevatedPrivliges should be defined as:
/// <summary>
/// Runs SharePoint code with elevated privliges
/// </summary>
private static void runSharePointScriptWithElevatedPrivliges
(string url)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
string result = exampleMethod(url);
Console.WriteLine(result);
});
}
where exampleMethod is can be pointed towards whatever code you would like to manipulate SharePoint with.
Remember, unlike when you run SharePoint code as a workflow or event handler, the code will be run as your local user, not the system or farm account. As such, you will almost certainly need to call your code from within this elevated privileges delegate. Be careful!
If you’ve gotten this far:
… then you’ve only got one last step to go. You’ll find that attempting to get an instance of SPSite or SPWeb in the traditional manner:
using (SPSite site = new SPSite(url))
{
using (SPWeb web = site.OpenWeb())
{
}
}
will not work from within a console application. Instead, you need to use:
//Opens Web application. Opening directly using SPSite() is not available in exe files
SPWebApplication webApp;
try
{
Uri b = new Uri(url);
webApp = SPWebApplication.Lookup(b);
}
catch (Exception ex)
{
return "Could not find the specified url" + ex.Message;
}
using (SPSite site = webApp.Sites[0])
{
using (SPWeb web = site.OpenWeb())
{
}
}
There you go! Now you can manipulate SharePoint exactly the same as if you were doing so from within a workflow, event receiver, Stsadm or PowerShell, but in a significantly faster manner than available with those first three options.
If you’re interested in seeing a basic example of this code in action, scroll to the top of the page, and follow the link to updateAllSiteCollectionAdministrators.
The entire code for this solution has been copy pasted below. Enjoy!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Reflection;
namespace SiteCollectionAdminChanger
{
class Program
{
static void Main(string[] args)
{
Assembly SharePoint;
bool correctMachine = checkSharePointComputer(out SharePoint);
if (!correctMachine)
return;
string url = "YOURURLHERE";
runSharePointScriptWithElevatedPrivliges(url);
Console.ReadLine();
}
/// <summary>
/// Determines if SharePoint 2010 is installed on this computer
/// </summary>
/// <param name="SharePoint">The DLL file for Microsoft.SharePoint</param>
/// <returns>True or false depending on whether Microsoft.SharePoint was
/// found on the computer</returns>
private static bool checkSharePointComputer(out Assembly SharePoint)
{
try
{
SharePoint = Assembly.Load("Microsoft.SharePoint, Version=14.0.0.0, Culture=Neutral, PublicKeyToken=71e9bce111e9429c");
return true;
}
catch
{
Console.WriteLine("Unfortunately, SharePoint 2010 is not installed "
+ "on this machine.");
Console.WriteLine("This program must be run on a x64 OS with "
+ "SharePoint Server 2010 installed.");
Console.WriteLine("Enter any key to now quit.");
Console.ReadLine();
SharePoint = null;
return false;
}
}
/// <summary>
/// Runs sharepoitn code with elevated privliges
/// </summary>
private static void runSharePointScriptWithElevatedPrivliges(string url)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
string result = exampleMethod(url);
Console.WriteLine(result);
});
}
private static string exampleMethod(string url)
{
//Opens Web application. Opening directly using SPSite() is not available in exe files
//unless using Microsoft.SharePoint.Client
SPWebApplication webApp;
try
{
Uri b = new Uri(url);
webApp = SPWebApplication.Lookup(b);
}
catch (Exception ex)
{
return "Could not find the specified url " + ex.Message;
}
using (SPSite site = webApp.Sites[0])
{
using (SPWeb web = site.OpenWeb())
{
return "success!";
}
}
}
}
}
By: Robert Christ