SharePoint Module tag


– The Module tag is used to deploy files ‘logically’ to SharePoint when the given

feature is activated. This means they liv in the database, not physcally on disk

in the SharePoint 12 hive.

Module Attributes:

  • Path is relative to the current web site.

  • Url – is the relative url to the web site root (blank) or to the document library (i.e. "MyLibrary").

    • URL – This is the target location for your file. Effectively, this is the relative URL that points to the list that you want your files to be placed in. The relative url to the web site.

  • Path – this is the relative location between the feature and the physical file that you want to install. So if your file is in a sub-folder of the featue called "Images" then you would place "Images" as the Path. If your file is in the root feature folder (next to your feature.xml) then the "Path" would be an empty string ("").

  • RootWebOnly – this is a boolean value. If set to true, then this will only install when activated at the top-level site collection.

File Attributes:

  • Url is relative to the web site and contains the name of the file (i.e MyPage.aspx).

How to Create a Custom List with a Custom Content Type and Views


Steps to creating a new list with custom views and a custom content type:

Why use a custom content type?

  1. Create your site columns (fields) and content type, and deploy it to your development farm.
  2. Create a new generic Custom list on any site of your choosing.  Enable content type management on the list.
  3. Remove the default Item content type from the list.
  4. Add your new custom content type to the list, it should be the default.
  5. Customize your views as needed.
  6. Use the SharePoint Solution Generator to generate a List Definition for your new list.  The resulting generated Visual Studio project will contain a folder for the list that contains several form files (DispForm.aspx, EditForm.aspx, and NewForm.aspx) and an .aspx file for each view you created such as AllItems.aspx.  You will also have a schema.xml file which contains the content type definition, the views definition, and the fields section.  Leave the Fields and Views nodes/sections alone as they contain the definitions you defined.
  7. In the schema.xml file, in the ContentTypes node you will find a ContentType node defining your custom content type.  Comment (or delete) this entire node.  We will add this content type to the list via code instead of defining its association here declaratively.

The Major Task content type is commented out here because we are going to add
it programmatically via the ListInstances feature receiver.  This allows us to
properly promote all the fields in the content type to the list and enable
content type management on the list much more easily.

Logging to the SharePoint Log Files

Thanks to Brad Younge for sharing this a while back.  Below is an example on how to write to the SharePoint log files (located in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\LOGS folder).

catch(Exception e) 
   Microsoft.Office.Server.Diagnostics.PortalLog.LogString("Exception: {0} - {1}", e.Message, e.StackTrace);

You’ll likely want to prefix your log entries with a date and time stamp.

How To SysPrep Your Virtual PC/Virtual Server Images

This is something that anyone who uses Virtual Server or Virtual PC should know.


System administrators and software developers, especially those who are developing SharePoint solutions, often develop or test using virtual machines, either Virtual PC 2007 or Virtual Server 2005 R2.  Creating new virtual machines can be a time consuming effort; one we would all like to prevent from having to do every time we need a new virtual machine.  The great thing is that you can save all the time it takes to install Windows and the latest Windows Updates if you SysPrep a virtual machine.

What Is SysPrep?

SysPrep is a tool that allows you to prepare or “prep” a machine with the operating system along with any software you wish was pre-installed and pre-configured.  Once a machine is SysPrep’d, you have a new virtual machine that has the Windows operating system along with any additional software or features you want, such as IIS, pre-installed and pre-configured.  SysPrep allows you to create your perfect system configuration packaged so that you can have a new virtual machine up and running in just minutes.  And, it is available for both Windows Server 2003 and Windows XP.

Where Is SysPrep?

The SysPrep tool is located in a separate download from Microsoft called the System Preparation tool for Windows Server 2003 Service Pack 2 Deployment.

How To SysPrep

