Developer News, SPDisposeCheck Released and Updated Developer Guidance

Today we announced the availability of SPDisposeCheck and updated the guidance [Using Disposable Windows SharePoint Services Objects].  The published guidance provides best practices to follow when using Windows SharePoint Services objects to avoid retaining the objects in memory in the Microsoft .NET Framework, SPDisposeCheck facilitates a programmatic method to enable developers to efficiently adhere to that guidance throughout the development lifecycle.

Learn more and download SPDisposeCheck


Developing Web Parts, considerations on Microsoft SharePoint Products and Technologies

Background Information

Web Parts as defined by MSDN are an integrated set of controls for creating Web sites that enable end-users to modify the content, appearance, and behavior of Web pages in a browser.

In Windows SharePoint Services 3.0 Web Parts ultimately derive from the ASP.WebPart (System.Web.UI.WebControls.WebParts) base class; however, Windows SharePoint Services 3.0 also has a Web Part base class (Microsoft.SharePoint.WebPartPages.WebPart) derived from the ASP.WebPart class.  If you are developing Web Parts you can elect to derive from either the Asp.WebPart or WSS.WebPart; however you should carefully consider your approach before developing custom Web Parts for use with Windows SharePoint Services 3.0.  To help define the differences, we’ll examine each class and their respective pros and cons.

ASP.NET Web Parts

When deriving from the ASP.WebPart your Web Part derives directly from the ASP.WebPart class which does not have a dependency on Windows SharePoint Services 3.0 code so it can be used in both ASP.NET Web sites or a Windows SharePoint Services 3.0 site collection/Web.  To ensure the Web Part customization is sustainable you should consider using the ASP.WebParts.  ASP.WebParts are exportable using the .webpart extension, can be displayed in SPD using attribute markup and are persisted to the Windows SharePoint Services store in binary Web Part format.

Hybrid (ASP.NET 2.0 + Windows SharePoint Services Web Parts)

Hybrid Web Parts typically derive from the Wss.WebPart base class; however, adhere to the design guidelines for ASP.WebParts though the dependency on WSS.WebPart implies its use strictly in a Windows SharePoint Services 3.0 site collection/Web.  Hybrid Web Parts should be considered only where features provided in the WSS.WebParts class are required, for example, client-side connections.  Hybrid Web Parts can also be used in version to version upgrades where the existing legacy hybrid Web Part cannot be retired in favor of a ASP.WebPart.  Hybrid Web Parts are exportable using the .webpart extension, can be displayed in SPD using attribute markup and are persisted to the Windows SharePoint Services store in binary Web Part format.

Windows SharePoint Services Web Parts

WSS Web Parts derive from the WSS.Web Part base class and meet the guidelines as provided by the Windows SharePoint Services 2.0 Web Part design guidelines.  The WSS.WebPart class is obsolete and is retained solely for backwards compatibility.  Wss.WebParts are exportable using the .dwp extension, can be displayed in SPD using XML Markup and are persisted to the WSS store in a compressed XML format.

The bottom line is, if you are considering developing custom Web Parts you should consider deriving from the System.Web.UI.WebControls.WebParts.WebPart class and referencing the MSDN guidance on developing ASP.NET Web Parts to ensure the Web Parts to maximize interoperability and sustainability.


Working with ASP.NET 2.0 Web Parts and Windows SharePoint Services 3.0


Discover Significant Developer Improvements in SharePoint Services (Integration with ASP.NET 2.0 Web Parts)


Use Windows SharePoint Services as a Platform for Building Collaborative Apps, Part 2


Windows SharePoint Services Developer Center


Developing Web Parts (Developer Center)


Windows SharePoint Services Version Comparison



Master Page Example

I used the sample master pages at http://office.microsoft.com/en-us/sharepointdesigner/HA102223711033.aspx in several Feature Stapling/Receiver demonstrations over the past year and was asked if I could provide the solution package I compiled using the Clarity master page (see image) in conjunction with a Feature Receiver to update the master page on both site collections and Webs.  I’ve finally gotten around to uploading the .wsp, so for those interested it can be downloaded here.


Copy the Clarity Master Page.wsp to a location on a Web front-end computer.

Open a Command Prompt and change directories to %commonprogramfiles%Microsoft SharedWeb Server Extensions12BIN.

