How to create a browser cache save URL to a javascript or css file in SharePoint

on Monday, March 29, 2010

How to create a browser cache save URL to a javascript or css file in SharePoint

Often it is necessary to ensure that updates to files on the server get populated to the client asap. Especially when it comes to dependencies to custom javascript of CSS files and server controls.

SharePoint itself does this by adding a query string to some of its vital Javascript files. E.g.:


Whenever the core.js file changes on the server a new query string value is generated. That allows browsers to cache the file as long as the file does not change on the server.

Today I got the question if it is possible to utilize the same method for custom js and css files. The answer is yes.

SharePoint provides the functionality to generate browser cache save Urls for such files if they reside inside the _layouts directory or one of it's localized subdirectory using the following method:

public static string Microsoft.SharePoint.Utilities.SPUtility.MakeBrowserCacheSafeLayoutsUrl(string name, bool localizable)

The first parameter needs to be the filename without a path (e.g. test.css) the second defines if the file resides in a language specific subdirectory or directly in the _layouts directory.

The following code will (e.g.) create the output below for german locale:

string saveUrl = Microsoft.SharePoint.Utilities.SPUtility.MakeBrowserCacheSafeLayoutsUrl("my-own.js", true);


SharePoint Caching

Bring Cache

Depending on your user base you may care very little about how caching works in SharePoint. But whether you plan on using it or not, you should at least know it's there and that it takes very little effort to turn it on.

Remember that almost everything in SharePoint resides in the content database. This coupled with the fact that opening a database connection is an extremely expensive operation means that there's potentially a lot more capacity to be had from a SharePoint site by simply enabling caching.