Building Your Virtual Machine Image

  1. Install your OS.  Windows Server 2003 R2 SP2 (or latest service pack), or Windows XP, or Vista.
    Note: I have not personally tried to SysPrep a Vista machine yet.
  2. Do NOT join the machine to a domain, at least not yet. (so you can leave the Admin password blank)
  3. Reset the Administrator password to blank.
  4. Get the latest Windows Updates.  Reboot and get latest again until there are no more required updates.
  5. Antivirus (Yes, your virtual machines should have antivirus software installed.)
  6. BGInfo (optional.  Just a tool I like to use that provides system information on the desktop background.)
  7. Daemon Tools CD Emulator.  (optional.  Just a tool I like to use to access ISO images.)
  8. Install the latest VM Additions.  (optional, but you will likely want to install this.  This comes with your Virtual PC and Virtual Server.)
  9. .NET Framework 3.5 SP1.  (optional.  This will include the latest .NET Framework for 1.1, 2.0, and 3.0.)
  10. Activate the Windows license (if you want to prevent having to re-activate Windows for each new virtual machine you create.)

Preparing to SysPrep: Creating a SysPrep.inf File

Before you can SysPrep you virtual machine, you need to create a SysPrep.inf configuration file.  This file contains the information about your machine.  It will also prevent you from having to enter you CD Key each time you create a new virtual machine from you SysPrep’d image.  Below is a sample of the SysPrep.inf file that you need to create.  This file configures the SysPrep process and automates boot up process.

  1. On your virtual machine, create a folder SysPrep at the root of your C: drive (C:\SysPrep).
  2. Copy the following text into a text file named SysPrep.inf.
  3. Enter the correct values for the following keys:
    1. TimeZone – the value of 10 is MST.  You may want to change this to your local time zone, but it is not required to do so.
    2. OEMDuplicatorsting – this should contain the name of the operating system you have installed on your virtual machine.
    3. FullName – your name, the name you would enter if you were installing Windows.
    4. OrgName – the name of your company, or blank.
    5. ProductKey – Your product key (CD key) license.

Sample SysPrep.inf file:

    OEMDuplicatorstring="Windows Server 2003 R2 Standard"
    FullName="YOUR NAME HERE like Mark Wagner"
    OrgName="YOUR COMPANY NAME HERE like Contoso"

Your SysPrep.inf configuration file is now ready to be used.


SysPrep-ing your Virtual Machine

SysPrep-ing your virtual machine takes just a minute or two.  Most of the time is simply shutting down your virtual machine.  Important: do not start this virtual machine back up or it will un-SysPrep your machine.  If this does happen, you can simply go through these steps below to SysPrep you virtual machine again.

  1. On your virtual machine, in the C:\SysPrep folder, run SysPrep.exe.
  2. Check the “Don’t reset grace period for activation” option.
  3. Make sure Shutdown mode is Shut down.
  4. Click the Reseal button to shutdown and package.
  5. Click OK to generate new SID’s.
  6. Your virtual machine will now shut down and be SysPrep’d.
  7. You now have a virtual image that is SysPrep’d, but not ready to be used.
  8. Before you use this image, you will need to make a backup copy of your virtual machine image files.  This will allow you to always have a SysPrep’d virtual machine ready and waiting.
  9. Backup your SysPrep’d virtual machine image files (.vhd, .vmc), and rename them to something you can easily understand and that describes what your image contains.  For example:
    1. Windows Server 2003 R2 SP2 SysPrep.vmc
    2. Windows Server 2003 R2 SP2 SysPrep.vhd
  10. You now have Your virtual machine SysPrep’d.  You can now use this image to quickly create a new virtual machine in minutes, with a new machine name and new unique System ID (SID) each time you use it.

Using Your SysPrep’d Image to Create a New Virtual Machine