Run STSADM -o addsolution -filename "<path>Clarity Master Page.wsp" and wait for the operation to complete.

Run STSADM -o deploysolution -name "Clarity Master Page.wsp" -immediate -force -allowGacDeployment and wait for the operation to complete.

Run STSADM -o execadmsvcjobs and wait for the operation to complete.

NOTE Existing site collections will not be affected and can be modified either through SPD or the SharePoint UI.

Newly created site collections and Webs will receive the Clarity master page.


Microsoft IT Site Delete Capture LE Version 1.0 Released

Microsoft IT Site Delete Capture LE version 1.0 has been released.

Microsoft Site Delete Capture LE version 1.0 is an Windows SharePoint Services 3.0 solution package that when deployed to a Windows SharePoint Services 3.0 or Microsoft Office SharePoint Server 2007 server farm enables administrators to create a snapshot of site collections and Webs when they are deleted through the SharePoint user interface, the SharePoint Administration Tool, or Microsoft Office SharePoint Designer 2007.

Microsoft IT Site Delete Capture LE 1.0 is a light-weight implementation of the Microsoft IT Site Delete Capture 1.0 offered as a Windows SharePoint Services 3.0 solution package. This build does not include e-mail notification logic and introduces deprecated application event logging.

Read more…


Migrating User Accounts in Windows SharePoint Services

While attending Ask the Experts at the Microsoft Office SharePoint Server Conference 2008, I was asked about migrating user accounts in Windows SharePoint Services 3.0 to a new login name programmatically, fortunately Windows SharePoint Services addressed user account migrations with the Windows SharePoint Services 2.0 post SP1 hotfix package 896593 which was followed by a number of applications including SPUserUtil Keith Richie corrected me today – SPUserUtil preceeded the MigrateUser API – Thanks Keith!.  The good news is that with the exception of minor OM changes, the base functionality is retained in WSS 3.0.

Programmatically (Multiple User Scenarios)

Where working with a large number of users, you may wish to programmatically migrate those users using the MigrateUserAccount method which migrates a user account in WSS to a new login name and binary Id updating the site collection user in the UserInfo tables, people lists, and security policies across the farm. The MigrateUserAccount method is a member of the Microsoft.SharePoint.Administration namespace, SP Farm class and takes three arguments, oldLogin, newLogin, and enforceSidHistory.

  1. oldLogin is the is the login name you would like to modify – if the login name exists, it will be deleted to allow the change.

  2. newLogin is the desired login name.

  3. enforceSidHistory will query the Active Directory for the SID history attribute to ensure that the new logon name is truly correspondent to the old one (checks and balances).  NOTE Set enforceSidHistory to False when working with non-Windows user accounts, for example, Forms-Based Authentication users.

Sample Code

using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace MigrateUser
class Program
static void Main(string[] args)
SPFarm Farm = SPFarm.Local;
Farm.MigrateUserAccount(“CONTOSO\UserA”, “CONTOSO\UserB”, true);

This code snippet is provided under the Microsoft Permissive License.

NOTE  WSS stores user information based on both the Security Identifier and user logon information, when either changes in Active Directory, WSS needs to be updated with the new user information otherwise that user will be unable to access the WSS environment.

SharePoint Administration Tool (Single User Scenarios)

User accounts can also be migrated using the SharePoint Administration Tool (STSADM) migrateuser operation documented here http://technet2.microsoft.com/windowsserver/WSS/en/library/f9f9a3eb-ce46-4dbb-a15c-9fad9eb32ec71033.mspx?mfr=trueNOTE The ignoresidhistory parameter should be set to True when working with non-Windows user accounts, for example, Forms-Based Authentication users. Where working with a large number of users that are migrated in Active Directory subsequently changing those users corresponding Security Identifiers and/or where modifying the logon information for those users consider utilizing the MigrateUserAccount method to reduce the administration overhead of working with single user entities on a one by one basis.


Deploying ProClarity Viewer 6.3 for SharePoint

I was recently asked to deploy the ProClarity Viewer 6.3 for SharePoint Web Part – after downloading the package I realized that it was not offered in a deployable package, but rather a compressed archive of the .dwp, assembly, and resource files.  The challenge became offering a user experience similar to the previous ProClarity Viewer version so I decided to package the Web Part into a reusable solution.  For those interested or looking to create a deployable Web Part package I’ve documented the steps below:

Step 1 Create a Manifest

The Manifest file is a required configuration file that describes the contents and overall structure of the cabinet file.  STSADM will use the Manifest file to deploy the contents of the cabinet file when executing the addwppack operation.

    <Assembly FileName=”SPSPageViewer.dll“>
        <SafeControl Assembly=”SPSPageViewer, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ Namespace=”SPSPageViewer” TypeName=”*” Safe=”True” />
        <ClassResource FileName=”images/Book.gif“/>
        <ClassResource FileName=”images/Folder.gif“/>
        <ClassResource FileName=”images/Library.gif“/>
        <ClassResource FileName=”images/Page.gif“/>
        <ClassResource FileName=”images/TPMax2.gif“/>
        <ClassResource FileName=”images/TPMin2.gif“/>
        <ClassResource FileName=”images/Unknown.gif“/>
        <ClassResource FileName=”images/up.gif“/>
    <DwpFile FileName=”PasPageViewer.dwp“/>

The <Assemblies> node contains the overall definitions for each of the assemblies being deployed, the child <Assembly> node uses the FileName attribute to define the assembly file name, in this case SPSPageViewer.dll, and contains the definitions for the class resources in addition to the XML for the SafeControls list.  The XML for the SafeControls list can be found in the ProClarity Viewer Web Part Setup Guide or optionally copied from the example above.  This information will be written to the web.config for the Web application(s) when the solution is deployed to the SharePoint Products and Technologies server farm using the SharePoint administration tool (STSADM).

The <ClassResources> node contains the base definitions for each class resource that will be deployed, the child <ClassResource> node uses the FileName attribute to define the class resource file name, in this case each of the images accompanying the Web Part are defined in a <ClassResource> node with their path relative to wpresources at a global or localized level.

The <DwpFiles> node contains the definitions for each .dwp file being deployed, the child node <DwpFile> uses the FileName attribute to define the file name of the .dwp file, in this case the .dwp file name accompanying the downloaded Web Part archive is PasPageViewer.dwp.

The complete Manifest file should appear as follows:

<?xml version=”1.0″?>
<WebPartManifest xmlns=”http://schemas.microsoft.com/WebPart/v2/Manifest”>
    <Assembly FileName=”SPSPageViewer.dll”>
        <SafeControl Namespace=”SPSPageViewer” TypeName=”*” />
        <ClassResource FileName=”images/Book.gif”/>
        <ClassResource FileName=”images/Folder.gif”/>
        <ClassResource FileName=”images/Library.gif”/>
        <ClassResource FileName=”images/Page.gif”/>
        <ClassResource FileName=”images/TPMax2.gif”/>
        <ClassResource FileName=”images/TPMin2.gif”/>
        <ClassResource FileName=”images/Unknown.gif”/>
        <ClassResource FileName=”images/up.gif”/>
    <DwpFile FileName=”PasPageViewer.dwp”/>

Step 2 Create a MakeCab Directives File

The MakeCab directives file controls how files are compresses in a cabinet.

Create a logical file structure by copying Book.gif, Library.gif, Page.gif, TPMax.gif, TPMin.gif, Unknown.gif, and up.gif to /images.  *You will need to create the images directory in your cabinet directory.  The directives file is also used to define the name of the cabinet file.

.Set CabinetNameTemplate=ProClarity63.cab
.set DiskDirectoryTemplate=CDROM
.Set CompressionType=MSZIP
.Set UniqueFiles=’ON’
.Set Cabinet=on
.Set DiskDirectory1=.
“C:ProClarity63imagesBook.gif”    “imagesBook.gif”
“C:ProClarity63imagesFolder.gif”    “imagesFolder.gif”
“C:ProClarity63imagesLibrary.gif”    “imagesLibrary.gif”
“C:ProClarity63imagesPage.gif”    “imagesPage.gif”
“C:ProClarity63imagesTPMax2.gif”    “imagesTPMax2.gif”
“C:ProClarity63imagesTPMin2.gif”    “imagesTPMin2.gif”
“C:ProClarity63imagesUnknown.gif”    “imagesUnknown.gif”
“C:ProClarity63imagesup.gif”        “imagesup.gif”
“C:ProClarity63PasPageViewer.dwp”     “PasPageViewer.dwp”
“C:ProClarity63SPSPageViewer.dll”    “SPSPageViewer.dll”
“C:ProClarity63Manifest.xml”        “Manifest.xml”
;*** <the end>