In my experience running the Microsoft Web Application Stress Tool on test SharePoint sites, most sites running caching profiles were able to achieve 33% more requests per second that those using no caching at all. That's a LOT more capacity to be had, and best of all it's free (you've already paid a lot of money for MOSS).

To enable Page Output Caching you need to turn on both the Office SharePoint Server Publishing Infrastructure feature in the Site Collection and the Office SharePoint Server Publishing in the sub site. Disk Caching is turned on through the web.config.

Page Output Caching

Page Output Caching works a lot like ASP.NET page output caching, allowing you to cache pages in memory for a certain period of time and also maintain many cached versions of pages based off of Browser Type, Query String, HTTP Header, or some custom function that you write and implement in your pages. It's quite flexible.

You start off by defining Caching Profiles in Site Settings (that is, how you want to determined if something should be cached) and then assigning profiles to either of Authenticated or Anonymous users as they visit your site. For instance, you could choose to cache pages for anonymous users and not cache pages for authenticated users.

By default Cache Profiles inherit down to sub sites just like security, and like security you can change the inheritance at any sub site along the way.

Disk Caching

The other type of caching is Disk Caching which simply stores assets that you would normally fetch from the content database on disk. Disk Caching and Page Output Caching aren't mutually exclusive and actually marry quite well together. To enable disk output caching all you really need to do is open up the web.config for the site and change the BlobCache key to look like below:

<Blobcache location="C:\blobCache" path="\.(gif|jpg|png|css|js)$" maxSize="10" enabled="true" />

It's worth mentioning that path is a regular expressions of file types to cache to disk and maxSize is measured in gigabytes. The location is of course where these files will be persisted to disk.

Some Thoughts

I would strongly encourage you to enable caching schemes one or more of your SharePoint sites to try it out. Those that make the best candidates (stand to gain the most performance) are those that have a lot of users and have anonymous access turned on for the entire site collection (usually synonymous with public facing sites). If you think you're viewing a cached version of a page and you want to see the real content you can always suffix the query string with a nocache=1. IE. http://somedomain/Pages/default.aspx?nocache=1 displays the non cached version of default.aspx for the somedomain site.

So there it is. Enjoy your free performance gains. Like G.I. Joe says: "Knowing is half the battle."

Hide New Icon or Change the Duration SharePoint

on Friday, March 19, 2010

Use the command

Hide the Icon
stsadm -o setproperty -pn days-to-show-new-icon -pv 0 -url http://machinename/sites/teamsite.

Change the duration from default "2" days to "10"

stsadm -o setproperty -pn days-to-show-new-icon -pv 10 -url http://machinename/sites/teamsite.

Get All the Checkedout documents sharepoint

on Monday, March 15, 2010

using Microsoft.Office.Server.Search.Query;


ResultTableCollection rtc = null;
DataTable retResults = new DataTable();


string fullTextSql = "SELECT ModifiedBy,Title,owsCheckoutUser,FileExtension,owsFileLeafRef,Path FROM SCOPE() WHERE owsCheckoutUser IS NOT NULL"


 using (SPSite site = new SPSite(http://servername))

                    using (FullTextSqlQuery query = new FullTextSqlQuery(site))

                        query.QueryText = fullTextSql;
                        query.ResultTypes = ResultType.RelevantResults;

                        query.RowLimit = rowLimit;
                        rtc = query.Execute();

                        if (rtc.Count > 0)
                            using(ResultTable relevantResults = rtc[ResultType.RelevantResults])

                                retResults.Load(relevantResults, LoadOption.OverwriteChanges);


Mange WebPart Resources (Linked vs Embedded)

on Friday, March 12, 2010

One of the most common questions I get in class and see in the forums is how best to deal with Web Part resources. By resources, I mean those necessary files that your Web Part depends on. These include JavaScript files, images, CSS, Flash, or even Silverlight apps. With the packaging and deployment model of SharePoint, it may be challenging to figure out where to store and how to reference these files. This article will overview your deployment options and give you enough information to make the best choice for your resource needs.

Linked or Embedded

With resource files, you have two basic options: linked or embedded. Linked means your Web Part will point to the file that lives somewhere in the file system. This is the most common approach. Embedded means you store the actual resource file inside your Web Part assembly. While less common, this can be very useful in many cases. We’ll look at each of these in more detail.

Linked Resources

Linked resources work best if you’ll need to modify the resource file separately from the Web Part. For example, say your Web Part references a JavaScript file and you continually need to tweak it and don’t want to recompile and redeploy the Web Part. If you link to it, it’s easy to change, and no changes to your Web Part are necessary. When working with linked resources, SharePoint provides you two primary options.

  1. Store the resource in a virtual directory such as _wpresources (this points to C:\Program Files\Common Files\microsoft shared\Web Server Extensions\wpresources)
  2. Store the resource with the Web Application inside the inetpub\wwwroot\wss\VirtualDirectories\<80>\wpresources

For option 1, you should make sure your Web Part assembly is deployed into the GAC. This is necessary since the _wpresoures virtual directory is used across each SharePoint Web Application. We call this Farm-level scope.

For option 2, you should make sure your Web Web Part assembly is deployed in to the bin folder for the Web Application. We call this Web-Application scope.

That said, you choose which wpresources folder based on the scope of your Web Part. For both options, you’ll be placing your files inside a sub folder to keep them separate from other files in other Web Parts. The sub folder name needs to be the namespace of your project. For example, with Web-Application scope, it might go here: inetpub\wwwroot\wss\VirtualDirectories\80\wpresources\namespace.

Ok, so you’ve chosen the appropriate folder based on the scope. How would you then reference this file within your Web Part code? It’s actually pretty easy and would look like this for a JavaScript file. (Note: this code can be placed in the CreateChildControls method for the Web Part.)

//Path to resource.  This is used for a web part deployed into the GAC (Option 1)
string scriptUrl = "~/_wpresources/namespace/file.js";

//Path to resource.  This is used for a web part deployed into the bin folder (Option 2)

string scriptUrl = "~/wpresources/namespace/file.js";

//Reference Script for web page
Page.ClientScript.RegisterClientScriptInclude ("file.js", scriptUrl);
Be careful, as these are very similar. You’ll notice for the first one, that you specify _wpresources (with an underscore). Also, make sure you replace namespace with the actual namespace for your Web Part project. For an image, it would work like this:
Image myImage = new Image();
myImage.ImageUrl = "~/wpresources/namespace/image.jpg";


The last important detail when using linked resources is how should you deploy these files? First off, you should be using SharePoint Solutions to deploy your code. You are doing this, right? Inside the Solution manifest.xml file, there are specific tags to deploy these kinds of resources. The schema looks like this:

<Assembly Location="Namespace.dll" DeploymentTarget="WebApplication">   

      <ClassResource Location="file.js"/>
      <ClassResource Location="image.jpg"/>

Here is where you can see that the DeploymentTarget attribute matches the scoping option. In this sample above, it is WebApplication scoped (option 2). To deploy into the GAC, replace this with GlobalAssemblyCache. To learn more about the schema inside this file, see this link.

Now that you have a good grasp on linked resources, let’s take a closer look at those that are embedded.

Embedded Resources

Embedded resources are physically stored within the Web Part .DLL file. In one way, this is nice as you can always be assured that the resources and the Web Part stay together. The drawback is that if you need to change a resource, you must recompile and deploy an updated version of your Web Part. When the client needs the resource, it is dynamically extracted from the .DLL and provided. You’ll see how.

To use an embedded resource, there are three things you need to do. The first is that you need to add the resource file to the project and mark is as an Embedded Resource. This is done via the Build Action setting inside Visual Studio as shown here.


The second thing you need to do is declare this resource inside the AssemblyInfo.cs file for your Web Part project. This is an easy one-liner as shown:

[assembly: System.Web.UI.WebResource("namespace.file.js", "text/javascript")]

The parameter string that is used consists of the Web Part namespace followed by the filename of the resource. The next parameter is just the MIME type. If this were an image, it could be image/jpg.

The third thing step is make sure you extract the Url to the resource. This is also one line of code as shown:

string scriptUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(), "namespace.file.js");

As with linked resources, you’ll then deliver this script to the page with a call to RegisterClientScriptInclude within CreateChildControls. As you would probably guess, the string here must match the name in the AssemblyInfo.cs file. As written here, the resource files need to exist in the root folder of the Web Part project. (Note: technically you don’t need to precede the file with the namespace as long as the string is unique within the project. The common convention, however, is with the namespace).

You might be curious how this actually works from the browser’s perspective. Well, what gets delivered to the browser is a link to a special, in-memory page called WebResource.axd along with a querystring to uniquely identify this specific resource. In HTML, it looks something like this:

<script src="/WebResource.axd?d=ZPJuqJGGI6qgSKsEa2PfIw2&amp;t=633527425956801634" 

This is how it dynamically finds the resource file, extracts it from the Web Part DLL, sets the content type, and then delivers it to the browser. Pretty cool.


In this post, you have seen how to both link to and embed Web Part resources. Each has its own advantages and disadvantages, mostly boiling down to whether you need to maintain the resource separately from the Web Part. In both cases, the resource file can be cached, so there is little performance difference from each option. Feel free to use one of these two approaches for your next web part.

SharePoint Usage Report using Object Model


It is a common requirement to gather information around the Windows SharePoint site usage. Organizations prefer to find out the popular sites in their organizations are or what external WSS sites attract the most number of visitors. This will provide information necessary for an organization to identify the important sites in their environment and properly manage them with extra resources if necessary.

One of the common complains around accessing theses data are the inflexibility of gathering information in a central location. The administrator will have to navigate to the selected SharePoint site administration pages to access the data. This will become a more time consuming exercise when the administrator need to collect usage data from larger number of SharePoint sites.

In this article, I am looking at creating an ASP.NET web application that will populate a collection of SharePoint sites in a drop down list for a given SharePoint site collection. The web application will display the usage details of the selected SharePoint site from the list. This will help the SharePoint administrator to gather all SharePoint usage data from a central location with out have to navigate many different SharePoint site locations.

Usage Analysis Data Web Report

Figure 1 display a Usage Analysis data for a Windows SharePoint site. The users have the option of selecting a monthly or a daily report.

Figure 1: Monthly Usage Analysis Report

Usage Analysis Processing Reports

First of all let's have a look at what is Usage Analysis Reports in SharePoint. Theses reports will help the organizations to determine how the web sites are used in their environment. The data is taken from IIS Logs on the front end web servers and stored in to temporary files. The data is merged in to the content database on the back end SQL Servers when the daily log processing takes place.

The Usage Analysis is not enabled by default when the organization deploys the Windows SharePoint Services Sites. Organizations should enable the Usage Analysis logging process on the servers when they require gathering usage information. The logs files are created daily and a flag is attached to mark that it has been processed.

These logs files are not automatically deleted, they are preserved in "local_drive (C) :\Windows\system32\LogFiles\W3SVC*" where * indicates the Internet Information Server (IIS) instance number of the virtual server as displayed in Figure2. Organizations should consider the advantages against the disk space storage before enabling the Usage Analysis service in their environment. The organization can stop logging process' any time they require to do so.

Figure 2: Preserved log files folder structure with W3SVC* format

By default the log files are located at "local_drive (C) :\Windows\system32\LogFiles\STS" directory. Separate folders are created under above directory for each virtual server and separate folders for each day as displayed in the Figure 3.

Figure 3: Separate directories for each virtual server and for each day

Organizations can configure the above Log file store path for their own preferred path and create up to 30 log files.
(Please look at Setting up Usage Analysis process for more details.) If an organization decides to store the log
files in their preferred location, they should grant Read, Write and Update rights permissions for STS_WPG user
group for the specified folder. Without the permissions, the usage log files cannot be created or updated by IIS.

Setting up Usage Analysis Processing

Administrators can control the setting of Usage Analysis process using the SharePoint Central Administration page. The user must be an administrator on the local server or a member of the SharePoint Administrators group to configure the analysis processing. If the organization adds a new virtual server after the analysis service been configured, they will need to reconfigure the analysis service to collect the data on the newly added virtual server.

  • Click "Start -> All Programs -> Administrative Tools -> SharePoint Central Administration"
  • This will open the "Windows SharePoint Services Central Administration" page
  • Select the "Configure usage analysis processing" from the "Component Configuration" section as displayed in figure 4

    Figure 4: Component Configuration section on the central administration page
  • The Configure Usage Analysis Processing page will open as displayed in Figure 5

    Figure 5: Configure Usage Analysis Processing page
  • Select "Enable logging" check box in "Logging Settings" section
  • The administrator can select a preferred file locations for the log files in "Log file location" box or use the default location C:\WINDOWS\system32\logfiles\STS
  • Enter the number of log files to create in the "Number of log files to create" box. This can be between 1 and 30.
  • Select "Enable usage analysis processing" check box in "Processing Settings" section.
  • Select the time range that analysis process should run from "Run processing between these times daily". By default this is set to start at 1am daily. The administrator can allocate a time period that won't affect the demand on the site.
  • Click "OK" to finish the configuration.

View Usage Analysis Reports

The user must be an administrator or have the View Usage Data right for a site to view the site usage reports. The reports are available through Site Administration page.

The usage data is collected and stored for the entire site collection on a server at a time. The users can see the total number of hits for a site collection on the Site Collection Usage Summary page and for more detailed information, Site Usage Report page for individual sites or sub sites usage information.

View Site Usage Report

  • Navigate to the site you prefer to view the report.
  • Click Site Settings on top tool bar.
  • Click Go to Site Administration link under Administration section as displayed in Figure 6

    Figure 6: Site Settings page
  • Click View site usage data link under Management and Statistic section in Top-Level Site Administration page as displayed in Figure 7

    Figure 7: Top-Level Site Administration page
  • The Site Usage Report page will open as displayed in Figure 8

    Figure 8: Site Usage Report page

Site usage reports are useful for identifying which content on Windows SharePoint Services sites are being heavily used or used very little. This will help organizations to understand which sites are candidates for archiving and which sites should be kept online. In addition, this report contains information regarding how much storage space WSS sites are using. This page provides a report that contains following information:

  • Pages that have been accessed on that site, including document libraries
  • Users that have access the site
  • Operating system of the user accessing the site
  • Browser type
  • Referrer URL
  • Data can be displayed by monthly or daily summary format

Figure 9: Different reports available

The users can select a report option and a daily or monthly option to generate a report. Figure 9 displays a monthly report of all the pages accessed and different kind of reports options available.

Code Example

The web page contains a text box to enter the SharePoint site collection URL. The appropriate sub site will be listed in a dropdown list when user clicks the Submit button. The user then have the option of viewing the daily or monthly usage report of a selected site.

First of all you will need to add the Microsoft.SharePoint.dll to your web application reference list.
This will give us the access to the SharePoint Object Model.

Then instantiate the SPSite object as displayed below. The absolute URL is passed in through
the txtWSSSiteUrl text box. This will populate site collection for the given URL.

//Get the site collection
SPSite mySiteCollection = new SPSite(txtWSSSiteUrl.Text);

Then to access an individual site, instantiate the SPWeb object as displayed below. I am passing in the site name as a parameter.

//Get the details of the selected WSS site
SPWeb site = mySiteCollection.AllWebs[siteName];

After constructing the site SPWeb object, developers can access the information of the site usage data using the public method "GetUsageData" of the SPWeb object as displayed in code example.

GetUsageData(Microsoft.SharePoint.Administration.SPUsageReportType, Microsoft.SharePoint.Administration.SPUsagePeriodType) Method.

The GetUsageData method of the SPWeb class returns a data table that contains information about the usage of a Web site based on the specified type of report and time interval.

SPUsageReportType Enumeration

The SPUsageReportType enumeration specifies the type of information returned in a usage report for a SharePoint site.

The following table shows the members of the SPUsageReportType enumeration and a brief description

browserThe type of Web browser used to visit the SharePoint site. All usage data refers specifically to visits from referring URLs external to the site.
osThe operating system used on the client computer. All usage data refers specifically to visits from referring URLs external to the site.
refUrExternal URLs through which users navigated to the SharePoint site.
urlURLs of pages that are visited or of pages for lists that are updated. Discussions about a page are counted as hits on that page.
userUsers who visited the site.

SPUsagePeriodType Enumeration

The SPUsagePeriodType enumeration specifies the time interval on which a usage report for a Web site is based.

The following table shows the members of the SPUsagePeriodType enumeration and a brief description

dayReturns usage information for each day during the past 31 days starting from the previous day
lastMonthSummarizes usage information for the last 31 days relative to the previous day

I am binding the data table return from GetUsageData property to a DataGrid control to display the information.

Accessing User daily report

//Users who visited the site
DGUsers.DataSource = site.GetUsageData(SPUsageReportType.user,;

Accessing User monthly report

//Users who visited the site
DGUsers.DataSource = site.GetUsageData(SPUsageReportType.user, SPUsagePeriodType.lastMonth);

Accessing Browser daily report

//The type of browsers used to visit the site
DGBrowser.DataSource = site.GetUsageData(SPUsageReportType.browser,;

Accessing Browser monthly report

//The type of browsers used to visit the site
DGBrowser.DataSource = site.GetUsageData(SPUsageReportType.browser, SPUsagePeriodType.lastMonth);

Accessing Operating System daily report

//The Operating System used in client computer
DGOs.DataSource = site.GetUsageData(SPUsageReportType.os,;

Accessing Operating System monthly report

//The Operating System used in client computer
DGOs.DataSource = site.GetUsageData(SPUsageReportType.os, SPUsagePeriodType.lastMonth);

Accessing refUrl daily report

//External URL client used to navigate to SharePoint site
DGRefUrl.DataSource = site.GetUsageData(SPUsageReportType.refUrl,;

Accessing refUrl monthly report

//External URL client used to navigate to SharePoint site
DGRefUrl.DataSource = site.GetUsageData(SPUsageReportType.refUrl, SPUsagePeriodType.lastMonth);

Accessing url daily report

//URL's of pages visited
DGUrls.DataSource = site.GetUsageData(SPUsageReportType.url,;

Accessing url monthly report

//URL's of pages visited
DGUrls.DataSource = site.GetUsageData(SPUsageReportType.url, SPUsagePeriodType.lastMonth);

Deploying the Web Application to the SharePoint Portal Server

  • Create the "UsageAnalysisData" Virtual directory under the portal web site in IIS
  • Map the virtual directory to the physical file path (this should be done as apart of above step)
  • Open the SharePoint Central Administration pages by clicking "Start > Administration tools > SharePoint Central Administration"
  • Click "Windows SharePoint Services" link on the left hand side
  • Select "Configure Virtual server setting" link from "Virtual Server Configuration" group
  • Select your Portal server from the list
  • Click "Defined managed path" link under Virtual Server Management group in Virtual Server setting page
  • Type name of the virtual directory you created in first step in the Path section of Add new Path section
  • Select "Exclude path" radio button under the type section
  • Click "Ok"
  • Then navigate to http://portal_site_name/UsageAnalysisData/MonitoringPage.aspx

Figure 10: A list of sub sites of the site collection

Figure 11: Daily Usage Analysis Report of a Windows SharePoint Site


SharePoint Administrators should be able to use this article as a starting point and develop their SharePoint Usage Analysis data gatherer web application according to their requirements.

Print ListData SharePoint

on Thursday, March 11, 2010

Solution Architecture

The solution will be deployed as a wss feature, which allows us an easy way to add a menu item to the sharepoint menus. The feature will define that the item we want to add will be added to the actions menu of all lists, in a site collection. You can ofcourse change it so that it behaves differently and connects only to lists of a certain type if you so wish, or maybe move the menu item to a different place. I recommend reviewing the msdn article on the possible configurations.
The solution is based on 3 files:

  1. feature.xml
    Defines the feature, its scope and its title that you will see in the "site features" (or site collection features or farm features - depending on the scope)

  2. PrintList.xml
    Defines what action we want to add to what menu and what will happen when the user clicks the menu item. This is where you configure the text of the item, and the link to the page that will print the list. which just happens to be the last file:

  3. PrintList.aspx
    Contains the code that shows the list in a print-friendly view. This file should be deployed to the layouts folder and must be called with the site's context (more about that shortly).

To the Code!

note - when I talk about the "12 hive" I am referring to the folder C:\Program Files\Common Files\Microsoft Shared\web server extensions\12

Create the page that prints a list:

  1. Log on to the server, and open the template\layouts folder in the 12 hive.

  2. Create a new text file in the folder, and name it "PrintList.aspx"

  3. Open the empty file in your editor of choice (notepad is fine) and paste the following code into it:

    <%@ Page Language="C#" Inherits="System.Web.UI.Page" %>

    <%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"

    Assembly="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

    <%@ Import Namespace="Microsoft.SharePoint" %>



    <title>SharePoint List Print</title>

    <link rel="stylesheet" type="text/css" href="/_layouts/1033/styles/core.css" />

    <script type="text/javascript" language="javascript" src="/_layouts/1033/init.js"></script>

    <script type="text/javascript" language="javascript" src="/_layouts/1033/core.js"


    <script type="text/javascript" language="javascript" src="/_layouts/1033/ie55up.js"></script>

    <script type="text/javascript" language="javascript" src="/_layouts/1033/search.js"





    string listId = "";

    string referrer = "";

    //get the list id (guid in a string format) from the query string

    listId = Page.Request.QueryString["list"];

    //get the http referrer (for the back button\action)

    referrer = Page.Request.ServerVariables["http_referer"];

    //make sure the list parameter was passed

    if (listId == null)


    //if a referrer url exists (since the page may have been opened from a direct link, this is not always the case) redirect the user back

    if (referrer != null && referrer.Trim().Length != 0)


    Page.Response.Write("<p>The list ID parameter ('list') is missing from the address.<br>Please go to the list you want to print and try again.</p>");

    Page.Response.Write("<p><a href=\"" + referrer + "\" title=\"Go Back\">Click here to go back to the page you came from</p>");




    Page.Response.Write("<p>The list ID parameter ('list') is missing from the address.<br>Please go to the list you want to print and try again.</p>");







    //load the web object for the site that the page is now in context of

    using (SPWeb web = SPControl.GetContextWeb(Context))


    //load the list that was passed in the 'list' querystring parameter to the page

    SPList list = web.Lists[new Guid(listId)];

    //load the query of the default view. note - need to modify code in the future to enable multiple view printing

    SPQuery query = new SPQuery(list.DefaultView);

    //write the list to the page


    //add the print script


    <script type="text/javascript" language="javascript">






    catch (Exception ex)


    Page.Response.Write("<p>There was an error loading the list information:<br />");








Install the feature

  1. Open the \TEMPLATE\FEATURES folder under the 12 hive

  2. Create a folder called PrintListMenuAction

  3. In that folder, create 2 text files, one called feature.xml and the second printlist.xml

  4. In your editor of choice (notepad is fine) open the feature.xml file and paste into it the following:

    <?xml version="1.0" encoding="utf-8" ?>

    <Feature Id="769826dd-9dd2-11db-96ca-005056c00008"

    Title="Print List"

    Description="This feature adds a print command in the Actions menu for Windows SharePoint Services lists."





    <ElementManifest Location="PrintList.xml" />



  5. In your editor of choice open the printlist.xml and paste the following:

    <?xml version="1.0" encoding="utf-8" ?>

    <Elements xmlns="">


      <!-- Add the action to the List Toolbar Actions Menu Dropdown -->

      <CustomAction Id="SPSTIPS.PrintListActionsToolbar"





        Title="Print List">

        <UrlAction Url="{SiteUrl}/_layouts/PrintList.aspx?list={ListId}"/>




Almost done - install the feature and test it!

To install the feature, open command line (start>run>cmd) and navigate to the bin folder in the 12 hive.

Once there, run the following command to install the feature:

stsadm -o installfeature -name PrintListMenuAction -force

After you ran that command successfuly, you can activate the feature in the site collection either using the user interface (site actions> site settings> site collection features):

or you can (more easily since you are already in the command line) just run the following command, entering the site path:

stsadm -o activatefeature -name PrintListMenuAction -url [your site url here] -force

That's it! if you now go to any list in that site, you should have the print menu action.

Convert Word to PDF

I would highly recoomend ASPOSE.WORDS product to convert word documents into PDF in SharePoint.It is not a free product but is good for the functionality.

Branding Notes for SharePoint

I thought I would run through some of the tools that have helped me when branding a MOSS intranet. SharePoint Designer or perhaps better yet Studio can be the primary tool for creating master pages, themes, and page layouts, but your gonna need some help when trying to dig through all the CSS in the core.css file, and all it’s crazy inheritance. Combing through the css is a big chunk of your effort when you are starting with the default master or the default or classic theme. Most corporate organizations that I have worked with take the approach of “skinning” the SharePoint default look to match there colors and branding as opposed to starting from the ground up. So odds are your starting with the default look : -(

A couple of prerequisite tips before I get to the tools…..

When creating or modify styles - always, always, always put them in a new stylesheet. If you just update core.css, you will have a lot of pain in your life when your discover some goofy UI thing happening on a page, and you have to comb through the 4,000+ lines of styles in core.

Be cautious of overwriting or adding images directly in the _layouts/Images directory (C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\IMAGES) . If the box has to have MOSS reinstalled or perhaps some obscure patch occurs - you can kiss those image updates goodbye. However, I know that sometimes this is unavoidable….or at least a huge time saver. If your implementing a larger project, then put the images you added or modified in source control, and have a build script that will push the images. This way all the customization can be automatically pushed. OR if is a small implementation, at least document the image changes :- )

So…..oh yeah……The Tools:

IE Developer Toolbar

Certainly the biggest challenge in modifying the UI of MOSS is trying to figure out which style does what…and where is does it. And a good way to discover what MOSS is doing with it’s ginormous style sheet is to look at the rendered pages in the site. The IE Developer toolbar will provide 2 great features that will aid in this discovery process. 1. From the menu select ‘Find’ and ‘Select Element by Click’ which will allow you to click on any element in the page, and see the class used as well as all of the style attributes. So even if you see the class you modified, but say it is still show a incorrect style value (like color, padding, or whatever) then you know your style is being overwritten somewhere else. 2. As you select an element is also gives you a window with the html of the page that is much easier to comb though than viewing source in Notepad - That way you can crawl up and down the html tags to see what styles are being applied at the div, td, tr, table, etc. and……OK #3 - you can also disable scripts with a click so you can see styles without the hover state kicking in (i.e. - Menus)

CSS Finder Code (courtesy of msdn)

Similar to the IE Developer toolbar, you can throw this snippet into a content editor web part, which will allow you to roll over elements on the page and have the css style show up in a div tag on the screen. It is handy and quick, but will not give you as much information as the IE Developer toolbar. I would click on the link above because this page has a css reference chart that is fairly useful - also see Heather Solomon’s CSS Reference to get and idea for some of the major styles.

<script language="jscript">
function ClassInfo()
    if (window.event.srcElement.className != null)
        stsclass.innerText = window.event.srcElement.className;

        stsclass.innerText = "";

window.document.body.onmouseover = ClassInfo;</script>

<div style="border-style:solid;border-width:1px; width: 281px; height: 34px;
position: absolute; left: 286px; top: 41px; z-index:15; padding-left:4px;
padding-right:4px; padding-top:2px; padding-bottom:2px; background-color:#EEEEF4">
<p id="stsclasstitle"><font face="Tahoma" id="stsclasstitle">Classname: </font>

<font face="Tahoma"id="stsclass">&#xa0;</font>

Just Color Picker

Again another tool for style discovery (are you getting that this is a pain) I will use this little piece of freeware to quickly identify the hex color of an element on a page. Sometimes when you swear up and down that you have changed a color but it just wont show, I will get the hex off the screen, and start start seeing where that color shows up in the various style sheets.

SharePoint Skinner

This is a handy tool when you need to create a down and dirty theme - quickly. I’ll admit I have not played with this too much, but it will allow you so change colors and images with a few clicks, and export out a theme. This may also help you get an understanding of what css classes effect what styles, but I find the developer toolbar more efficient for that task.

Features and Deployment

The easiest way to deploy your look and feel to SharePoint is to utilize the Solution Framework MOSS provides. Especially in a farm environment where files need to be pushed to multiple servers. Features are also what I would recommend when including look and feel into site definitions. Many people have posted adding master pages to a Module Element in the ONET file of a site definition, but that will deploy a copy of the master page file to every site provisioned based on your definition. To me, this defeats the point of a template as it can not be globally changed now that you have copies stored in every web. You can create features that utilize receiver classes to programmatically apply a master page or theme when a feature is activated. You can also auto-activate these types of features in a custom site definition. Some good examples of how this is done are here:

Graham Sibley shows how to write a feature that deploys a theme to a site

Paul Papanek Stork shows how to write a feature that apply’s a master page to a site. This feature will apply a mater page from the /_catalogs directory at the root of the site collection.

Now that you are writing all these crazy features you may want a way to take some of the legwork out of the process. My friend Rich Finn has created a WSP Project Template for Visual Studio that will create the wsp along with the manifest.xml, and .ddf files for you. It also has deployment and upgrade scripts built in to deploy your look and feel to the portal. There is another one on CodePlex called SharePoint Feature Packager that will also do the trick, but Rich’s template has less manual steps to get rolling.

These tools definitely make life easier, but before implementing a portal look and feel, be sure to take all the proper planning steps to ensure that what you are implementing will best suit the long term needs of the business. SharePoint has made a lot of headway in how things can be packaged, deployed, and templated, but there are still a lot of gotchas - you don’t want to deploy a look and feel to a ton of pages and later find out something drastic has to change. You may find yourself rebuilding pages manually or basically undergoing a site migration. Each organization needs to consider things like:

Site Definitions vs. Site Templates

Themes vs. Masterpages - one or the other or both

Features and scope of those features

What meta data will be applied in our templates

Carefully document the pros and cons of each of these decisions so that the business can understand the potential impacts of the decisions being made during the design phase of a project.

WSS 3.0 vs MOSS Standard vs MOSS Enterprise

on Wednesday, March 10, 2010

There's still plenty of confusion out there about SharePoint, particularly around what is included in WSS versus MOSS. Part of the problem is that there is soooo much information about SharePoint that the simple details get lost…

So, let's go through the various options, comparing WSS with MOSS Standard and MOSS Enterprise as simply as possible. I'll exclude technicalities (eg that you need R2 of W2K3 etc) and just focus on the main points.

Windows SharePoint Services (WSS)

Currently in version 3.0, WSS is a free add-on to Windows 2003 Server. WSS is the foundation of SharePoint. It provides a stack of features (or services), including document management & collaboration, Wikis, Blogs, RSS feeds, strong Office integration (Word, Excel, Outlook, Access, PowerPoint) including alerts and synchronisation, basic workflow and some search capabilities. It has the foundational elements such as security and storage services.

Many intranet requirements are completely catered for with WSS. And WSS can be used quite effectively as a web site too.

[I've seen discussions about storage limits within WSS being set at 4GB*, but my current understanding is that this is not the case - ie there is no set limit.]

Microsoft Office SharePoint Services (MOSS) Standard

MOSS** sits on top of WSS and comes in two main versions: Standard and Enterprise.

MOSS Standard has stacks of features of course (including Enterprise Content Management, Portals and comprehensive Workflow), but the main ones to consider are:

  • Enterprise Search (which allows you to crawl a number of data sources)
  • People management (which includes all the My Site stuff, Personalisation features, Single Sign On and more)
  • Analytics (which includes all the usage and auditing functions for example: you can audit who is searching for what)

Point to note: Enterprise Search IS included in the Standard version.

Microsoft Office SharePoint Services (MOSS) Enterprise

Moving on to MOSS Enterprise, we get everything in Standard, plus a few more features added, the most important of which are:

  • Business Data Catalog or BDC (which is a means of linking SharePoint to basically anything including SQL Servers, Oracle Servers, Microsoft CRM, SAP and more, and providing the BI functions including dashboards and KPIs)
  • Excel 2007 Services (which allow Excel spreadsheets to be 'hosted' and rendered, and even accessed as web services)
  • Forms server (see below)

Point to note: People sometimes confuse BDC with Enterprise Search. To clarify: BDC can be considered an extra source of data feeds into Enterprise Search.

Other versions

There also used to be various flavours of MOSS for Search, and these can best be summed up as WSS plus Enterprise Search (ie they lack some of the other MOSS features such as ECM etc). They have recently been re-branded as Microsoft Search Server 2008 and come in a free 'Express' version and the Standard version.

Aside: There is another SharePoint pseudo-version known as the Office Forms Server 2007 which basically allows InfoPath forms to be rendered in the browser. It can be added to just WSS if required, and is included by default in the MOSS Enterprise version.


Microsoft hasn't gone out of its way to make all this clear I have to admit – the hype around SharePoint is usually focused on the MOSS side of things – and why not? After all that's where the big dollars are. Speaking of big dollars, it may not be as big as everyone keeps making out.


Sure enough the Internet facing licensing is off with the fairies (at around the USD 40K per server mark!), but inside the company it can be significantly cheaper.

I don't claim to understand the SharePoint licensing intimately, but this link will give you an overview of licensing (eg a basic intranet MOSS license is under $5K, although moving to Enterprise will get you into $60K level – Yikes!). However, the real kicker comes when you have to weigh up all the CALs you need (and for Enterprise you need to buy both the Standard CALs and the Enterprise CALS on top).

Getting confused yet? Yep, and to top it off you also need to factor in SQL Server licenses if you don't already have those in place.

Summary: You need MOSS Server license + CALs + SQL Server licenses

Point to note: If you want to expose your intranet on the internet (eg via your web site) then you are in for a headache :-)

This barely helpful link from Microsoft attempts to make it clearer, but requires about five readings before it starts to make sense.

This Excel spreadsheet is a great SharePoint feature comparison for those wanting to get into the nitty-gritty (well worth the download).

Consider this…

Here's the main takeaway… if you are considering SharePoint for your intranet but have been worried about licensing costs, then start with WSS. It has stacks of collaboration features and may be all you need. And it's free. Plus you can always build on it, adding MOSS features later.

If you did move to MOSS, start with MOSS Standard and think carefully about whether you need the Enterprise features.

And think very, very carefully about making your web site MOSS based :-)


References: Inside Microsoft Office SharePoint Server 2007 by Patrick Tisseghem


* 4GB limitation – MOSS running on SQL Express will be limited to 4GB (due to the SQL Express limitations), but WSS seems to run on a special version of SQL that is not limited. MOSS is never recommended to be run on SQL Express. Disclaimer: I am not sure of these details.

** MOSS is technically MOSS 2007, as there has not been any previous MOSS versions. The previous version of SharePoint was SharePoint Portal Server 2003, usually referred to as SPS or SPS 2003.

WSS 3.0 Search vs MOSS Search

We have spent some time comparing MOSS search and WSS search in our lab.  For those who are interested in the differences between MOSS search and WSS search, this blog post might clear things up.

WSS 3.0 Search
Single Site collection, automatically scoped to current site (and subsites):

Only SharePoint content in the site collection can be crawled. You cannot configure Search to crawl databases, mail servers, application servers, or Web sites and file shares outside of the site collection. In a deployment with more than one site collection, each site collection provides Search only for content on that site collection, and there is no aggregation of search results across site collections.

MOSS Search

MOSS uses an enhanced relevance algorithm for its search engine, and is able to crawl content from multiple sites within an enterprise, as well as non-sharepoint web sites. In short, the MOSS search engine is a powerful enterprise search engine with a relevance algorithm, while the WSS site-local search engine is actually pretty useless beyond simple "dumb keyword" search.

Site Directory
Site Directory MOSS provides a new site template called "Site Directory". When you create your first portal via MOSS, it comes with a Site Directory. This site template is designed specifically for tracking links to sites, displaying site maps and site navigation lists, as well as searching through the site directory. With a Site Directory in your portal, you will be asked if you want to publish a link to your new site every time you create a new site within the portal, regardless of its depth within the hierarchy. This single feature is, in my opinion, absolutely required for any kind of Intranet deployment of SharePoint. And yes, that means I think MOSS is a requirement for any real Intranet deployment of SharePoint on any kind of meaningful scale.

Customizing BestBets SharePoint

One of the things that people are not aware of is that you can customize the search results coming from the SharePoint search engine. The results, which is XML, given by the engine are styled using XSLT. If you create your own XSLT you can customize/restyle your results page.

There is a 'Visual How To' by Patrick Tisseghem explaining the steps you need to do to customize the search page.

You can do the same trick with the Best Bets meaning, you can customize them by applying your own XSLT. Before we are going to customize the Best Bets, let me explain what they do an how you can use them.

Best Bets are used to promote some results depending on your search keywords. If you look at the screenshot below you see that when I type SharePoint in the search box, U2U and Microsoft are pushed forward as results where you definitely can find something about SharePoint. So if you think about it, Best Bets is a way for an administrator to earn some extra money, the one who pays the most gets on top of the list J.

To create these Best Bets, you need to go to the settings page of your top level site and you need to click on the 'Search keywords' linkbutton where you can create the Best Bets by clicking on the create button.

After filling in a keyword you can add Best Bets by clicking on the Add Best Bet button, type in a url, title and description for your best bet.

Now that the Best Bets are created we can test them by typing SharePoint in the search textbox. You will see the results at the right side of the page.

Because they are displayed in a webpart you can drag the webpart into another webpartzone to ,for example, have your best bets before the search results.

Okay, now let's customize our Best Bets. These are basically the same steps as in the 'Visual How To', so you can follow the steps there as well, the only difference is that in the video they customize the search results.

Because the Best Bets webpart is using XSLT to show the results getting from the search engine (which is XML ) we can apply our own XSLT. So if you go to the properties of the webpart you can click on the XSL Editor to replace the existing XSLT with your personal XSLT.

As said, the best bests is nothing more than XML which is styled using XSLT. Because it is not easy to create XSLT, We are going to let SharePoint Designer create the XSLT for us. The only thing that we need to do is saving the XML returned from the search engine so we can use it in the Designer.

To see the XML returned from the engine we need to use following XSLT. Copy it in the XSLT dialog box.

<xsl:stylesheet version="1.0"
xmlns:xsl="" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />

<xsl:template match="/">
<xmp><xsl:copy-of select="*"/></xmp>


After saving your new XSLT you can copy the XML and paste it temporarily in an XML file, so we can import this file and use it as a Data Source in SharePoint Designer.

Speaking about the devil, lets open up SharePoint designer to do some customization magic. The first thing that we need to do is using our XML as a Data Source. You can manage your data sources by choosing Manage Data Sources which you can find in the Data View on the menu bar.

Once you've done this, you get an overview of all the available data sources in the toolbox. One of the data source categories is 'XML Files'. In that category you can click on Add an Xml File to add your XML file as a data source.

You can browse to your file and add it to your Data Sources . Once the file is added,you can see the available data by right-clicking on it and pick Show Data from the dropdownlist.

Once the data is shown you can specify what data you want to show for your best bets. Select title, url, description and drag this to your design surface.

Once you've dragged your data on the design surface, you see a menu where you can do some additional settings like adding more columns, allow paging and sorting …. In our case it is more useful to apply another layout so click on change layout and pick one that fit your needs.

Next thing that we need to do is make sure that we can click on the url.

Okay, that's it for now (you can off course customize as much or as advanced if you want), let's go to code view and copy the generated XSLT. Make sure that you copy everything between and including the <xsl:stylesheet> tags.

Copy the XSLT in the XSL Editor in the properties of the Best Bets webpart and save it.

Publish your page and try it out.

SharePoint Keyword and Property Search in SharePoint Server

Powerful Keyword and Property Search in SharePoint Server

MSDN has the best resources for understanding the keyword sytax and property searches.  You'll notice a lot of these are common across search platforms making it easy to adopt by end users.  Property search is extremly powerful for filtering down your results and worth your time to learn. 

If I'm searching for more data about content types using a keyword simple term, a great way to associate a template, workflow and meta data capture, I might search for content types.  Words following the ">" are example searches.

>content types

If that doesn't return the result I'm looking for I could add an keyword included term with a plus such as +sharepoint. Maybe I want to exclude exchange terms, so I can use an excluded term.

>+sharepoint content types -exchange

To narrow down my search I could add a property such as title:"content types."  Property searches support quote phrases:

>+sharepoint title:"content types"

If I know that William Devo authored the document I could do a property search based on author for example: 

>+sharepoint +title:"content types" author:"william devo"

If I know that the document should be on the office portal, I could search

>+sharepoint title:"content types" author:"william devo" site:http://office

Note: (no trailing slash on URLs.) The prefix property similar to a wild card search search described below applies to property searches where I can search for properties where I want to include multiple spellings. Maybe I don't know if he was Will or William.

>+sharepoint title:"content types" author:will site:http://office

I may want to do another property search to restrict it even more since I know I only want word docs.

>+sharepoint title:content types" author:will site:http://office filetype:doc

How do you do an OR? Simply include multiple property filters maybe it's bill or will/william.

>+sharepoint title:content types" author:will author:bill site:http://office filetype:doc

If all this seems like a lot to do on the simple search query box, you can use advanced search.  Using this same last example I could use the following:

Find Documents with:

content types


Result type: Word documents

Property Restrictions

Where the property... Author Contains Will or

Author Contains Bill and

URL Contains http://office