Now, creating a new virtual machine will only take just a couple minutes.

  1. First, you need to copy your SysPrep’d image to a new name and to a new location where you will use this new virtual machine.  Copy your SysPrep’d image files (.vmc & .vhd) to a new location where you want your new virtual machine file to reside.
  2. Rename them to a new, appropriate name.  For example, if you are going to create a SharePoint server you might name them something like:
    1. MySharePoint2007.vmc
    2. MySharePoint2007.vhd
  3. Add this new virtual machine to you Virtual PC or Virtual Server; which ever you are using;
  4. Edit the configuration and make sure the virtual hard drive (VHD) is pointing to your new .vhd file.  In this example, the MySharePoint2007.vhd file.
  5. Configure any other items such as memory allocation and network cards as necessary.
  6. Start the virtual machine.
  7. You will receive a few prompts such as the name for you new machine.
  8. If you wish, you can now join you virtual machine to a domain.

SysPrep is a must have time-saving tool for anyone who uses Virtual PC and/or Virtual Server.

How To: Modify the web.config file in SharePoint using SPWebConfigModification

by Mark Wagner

SharePoint 2007 (WSS and MOSS) allows you to easily and safely add and remove modifications to the web.config file. This post briefly covers what the SPWebConfigModification class can do for you, and how to best to use it.

I hope to improve this post with additions, corrections, and contributions from the public, so please provide any constructive comments and suggestions you have.

Technologies this applies to:

  • Windows SharePoint Services 3.0 (WSS 3.0)
  • Microsoft Office SharePoint Server 2007 (MOSS 2007)


While I was scavenging for any information I could find regarding the SPWebConfigModification, there were a few posts I found useful. Information seemed to be scarce and I ended up learning most through trial and error; however, there a couple good nuggets and others I must achnowledge.

  • Shawn Feldman is a coworker (very sharp developer) who was the first to make me aware of the SPWebConfigModification class. Additionally, he provided me with the original code samples, some of which I have since modified and included in my WebConfigurator helper class (a separate post to come).
  • Vincent Rothwell has a post entry that provides, in my opinion, a “Best Practice” on how to best remove your modifications using SPWebConfigModification. It’s simple and right on target.
  • Antonz has a post entry that addresses the proper way to create a section that can be removed.
  • Daniel Larson also has a few a posts that provide a basic overview and examples on how to use SPWebConfigModification.

Overview of SPWebConfigModification

Through the use of the SPWebConfigModification class and xpath you can safely add and remove modifications to the web.config file. There are a number of benefits to using SPWebConfigModificaton to modify the web.config.

SharePoint provides access to a SharePoint web application via the object model using the SPWebApplication class. The SPWebApplication class has a SPWebConfigModifications collection property that contains all the modifications (SPWebConfigModification objects) made to this web application’s web.config file. This is also where we can add new modifications and have them applied to the web.config – or remove them. Additionally, you can iterate through this collection and inspect what changes have been applied. This contains all changes – including yours and those made by other assemblies. You can determine (or attempt to determine) where each change was made by inspecting the owner property.

Every modification has an Owner. Every change made the web.config can be assigned an owner. The owner is nothing more than a string value that uniquely identifies your changes from any other changes that have been made, or may be made in the future.  I suggest using the name of the assembly, or the feature name or feature ID.

Removing is not merely changing a value. By assigning an owner to each new change you make, you can very easily remove your changes. In the case where your original modification was an addition, where you added a new node or attribute, your changes are simply deleted and remove from the web.config file when they are removed. In the case where your modification changed the value of an existing node, upon removing your modification SPWebConfigModification automatically assigns the appropriate previous value. For example, let’s say we wanted to change the Trust level in the web.config to “Full” from whatever it currently is. The Trust level is usually set to a value of “WSS_Medium” by default, but it could easily be some other value before we make our changes. The great thing is that we don’t need worry about what the current value is if ever we need to remove our modification. We do this by removing our change, not by trying to change the value back to a predetermined value such as “WSS_Medium” – SPWebConfigModification manages this for us. This is a big advantage.

Propagate your web.config changes across the farm. SharePoint is designed to be very scalable and easily scalable. The changes you make to the web.config will need to be made to every front-end web server in the farm. SPWebConfigModification can manage this for you very easily.