Step 3 Create the Cabinet

To create the cabinet file execute MakeCab.exe /F <filename>.ddf where <filename> is the name of your directives file.  The cabinet file when a source destination is not specified is commonly created under C:Documents and Settings<user>.

Step 4 Deployment

To deploy the Web Part package, copy <cabinet>.cab to a location on one Web front-end server.

Execute STSADM -o addwppack -filename <cabinet>.cab [-globallinstall].

Step 5 Verify Deployment

The Web Part package will be listed in the list of available/deployed solutions to the SharePoint Products and Technologies server farm under SharePoint 3.0 Central Administration | Operations | Solutions Management (see image).


To review deployment details, retract, or remove the solution click <cabinet>.cab (see image).


Step 6 Add the ProClarity Viewer to a Page

To add the ProClarity Viewer Web Part to a page, navigate to a site collection and select Site Actions | Edit Page.

Select a Web Part zone and click Add Web Part.

Select ProClarity Viewer from the list of available Web Parts and click Add.


Ghosts in the Machine?

Ghosted and unghosted pages are references not new to Microsoft Office SharePoint Server 2007, but have received increased interest as a result of their impact on upgrading from previous versions and more recently, the ability to manage pages in an unghosted state.


Ghosted is the preferred state of pages in a site collection, ghosted pages refer to site definition files cached in memory on the server at process startup of IIS.  By caching site definition files in memory performance and scalability are improved by reducing data storage and retrieval requirements.  Ghosted pages can be reused as a result across one or many site collections on the Web application.

Unghosted pages are most commonly the result of customization through Microsoft FrontPage and/or Microsoft Office SharePoint Designer and are stored in the corresponding content database.  The contents of unghosted pages are routed through safe mode parsing in ASP.NET, which prevents server-side code from executing, and which depends entirely on the Safe Controls list specified in the web.config file of the wwwroot directory to determine which controls can be rendered at run time.  When upgrading unghosted pages in SharePoint Portal Server 2003 and or Windows SharePoint Services 2.0, some functionality is lost until the page is reset to its site definition (ghosted) and can include security trimming, navigation (Site Actions), Recycle Bin, and other core Microsoft Office SharePoint Server 2007 functionality.  The performance penalty of unghosted pages in Microsoft Office SharePoint Server 2007 is less evident when compared to previous versions due to enhancements in the .NET 2.0 runtime.

So how do pages become unghosted?

In most cases an unghosted page is the result of customization through Microsoft FrontPage and/or Microsoft Office SharePoint Designer 2007 – browser based modifications such as the manipulation of Web Parts will not cause the page to be unghosted.  In a change over Microsoft FrontPage, Microsoft Office SharePoint Designer users are presented with a prompt to indicate the page they are working with will no longer be associated with its specified site definition (see illustration).


In many cases users can resolve minor customizations through resetting the page to its site definition through both the Windows SharePoint Services 3.0 user interface and Microsoft Office SharePoint Designer; however, changes made within Web Part Zones will be retained after synchronizing the page with its site definition.  [Site Settings | Look and Feel | Reset to site definition]. 

In some circumstances a page cannot be reghosted, for example if the page was not based on an existing page, was created from a blank page, imported from another application or editor or (most commonly) was associated with a site definition no longer available to the server farm – this can occur if a site definition was retired or a database migration approach was implemented and the upgrade definition not made available to the target server farm.  In many cases you can simply copy a known good <page>.aspx from an alternate location and retrofit it to restore functionality.


Reghosting can be also accomplished through by a server farm administration calling the RevertAllDocumentContentStreams method of the Microsoft.SharePoint namespace on each SPWeb object.

Sample Code

        static void Main(string[] args)
string siteUrl = “”;
SPSite Site = new SPSite(siteUrl);
foreach (SPWeb Web in Site.AllWebs)

This code snippet is provided under the Microsoft Permissive License.

Microsoft Office SharePoint Designer 2007

  1. In Office SharePoint Designer 2007, open the Web site where the customized page resides.
  2. Right-click the page that you want to reset to the site definition, and then click Reset to Site Definition on the shortcut menu.

NOTE A copy of the customized page is placed in the same directory where the reset page resides and is named file name_copy(1), where file name is the original file name – when reghosting a page through the Windows SharePoint Services 3.0 user interface a backup copy of the page is not created.