Also, features are likely the method you will want to use to apply your changes. Using a feature (that can be either hidden or visible) will ensure your web.config changes are applied if a new web server is added to the farm, or rebuilt from scratch. Applying your web.config changes via a feature will ensure your changes are applied to new or newly built web servers – without having to refer to documentation or manually apply your changes to the web.config file on each and every web server.

SPWebConfigModification properties

SPWebConfigModification on MSDN

Gets or sets the name of the attribute or section node to be modified or created.  This is an XPath expression relative to the parent node (specified by the Path property). Sometimes this is nothing more than the name of the new or existing node you want to change. For example: “pages”.

However, this often times needs to contain an XPath expression that is more spcific in order to properly specify the correct node to modify (if it exists) or to create.  For example: “add[@assembly=’myAssemblyName’]”

Gets or sets the owner of the web.config modification. This should to be a unique string value that will allow you to uniquely identify your modifications from any other modifications made to the web.config.  Suggestions are to use the assembly name, feature name, or feature ID.  This will ensure you are able to easily and cleanly remove your modification when the need arises.

Gets or sets the XPath expression that is used to locate the node that is being modified or created. This value usually contains simple XPath expression to the parent node of the item you intend to change or create. For example: “system.web/httpHandlers” or “system.web/customErrors”.

This can also be a more specific XPath expression to select (or create) a node with a specific attribute value. For example:

Gets or sets the sequence number the modification. I have not performed any detailed testing with this parameter. I have always just set this value to zero (0) with no problems.

Gets or sets the type of modification for this object instance. The three values available are defined via the SPWebConfigModification.SPWebConfigModificationType and are EnsureChildNode, EnsureAttribute, and EnsureSection. Caution: Use the EnsureSection type with prudence as nodes created with EnsureSection cannot be removed. See Best Practice section below.

Gets the collection of field names and values for fields that were deleted or changed. I have not investigated this property and do not know of any need for using it. (inherited from SPAutoSerializingObject)

Gets or sets the value of the item to set. This is usually the complete xml element tag or attribute value for the node specified in the Name property (or as the name parameter in the constructor).

How to use SPWebConfigModification

Using SPWebConfigModification is very easy, which makes it even better.

Below is a quick example of code that changes the mode attribute to a value of “Off”. Here is a sample of what the web.config node might look like that this code would be modifying.

      <customErrors mode="On">

Here is the quick example that will change the mode attribute to “Off”. Comments are inline describing each section of code.

private void SimpleSample()
    // Get an instance of my local web application
    SPWebApplication webApp = new SPSite("http://localhost").WebApplication;

    // Create my new modification to set the mode attibute to "Off".
    // Example: <customErrors mode="Off">
    SPWebConfigModification modification = new SPWebConfigModification("mode", "system.web/customErrors");
    modification.Owner = "SimpleSampleUniqueOwnerValue";
    modification.Sequence = 0;
    modification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureAttribute;
    modification.Value = "Off";
    // Add my new web.config modification.
    // Save web.config changes. 
    // Applies the list of web.config modifications to all Web applications in this Web service across the farm.

More examples can be found later in the article.  Additonally, I will be posting my WebConfigurator helper class that contains a number of helper methods to centralize and simplify commonly modified elements in the web.config file.

Best Practices

I found it difficult to fully understand exactly how to use SPWebConfigModification as well as how it should and should not be used, and how I should expect it for function. For this reason I have started a list of best practices when using SPWebConfigModification.

Saving your modifications

While first using the SPWebConfigModification class, everything was going fairly smooth with testing and deployment – as it usually does on the developer machine. Of course my development machine is a single farm configuration, which is standard. Executing my web.config modifications on my single server worked just fine. However, when I deployed my code to two other farm configurations, the changes were not being applied to the web.config on any web server. Searching on the Internet surfaced a few other comments posted by others who were experiencing the same problem.

So, to correctly apply your changes on any farm configuration, be sure to perform the following two steps in your code:

  1. Use the ApplyWebConfigModifications() method on the SPWebApplication object you are saving your SPWebConfigModification object to. I don’t understand why this works over the other way, but it solved the problem for me. Example:

    Note: This code did not work across the farm (I could not tell you why).

    SPFarm.Local.Services.GetValue< SPWebService>().ApplyWebConfigModifications();
  2. Execute the Update() method on the SPWebApplication object. This will serialize the web application state and propagate changes across the farm – including your web.config changes.

So, whenever you want to save your modification to the web.config file, you should execute the following two statements.

// Save web.config changes.

// Applies the list of web.config modifications to all Web applications in this Web service across the farm.

Removing your modifications

You should remove your modifications by checking the owner property on each SPWebConfigModification object in the SPWebConfigModifications collection. There are many examples that demonstrate removing modifications by creating a new SPWebConfigModification object and then removing that object. A must simpler, cleaner, and safer method is to remove your original SPWebConfigModification object by checking the Owner property on the SPWebConfigModification object.  Credit goes to Vincent Rothwell for sharing this logic.  Here is an example:

public void RemoveConfiguration(string owner)
   if (myWebApp != null)
      Collection<SPWebConfigModification> collection = myWebApp.WebConfigModifications;
      int iStartCount = collection.Count;
      // Remove any modifications that were originally created by the owner.
      for (int c = iStartCount - 1; c >= 0; c--)
         SPWebConfigModification configMod = collection[c];
         if (configMod.Owner == owner)
      // Apply changes only if any items were removed.
      if (iStartCount > collection.Count)

Creating Sections
(EnsureSection vs. EnsureChildNode)

When creating new section you should use the EnsureChildNode modification type value instead of the EnsureSection. This will allow you to remove your custom section when the need arises. Antonz also discovered this as well and has an earlier post worth mentioning. Here is an example of the two options, both creating a section node like this: <mySection></mySection>

This cannot be removed (using EnsureSection):

SPWebConfigModification mod = new SPWebConfigModification("mySection", "configuration");
mod.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureSection;

This can be removed (using EnsureChildNode):

SPWebConfigModification mod = new SPWebConfigModification("mySection", "configuration");
mod.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
mod.Value = "<mySection />";

Save Only Once per Event or Feature Activation

It is important to remember that when developing and testing on a single server installation of SharePoint there are many activities that are able to complete instantly.  However, when that same section of code executes on a SharePoint farm with multiple servers the time it takes to complete a given task is longer.  This is due to timer jobs and farm synchronization events that must occur.

For this reason, you should only execute the ApplyWebConfigModifications() method only once within a feature activation or event handler.  If more than one call to the ApplyWebConfigModifications() method is made in close succession you will likely get the following error:

A web configuration modification operation is already running.

This is because request to save your changes from the first call to the ApplyWebConfigModifications() is not fully completed across the farm.

SPWebConfigModification Sample Feature

I intend to post a blog entry containing code samples of my WebConfigurator class and a sample of how to implement SPWebConfigModification using a web application feature.

Related Posts

WebConfigurator – a helper class to assist in using SPWebConfiguration.


Broken Trophy (social remedy for the build buster)

by Mark Wagner

February 29, 2004

I was asked this last Friday to bring my Broken Trophy to work.  The Broken Trophy has been very effective at improving the productivity of the development team in the past.  If you work on a project with a team of developers, this is a must-have item.

I am currently working on a project of 12 developers.  Each new development cycle typically translates into the code base changing quite rapidly from day to day, or even hour by hour at times.  This usually (and should) diminish as the development cycle progresses.  Of course, we often need to get the latest version of the code base to continue developing or unit testing our code.  Nothing can be more frustrating when you’re coding away, or "in the groove" as I say, and you get the latest code base only to realize your project now fails to compile.  Usually somebody failed to completely check in their code, or their code simply does not compile!  This can be very frustrating, especially during tight development time frame – is there any other kind.