If the customization was implemented on a MasterPage, the MasterPage and attached pages can be reset to their site definition through Microsoft Office SharePoint Designer 2007:

In Office SharePoint Designer 2007, open the Web site where the customized master page resides.

  1. Right-click the master page that you want to reset, such as default.master, and then click Reset to Site Definition on the shortcut menu.

    Note   By default, in the Folder List, master pages are located in the masterpages folder, which is in the _catalogs folder in the site.

    A warning message informs you that the master page’s contents will be overwritten, but that a backup copy of the current page will be created.

  2. Click Yes.

Ghosted Pages and Upgrade

Ghosted pages, though, in many cases can be upgraded safely depending on the extent of their customization (see introduction for caveats) should be considered for reghosting at the time they are upgraded.  The gradual upgrade approach allows administrators to reghost (reset to site definition) pages during the upgrade process and enables the reghosting of pages at a more granular level.  Reghosting in a gradual approach can be applied through the Upgrade user interface or optionally using the STSADM -o command line argument -Reghost in the upgrade operation, for example STSADM -o upgrade -sidebyside -url http://www.contoso.com -sitelistpath <pathtoxml> -reghost.  This granularity allows you to decide where you would like to reghost and what customizations should be retained during the upgrade.  The database migration approach and inplace approaches both permit the upgrade of unghosted pages preserving the customizations; however, these pages will be upgraded in their existing state and will need to be reghosted post-upgrade to enable Microsoft Office SharePoint Server 2007 functionality.

Locating Unghosted Pages

Now that we understand ghosted vs. unghosted pages and their implication on upgrade, how do we determine where unghosted pages exist?


PRESCAN.EXE has two primary purposes:

  1. It parses and saves List definitions with the associated Lists.  SharePoint Portal Server 2003 Service Pack 2 already incorporates this feature whenever a list is modified; however, this process should be completed for all Lists, so prescan calls the SharePoint Portal Server 2003 Service Pack 2 method to persist that data.
  2. PRESCAN.EXE will report on common issues that will result in a failed upgrade; therefore, running PRESCAN.EXE, addressing reported issues, and resolving those issues, and re-running PRESCAN.EXE to verify those fixes is a best practice when planning a Microsoft Office SharePoint Server 2007/Windows SharePoint Services 3.0 upgrade.  The most commonly detected issues are:

    • Database Orphans This is a class of issue where an object exists, but the pointer with the parent object is broken and/or corrupt.   Classic examples include situations where a site exists in the content database; however, does not exist in the configuration database and a web that points to a site collection that no longer exists. 
    • Missing Site Definitions This issue is rare at best ad exists when a site collection has been removed/deleted – sites under this classification will not be upgraded and in addition those sites will not render in SharePoint Portal Server 2003/Windows SharePoint Services 2.0.

PRESCAN can be used to identify custom Site Definitions, FrontPage customizations, Web Parts, etc.

PRESCAN.EXE will report and summarize any unghosted pages occurring in your environment (see illustrations).

The example above illustrates unghosted pages discovered by PRESCAN.EXE and reported in the application log file.

The example above illustrates a summary of unghosted pages.


Alternatively SQL can be leveraged (not recommended on production databases) to generate a report of unghosted pages in your content databases (see example).





     (Docs.Type = 0)


     (Docs.SetupPath IS NOT NULL) AND

     (dbo.Docs.DocFlags & 64 = 64)

Microsoft Office SharePoint Designer 2007

You can also run a report in Office SharePoint Designer 2007 to list all of the customized pages in your site.

  1. In Office SharePoint Designer 2007, open the Web site for which you want to run the report.
  2. On the Site menu, point to Reports, point to Shared Content, and then click Customized Pages.

    The report opens with all pages in the site listed, and the Customized column indicates whether content has been customized for that page.

  3. To display only pages that have been customized, click the down arrow to the right of the Customized column, and then click Yes.

    The report now displays only pages that have been customized.

Additional Resources

Joel Oleson’s To Ghost or Not to Ghost, That is the Question

MSDN – Custom Site Defintiions

Microsoft.com – SharePoint Application Templates

This Blog – PRESCAN

Microsoft.com – Upgrade Considerations for Customized Sites

Technet – Determine How to Handle Customizations