Yes, we have all been in this situation, and dare we admit we have even been the one causing this problem for others.  No developer wants to be at either end of breaking the build.  For this, I suggest to you the Broken Trophy.  The broken trophy is exactly what it sounds like – the most hideous, obnoxious, large broken trophy you can find.  Again, the larger, the better.  This should not be easy to hide or tuck away in a corner.

I found this to be the most effective way of reducing the frequency at which developers break the build for others.  Of course, nobody wants this trophy, and you will find some developers resistant to this idea.  However, I have experienced that even those who are opposed to the Broken Trophy soon ease into accepting it once they begin to reap the benefits of its presents.

The Broken Trophy does wonders in many ways, all of which are often what you or your teammates either want to do or are doing in less productive ways, recognize it, vent it, and forget it.  I have seen this bring a team together.  After all, we are all human and we will make mistakes.  The idea is to reduce the frequency of these mistakes that hinder the productivity of others.  Everyone will eventually get the trophy.  It may take a little longer for some than others, but I have always seen it even out in the end.  When the trophy is awarded, we usually have a quick announcement and chuckle that lasts about 30 seconds.  Nothing more.

Rules for winning the Broken Trophy:

  • The code in the source control database does not successfully compile.  The trophy goes to the person who broke the build by checking in code preventing the code from compiling successfully. 
  • The last person to win the Broken Trophy retains possession until the next person earns it.  This may be a matter of hours or minutes; or it may be a matter of days or weeks.
  • Falsely accusing someone of breaking the build.  They may announce they think the build is broken, but not absolutely place ownership on someone.  Doing so will earn the false accuser the trophy, if in fact the build is not broken.  This has its benefits as you will see below.

Here are things that do not win the Broken Trophy:

  • The code does not have to function correctly or even function at all, as long as it compiles.  This may sound odd, but functional or bug-free code has nothing to do with this award.  Allowing the code to compile, allows other developers to continue developing and testing their code.  That is what matters – productivity.
  • If someone is in the middle of checking code in to the source control management database (SC).

There may be situations where there is a disagreement as to whether someone has earned the trophy or not.  The rules above are clear and will usually determine the answer.  If not, a simple majority vote will solve the problem.  However, this has rarely been needed.  If you lose the vote and are awarded the trophy, suck it up.  Your team will respect you for being an equal team member.

Here is a list of the few outcomes you will get:

  • The team will find it easier to laugh about the problem instead of getting frustrated.
  • The team gets satisfaction in knowing the problem is being recognized.  This alone will begin to reduce the frequency of build-busting mistakes.  Your team will also become more aware of the lazy mistakes that have earned them (or others) the trophy, and they will be more intent on not making them again.
  • The team gets a chance to vent about it.  However, the venting is normally not an issue since the presentation of the trophy says it all.  There is rarely any need or desire to discuss it any more.  Point made, venting done!
  • The team can forget about the issue.  Although, jokes will continue at the recipients expense, they will soon subside once the trophy is awarded.  This is especially true as the trophy makes its way around the team.  The problem has been addressed!
  • Usually, the root cause of the broken build is researched and resolved before the trophy is even awarded.  This causes the team to focus on solving the problem first.  This is a beautiful outcome.  Remember, false broken build accusations can win the trophy as well.  Therefore, the whistle blower soon becomes very diligent in determining the problem before “officially“ sounding the Broken Trophy alarm.
  • After the trophy has been awarded to a few people, it will become easier to award and easier to receive, and the team will soon begin to recognize the reduction in build errors.  The confidence of the code in your SC database will begin to improve.

I have seen this work very well.  In fact, it has always work well.  The important point is to remember that this is all in good fun and good productivity for the entire team.  Some may see this as being controversial or a public fogging.  I have never seen this be the case.  The first person to win the trophy is usually the hardest to award – and receive.  When presenting the trophy the first time be sure to remind everyone of this.  As long as everyone focuses on the lighter side, your entire team will win.