<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Random Musings of Jeremy Jameson : My System</title><link>http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx</link><description>Tags: My System</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Building SharePoint WSPs with Team Foundation Build</title><link>http://blogs.msdn.com/jjameson/archive/2009/11/18/building-sharepoint-wsps-with-team-foundation-build.aspx</link><pubDate>Wed, 18 Nov 2009 13:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9924271</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9924271.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9924271</wfw:commentRss><description>&lt;P&gt;As I noted in my &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/11/18/the-copy-local-bug-in-visual-studio.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/11/18/the-copy-local-bug-in-visual-studio.aspx"&gt;previous post&lt;/A&gt;, I recently discovered that &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/28/sample-walkthrough-of-the-dr-dada-approach-to-sharepoint.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/28/sample-walkthrough-of-the-dr-dada-approach-to-sharepoint.aspx"&gt;my approach for building Web Solution Packages (WSPs)&lt;/A&gt; in Microsoft Office SharePoint Server (MOSS) 2007 isn't compatible with Team Foundation Build.&lt;/P&gt;
&lt;P&gt;I'm actually a little embarrassed to say this, but when I created the original &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/03/31/introducing-the-dr-dada-approach-to-sharepoint-development.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/03/31/introducing-the-dr-dada-approach-to-sharepoint-development.aspx"&gt;"DR.DADA" approach for MOSS 2007&lt;/A&gt; development back on the Agilent Technologies project, we were using Visual SourceSafe -- not Team Foundation Server (TFS) -- and a "manual" build process.&lt;/P&gt;
&lt;P&gt;I'd used VSS and automated builds on other projects before (using NAnt), but never got around to automating our MOSS 2007 builds on the Agilent project because, honestly, there were just too many other higher priority items. Besides, each build only required a couple of minutes of actual human effort because most of the build was scripted.&lt;/P&gt;
&lt;P&gt;Still, an automated daily build (and deployment to DEV) is a &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/26/best-practices-for-scm-and-the-daily-build-process.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/26/best-practices-for-scm-and-the-daily-build-process.aspx"&gt;really, really good thing to have&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;I've been fortunate to be on a few projects since then that have leveraged TFS.&lt;/P&gt;
&lt;P&gt;However, up until about a month ago, I hadn't used Team Foundation Build (outside of the &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx"&gt;Jameson Datacenter&lt;/A&gt;, of course) due to the fact that we are leveraging the extranet TFS instance hosted by Microsoft.&lt;/P&gt;
&lt;P&gt;Note that Microsoft IT makes it very easy for us to provision new TFS projects on either the extranet or one of several internal TFS instances. Configuring builds using Team Foundation Build on one of the intranet TFS instances is very easy (from what I hear), but I strongly prefer working off the extranet TFS instance because then I don't have to VPN into CorpNet in order to have access to source control.&lt;/P&gt;
&lt;P&gt;However, choosing the extranet TFS instance also means we can't configure builds using the out-of-the-box functionality in Team Foundation Server (at least not without setting up a build server on the extranet). Fortunately, I've found a way to schedule "manual" builds that look a lot like automated builds performed using Team Foundation Build.&lt;/P&gt;
&lt;P&gt;So, if you are building SharePoint WSPs -- regardless of whether you use the real Team Foundation Build or my "imitation Team Foundation Build" -- you need a way to build the WSPs without referring to referenced assemblies using relative paths.&lt;/P&gt;
&lt;P&gt;As I first mentioned in my previous post, relative paths work just fine when compiling from within Visual Studio or using MSBuild from the command line. However, they don't work at all when queuing the builds through Team Foundation Build.&lt;/P&gt;
&lt;P&gt;The problem with relative paths is that Team Foundation Build uses a different folder structure when compiling your projects. Specifically, it changes the output folder for all compiled items to be under a new &lt;STRONG&gt;Binaries &lt;/STRONG&gt;folder -- not the location specified in the project settings within Visual Studio.&lt;/P&gt;
&lt;P&gt;In other words, if you refer to a referenced assembly using something like:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;..\..\..\CoreServices\bin\%BUILD_CONFIGURATION%\Fabrikam.Demo.CoreServices.dll&lt;/BLOCKQUOTE&gt;
&lt;P&gt;then you will find that this works just fine when building through Visual Studio -- or even when compiling using TFSBuild.proj from the command line (a.k.a. a "Desktop Build"). However, if you then queue the build through Team Foundation Server, you'll find your build fails because the referenced assembly was actually output to a different folder.&lt;/P&gt;
&lt;P&gt;If you dive into the log file for the build, you will find that Team Foundation Build modifies the &lt;STRONG&gt;OutDir &lt;/STRONG&gt;variable and sets it to something like:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;C:\Users\svc-build\AppData\Local\Temp\Demo\Daily Build - Main\Binaries\Debug\&lt;/BLOCKQUOTE&gt;
&lt;P&gt;So the trick to building WSPs with Team Foundation Build is to leverage the &lt;STRONG&gt;OutDir &lt;/STRONG&gt;variable instead of relying on relative paths to referenced assemblies.&lt;/P&gt;
&lt;P&gt;Here is the updated DDF file based on &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/28/sample-walkthrough-of-the-dr-dada-approach-to-sharepoint.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/28/sample-walkthrough-of-the-dr-dada-approach-to-sharepoint.aspx"&gt;my earlier sample&lt;/A&gt;:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;;
; This ddf specifies the structure of the .wsp solution cab file.
;
; HACK: OPTION EXPLICIT cannot be used when specifying a variable with the /D option,
; otherwise MakeCAB aborts with an error similar to the following:
;
;        ERROR: Option Explicit and variable not defined: OUT_DIR
;
;.OPTION EXPLICIT    ; Generate errors for undefined variables

.Set CabinetNameTemplate=Fabrikam.Demo.Publishing.wsp

; The following variable must be set when calling MakeCAB (using the /D option)
;.Define OUT_DIR=

.Set DiskDirectoryTemplate=CDROM    ; All cabinets go in a single directory
.Set CompressionType=MSZIP            ; All files are compressed in cabinet files
.Set UniqueFiles=ON
.Set Cabinet=ON
.Set DiskDirectory1=%OUT_DIR%\Package

DeploymentFiles\PackageFiles\manifest.xml

.Set SourceDir=%OUT_DIR%            ; Copy assemblies from %OUT_DIR% folder

Fabrikam.Demo.Publishing.dll
Fabrikam.Demo.CoreServices.dll

.Set SourceDir=                    ; Copy files relative to project folder

.Set DestinationDir=Fabrikam.Demo.Publishing.DefaultSiteConfiguration
DefaultSiteConfiguration\FeatureFiles\Feature.xml

.Set DestinationDir=Fabrikam.Demo.Publishing.Layouts
Layouts\FeatureFiles\Feature.xml
Layouts\FeatureFiles\ProvisionedFiles.xml

.Set DestinationDir=Fabrikam.Demo.Publishing.Layouts\MasterPages
Layouts\MasterPages\FabrikamMinimal.master

;.Set DestinationDir=Fabrikam.Demo.Publishing.Layouts\PageLayouts
;Layouts\PageLayouts\MinimalPage.aspx

.Set DestinationDir=Fabrikam.Demo.Publishing.Layouts\Images
Layouts\Images\FabrikamLogo_32x32.png

.Set DestinationDir=Fabrikam.Demo.Publishing.Layouts\Themes\Theme1
Layouts\Themes\Theme1\BreadcrumbBullet.gif
Layouts\Themes\Theme1\FauxColumn-Fixed-2Col.png
Layouts\Themes\Theme1\FauxColumn-Fixed-3Col.png
Layouts\Themes\Theme1\Fabrikam-Basic.css
Layouts\Themes\Theme1\Fabrikam-Core.css
Layouts\Themes\Theme1\Fabrikam-FixedLayout.css
Layouts\Themes\Theme1\Fabrikam-IE.css
Layouts\Themes\Theme1\Fabrikam-IE6.css
Layouts\Themes\Theme1\Fabrikam-QuirksMode.css
Layouts\Themes\Theme1\Tab-LeftSide.jpg
Layouts\Themes\Theme1\Tab-RightSide.jpg

.Set DestinationDir=ControlTemplates\Fabrikam\Demo\Publishing\Layouts
Layouts\Web\UI\WebControls\GlobalNavigation.ascx
Layouts\Web\UI\WebControls\StyleDeclarations.ascx

.Set DestinationDir=Layouts\Fabrikam
Layouts\MasterPages\FabrikamMinimal.master&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Note how I've replaced the BUILD_CONFIGURATION variable with the OUT_DIR variable. Not surprisingly, the OUT_DIR variable in the DDF is specified similar to how BUILD_CONFIGURATION was previously specified when calling makecab.exe. However, unlike the build configuration the OutDir variable will likely contain spaces as well as a trailing slash (which makecab.exe apparently doesn't like). Therefore we must quote the OutDir variable and append with "." if a trailing slash is found.&lt;/P&gt;
&lt;P&gt;Here is the corresponding update to the project file:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;SPAN style="COLOR: #0000ff"&gt;  &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;PropertyGroup&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;BuildDependsOn&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;
&lt;/SPAN&gt;      $(BuildDependsOn);
      CreateSharePointSolutionPackage
&lt;SPAN style="COLOR: #0000ff"&gt;    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;BuildDependsOn&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;QuotedOutDir&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;"$(OutDir)"&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;QuotedOutDir&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;QuotedOutDir&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;Condition&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;HasTrailingSlash($(OutDir))&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;"$(OutDir)."&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;QuotedOutDir&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;
  &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;PropertyGroup&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;
  &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Target&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;CreateSharePointSolutionPackage&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;Inputs&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;@(None);@(Content);$(OutDir)$(TargetFileName);&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;Outputs&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;$(ProjectDir)$(OutDir)Package\Fabrikam.Demo.Publishing.wsp&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Message&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;Text&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;Creating SharePoint solution package...&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt; /&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Exec&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;Command&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;makecab /D OUT_DIR=$(QuotedOutDir) /F &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;&amp;amp;quot;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;$(ProjectDir)DeploymentFiles\PackageFiles\wsp_structure.ddf&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;&amp;amp;quot;&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt; /&amp;gt;
  &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Target&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;With these changes, the SharePoint WSP is successfully built regardless of whether it is compiled through Visual Studio, from the command line using MSBuild and the TFSBuild.proj file, or as an automated build using a Team Foundation Build server.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9924271" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Simplify/default.aspx">Simplify</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/MOSS+2007/default.aspx">MOSS 2007</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/WSS+v3/default.aspx">WSS v3</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/TFS/default.aspx">TFS</category></item><item><title>A Simple Backup Solution</title><link>http://blogs.msdn.com/jjameson/archive/2009/11/09/a-simple-backup-solution.aspx</link><pubDate>Mon, 09 Nov 2009 13:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9919509</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9919509.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9919509</wfw:commentRss><description>&lt;P&gt;As I've mentioned before, I don't spend much money or time maintaining the &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx"&gt;"Jameson Datacenter"&lt;/A&gt; (a.k.a. my home lab). However, that doesn't mean that I treat my infrastructure lightly.&lt;/P&gt;
&lt;P&gt;In previous posts, I've covered many of the Group Policy objects that I use to minimize the maintenance effort associated with running more than a dozen servers (mostly virtual). In this post, I'll provide the details on how I backup these servers.&lt;/P&gt;
&lt;P&gt;I should preface this by saying this is not meant to be an "enterprise-level" backup solution. Rather it is simply meant to provide a cheap (actually free) and easy solution to the problem of ensuring you can recover from data loss. Note that data loss rarely occurs through some sort of hardware failure or Act of God (as the insurance folks like to put it). Rather the majority of the time someone accidentally overwrites or deletes a file -- or, gasp, a complete folder hierarchy -- and you subsequently need to restore the data from a backup.&lt;/P&gt;
&lt;P&gt;For as long as I can remember, Windows Server has included the NTBackup utility. I'm guessing from the name that this has been around since the days of Windows NT 3.1, but honestly I don't believe I even started running Windows NT until version 3.5. Or was it 3.51? I can't remember. Anyway, I certainly haven't been running NTBackup since then.&lt;/P&gt;
&lt;P&gt;Here is the simple batch file that I use to perform scheduled backups:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;@echo off

setlocal

set BACKUP_TYPE=normal

if ("%1") NEQ ("") set BACKUP_TYPE=%1

for /f "tokens=2-4 delims=/ " %%i in ('date /t') do set currentDate=%%k-%%i-%%j
for /f "tokens=1-2" %%i in ('time /t') do set currentTime=%%i %%j
set BACKUP_TIMESTAMP=%currentDate%-%currentTime:~0,2%-%currentTime:~3,2%-%currentTime:~6,2%

set BACKUP_FILE=D:\NotBackedUp\Backups\Backup-%BACKUP_TYPE%-%BACKUP_TIMESTAMP%.bkf

:: ----------------------------------------------------------------------------
call :LogMessage "Starting backup..."
call :LogMessage "BACKUP_TYPE: %BACKUP_TYPE%"
call :LogMessage "BACKUP_FILE: %BACKUP_FILE%"

C:\WINDOWS\system32\ntbackup.exe backup C:\BackedUp /n "Backup created %BACKUP_TIMESTAMP%" /m %BACKUP_TYPE% /j "Backup (%BACKUP_TYPE%)" /f "%BACKUP_FILE%"
if %ERRORLEVEL% neq 0 goto Errors

call :LogMessage "Successfully completed backup."

goto :eof

:: ----------------------------------------------------------------------------
::
:LogMessage

REM Strip leading and trailing quotes and then display message with timestamp
set MESSAGE=%1
set MESSAGE=%MESSAGE:~1,-1%

for /f "tokens=2-4 delims=/ " %%i in ('date /t') do set currentDate=%%k-%%i-%%j
for /f "tokens=1-2" %%i in ('time /t') do set currentTime=%%i %%j
echo %currentDate% %currentTime% - %MESSAGE%

goto :eof

:: ----------------------------------------------------------------------------
::
:Errors

echo Warning! One or more errors detected.&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;If you've seen any of my scripts before, then you'll quickly notice the typical &lt;CODE&gt;LogMessage&lt;/CODE&gt; "function" that I use to write messages prefixed with a timestamp. For example here's the output from the log for this morning's backup:&lt;/P&gt;
&lt;DIV class=logExcerpt&gt;&lt;PRE&gt;&lt;SAMP&gt;2009-11-09 12:30 AM - Starting backup...
2009-11-09 12:30 AM - BACKUP_TYPE: differential
2009-11-09 12:30 AM - BACKUP_FILE: D:\NotBackedUp\Backups\Backup-differential-2009-11-09-12-30-AM.bkf
2009-11-09 12:31 AM - Successfully completed backup.&lt;/SAMP&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;I use similar token parsing of the output from the &lt;STRONG&gt;&lt;A href="http://technet.microsoft.com/en-us/library/cc732776(WS.10).aspx" mce_href="http://technet.microsoft.com/en-us/library/cc732776(WS.10).aspx"&gt;date&lt;/A&gt;&lt;/STRONG&gt; and &lt;A href="http://technet.microsoft.com/en-us/library/cc770579(WS.10).aspx" mce_href="http://technet.microsoft.com/en-us/library/cc770579(WS.10).aspx"&gt;&lt;STRONG&gt;time&lt;/STRONG&gt;&lt;/A&gt; system commands to generate the name of the backup file (e.g. &lt;SAMP&gt;Backup-differential-2009-11-09-12-30-AM.bkf&lt;/SAMP&gt;).&lt;/P&gt;
&lt;P&gt;Also note that the &lt;A href="http://technet.microsoft.com/en-us/library/cc784306(WS.10).aspx" mce_href="http://technet.microsoft.com/en-us/library/cc784306(WS.10).aspx"&gt;type of backup&lt;/A&gt; (e.g. &lt;STRONG&gt;normal &lt;/STRONG&gt;or &lt;STRONG&gt;differential&lt;/STRONG&gt;) can be specified as a parameter when running the batch file. This is really powerful for scheduling different types of backups on various schedules.&lt;/P&gt;
&lt;P&gt;Here are the scheduled backups on one of my servers (BEAST):&lt;/P&gt;
&lt;TABLE class=accent1 cellSpacing=0 class="accent1"&gt;
&lt;CAPTION&gt;Scheduled Backups on BEAST&lt;/CAPTION&gt;
&lt;THEAD&gt;
&lt;TR&gt;
&lt;TH&gt;Name&lt;/TH&gt;
&lt;TH&gt;Schedule&lt;/TH&gt;&lt;/TR&gt;&lt;/THEAD&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;Daily Backup&lt;/TD&gt;
&lt;TD&gt;At 12:00 PM every day&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Differential Backup&lt;/TD&gt;
&lt;TD&gt;At 12:30 AM every day&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Full Backup&lt;/TD&gt;
&lt;TD&gt;At 1:00 AM every Sun of every week&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;The &lt;STRONG&gt;Daily Backup&lt;/STRONG&gt; task is configured as follows:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Run: &lt;/STRONG&gt;C:\BackedUp\Backup.cmd daily &amp;gt;&amp;gt; Backup.log&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Start in:&lt;/STRONG&gt; C:\BackedUp&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Run as:&lt;/STRONG&gt; TECHTOOLBOX\svc-backup&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Note that I specifically chose the middle of the day to perform daily backups so that I could potentially recover a file that was created in the morning but mistakenly deleted in the afternoon. I suppose I could schedule incremental backups throughout the day, but honestly, I haven't seen the need given my situation.&lt;/P&gt;
&lt;P&gt;Also note that the service account that I use for backups (TECHTOOLBOX\svc-backup) is only a member of the &lt;STRONG&gt;Backup Operators &lt;/STRONG&gt;group. It is not a member of the &lt;STRONG&gt;Administrators &lt;/STRONG&gt;group.&lt;/P&gt;
&lt;P&gt;Consequently there's a known issue with running batch files using scheduled tasks due to out-of-the-box security restrictions on cmd.exe:&lt;/P&gt;
&lt;DIV class=reference&gt;&lt;CITE&gt;"Access is denied" error message when you run a batch job on a Windows Server 2003-based computer&lt;/CITE&gt; 
&lt;DIV class=referenceLink&gt;&lt;A href="http://support.microsoft.com/kb/867466" mce_href="http://support.microsoft.com/kb/867466"&gt;http://support.microsoft.com/kb/867466&lt;/A&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Lastly, note that I am doing a simple disk-to-disk backup on my servers, so if there's a fire in the Jameson Datacenter (i.e. my basement) and I lose these servers completely then I'm going to be "hurtin' for certain." However should there ever be a fire in my basement (Heaven forbid), I'm going to be worried about a lot more than just restoring my data from backup. Note that I keep copies of the &lt;EM&gt;really&lt;/EM&gt; important stuff (e.g. digital photos and home videos of my family) on DVDs at my parents' house.&lt;/P&gt;
&lt;P&gt;I've read that there's a new backup tool in Windows Server 2008, so I suppose one of these days I'll need to get around to upgrading my backup solution ;-)&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9919509" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Windows+Server/default.aspx">Windows Server</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Infrastructure/default.aspx">Infrastructure</category></item><item><title>Using Password Minder to Manage Your Passwords</title><link>http://blogs.msdn.com/jjameson/archive/2009/11/07/using-password-minder-to-manage-your-passwords.aspx</link><pubDate>Sat, 07 Nov 2009 14:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9919057</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9919057.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9919057</wfw:commentRss><description>&lt;P&gt;I started using &lt;A href="http://msdn.microsoft.com/en-us/magazine/cc163958.aspx" mce_href="http://msdn.microsoft.com/en-us/magazine/cc163958.aspx"&gt;Password Minder&lt;/A&gt; almost immediately after reading about it in the July 2004 edition of MSDN Magazine. I don't know about you, but trying to remember all of my various passwords for dozens of Web sites, numerous network accounts, VMs, etc. is really quite a nightmare. [I'm actually a little embarrassed to say that on more than one occasion I've had to hack one of my VMs in order to reset the password for a domain admin. This process definitely isn't for the faint of heart, but it was better than having to rebuild &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx"&gt;my FABRIKAM domain &lt;/A&gt;from scratch.]&lt;/P&gt;
&lt;P&gt;Instead I tend to use no more than three or four passwords that I can remember (and change every couple of months) and a whole bunch of randomly generated passwords that I rely on Password Minder to store securely.&lt;/P&gt;
&lt;P&gt;Note that all of the service accounts used in the &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx"&gt;"Jameson Datacenter"&lt;/A&gt; (a.k.a. my home lab) use random 20 character passwords.&lt;/P&gt;
&lt;P&gt;Hence, why I added Password Minder to my &lt;A href="http://blogs.msdn.com/jjameson/archive/2007/03/22/backedup-and-notbackedup.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2007/03/22/backedup-and-notbackedup.aspx"&gt;Toolbox&lt;/A&gt; years ago. [Thanks to Keith Brown for sharing this wonderful utility, as well as take the time to write about the internals of how it works.]&lt;/P&gt;
&lt;P&gt;However, there were a few problems I had with the original Password Minder.&lt;/P&gt;
&lt;P&gt;First, it didn't like the fact that my Documents folder is redirected to a server. In other words, my encrypted password file is:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;\\BEAST\Users$\jjameson\Documents\My Passwords.xml&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Consequently, I encountered the following error when trying to save my password file:&lt;/P&gt;
&lt;BLOCKQUOTE class="directQuote errorMessage"&gt;Failed to save the password file. Here are the gory details: 
&lt;P&gt;GetVolumeInformation failed:&lt;BR&gt;The filename, directory name, or volume label syntax is incorrect.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I discovered that I could avoid this error by clearing the &lt;STRONG&gt;Let Password Minder control the DACL&lt;/STRONG&gt; checkbox in the &lt;STRONG&gt;Password Minder Options&lt;/STRONG&gt; dialog window.&lt;/P&gt;
&lt;P&gt;The next problem that I encountered was Password Minder throwing up on me (in other words, generating an unhandled &lt;CODE&gt;IndexOutOfRangeException&lt;/CODE&gt;) when one of my passwords somehow ended up being an empty string (to this day I'm still not sure how that empty password managed to get saved to the file).&lt;/P&gt;
&lt;P&gt;Thus I made a small change to line 381 of CryptMaster.cs. The original code was:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt; == record.EncryptedUserId) {&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;I changed this to:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(record.EncryptedUserId) == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;) {&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;The third problem (which I didn't encounter until a few years later) was that Password Minder wouldn't run on my Windows Vista x64 desktop.&lt;/P&gt;
&lt;P&gt;Note that the original project settings specified &lt;STRONG&gt;Platform target: Any CPU&lt;/STRONG&gt; and thus pwm.exe would generate a &lt;A href="http://msdn.microsoft.com/en-us/library/system.badimageformatexception.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.badimageformatexception.aspx"&gt;&lt;CODE&gt;BadImageFormatException&lt;/CODE&gt;&lt;/A&gt; when trying to load the 32-bit NativeHelpers.dll.&lt;/P&gt;
&lt;BLOCKQUOTE class="directQuote errorMessage"&gt;Could not load file or assembly 'NativeHelpers, Version=1.5.0.4, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format.&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This was easy enough to fix simply by setting &lt;STRONG&gt;Platform target &lt;/STRONG&gt;to &lt;STRONG&gt;x86 &lt;/STRONG&gt;and then recompiling.&lt;/P&gt;
&lt;P&gt;So, why do I blog about Password Minder after all this time? Well, just this week I finally got around to incorporating it into my "Toolbox" Visual Studio solution that is scheduled to build daily using Team Foundation Server, and I discovered that my Team Foundation Build server wasn't setup to build C++ projects, which is what I will blog about next.&lt;/P&gt;
&lt;P&gt;Stay tuned...I need to eat some breakfast first ;-)&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9919057" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category></item><item><title>Using Robocopy to Move Files and Folders</title><link>http://blogs.msdn.com/jjameson/archive/2009/11/07/using-robocopy-to-move-files-and-folders.aspx</link><pubDate>Sat, 07 Nov 2009 13:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9919053</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9919053.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9919053</wfw:commentRss><description>&lt;P&gt;I use &lt;A href="http://technet.microsoft.com/en-us/library/cc733145(WS.10).aspx" mce_href="http://technet.microsoft.com/en-us/library/cc733145(WS.10).aspx"&gt;Robocopy&lt;/A&gt; a lot, and it's been in my &lt;A href="http://blogs.msdn.com/jjameson/archive/2007/03/22/backedup-and-notbackedup.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2007/03/22/backedup-and-notbackedup.aspx"&gt;Toolbox&lt;/A&gt; for so long that I hardly remember using anything else. I was glad to see that it is now included out-of-the-box (starting with Vista), because I typically use it instead of Windows Explorer to move or copy files, since I prefer the way it reports the progress of the lengthy file operations.&lt;/P&gt;
&lt;P&gt;Note that when you specify the "/S /MOV" or "/E /MOV" options (to recursively move files from one location to another), it may leave behind a bunch of empty folders depending on the contents of the source and what you specify to move.&lt;/P&gt;
&lt;P&gt;Over a year ago I went through the rather painful effort of organizing my thousands of digital photos. During the process of moving thousands of files around to various folders, I ended up with lots of empty folders in my source folder structure.&lt;/P&gt;
&lt;P&gt;As I discovered earlier this week, you can specify the /MOVE option (instead of /MOV) to move both the files and directories, and delete them from the source after they are copied.&lt;/P&gt;
&lt;P&gt;Perhaps now my blog post from&amp;nbsp;earlier this week about &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/11/03/deleting-empty-folders.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/11/03/deleting-empty-folders.aspx"&gt;deleting empty folders&lt;/A&gt; makes a little more sense ;-)&lt;/P&gt;
&lt;P&gt;Sometimes I'm amazed at what I learn while blogging. I had just been in such the habit of using the /MOV option that I never gave it any thought (that is, until this week).&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9919053" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category></item><item><title>Deleting Empty Folders</title><link>http://blogs.msdn.com/jjameson/archive/2009/11/03/deleting-empty-folders.aspx</link><pubDate>Tue, 03 Nov 2009 13:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9916741</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9916741.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9916741</wfw:commentRss><description>&lt;P&gt;For the sake of this post, let's assume that you have a directory that contains some empty folders you want to get rid of. How the empty folders got there isn't important; all that matters is that you have some and you want to get rid of them.&lt;/P&gt;
&lt;P&gt;A few years ago, I created the following script (starting from a sample I found in the &lt;A href="http://technet.microsoft.com/en-us/scriptcenter/default.aspx" mce_href="http://technet.microsoft.com/en-us/scriptcenter/default.aspx"&gt;Script Center on TechNet&lt;/A&gt;) to recursively enumerate a folder structure, identify any empty folders, and subsequently delete them.&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;Option Explicit

If (WScript.Arguments.Count &amp;lt;&amp;gt; 1) Then
    WScript.Echo("Usage: cscript DeleteEmptyFolders.vbs {path}")    
    WScript.Quit(1)
End If

Dim strPath
strPath = WScript.Arguments(0)

Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

Dim objFolder
Set objFolder = fso.GetFolder(strPath)

DeleteEmptyFolders objFolder

Sub DeleteEmptyFolders(folder)
    Dim subfolder
    For Each subfolder in folder.SubFolders
        DeleteEmptyFolders subfolder
    Next
    
    If folder.SubFolders.Count = 0 And folder.Files.Count = 0 Then
        WScript.Echo folder.Path &amp;amp; " is empty"
        fso.DeleteFolder folder.Path
    End If    
End Sub&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;As you can see, there's really nothing complex here. Nevertheless I still find it to be a very useful script from time to time, so I thought I should share it. I used it this morning and it occurred to me that I should throw it up on the blog.&lt;/P&gt;
&lt;P&gt;Just be sure to run it with &lt;A href="http://msdn.microsoft.com/en-us/library/xazzc41b(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/xazzc41b(VS.85).aspx"&gt;CScript&lt;/A&gt; -- and not the default WScript -- or you'll find the &lt;CODE&gt;WScript.Echo&lt;/CODE&gt; messages rather frustrating.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9916741" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category></item><item><title>Recommendations for Code Analysis</title><link>http://blogs.msdn.com/jjameson/archive/2009/10/31/recommendations-for-code-analysis.aspx</link><pubDate>Sat, 31 Oct 2009 13:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9915654</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9915654.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9915654</wfw:commentRss><description>&lt;P&gt;In my &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/10/31/recommended-check-in-policies-for-team-foundation-server.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/10/31/recommended-check-in-policies-for-team-foundation-server.aspx"&gt;previous post&lt;/A&gt;, I briefly mentioned the Code Analysis feature of Visual Studio in the context of using check-in policies with Team Foundation Server (TFS). However, there's a lot more to talk about with regards to using Code Analysis.&lt;/P&gt;
&lt;P&gt;If you are ever find yourself "starting from a clean slate" on a software development project, I hope you take advantage of the opportunity to not only enable Code Analysis, but also to treat all Code Analysis warnings as errors. That's right, go ahead and check all of those boxes (for both &lt;STRONG&gt;Debug &lt;/STRONG&gt;and &lt;STRONG&gt;Release &lt;/STRONG&gt;configurations, of course) so that whenever potential issues are reported by Code Analysis, it stops developers dead in their tracks and considers the build to be broken.&lt;/P&gt;
&lt;P&gt;While you're at it, go ahead and select the &lt;STRONG&gt;All &lt;/STRONG&gt;option in the &lt;STRONG&gt;Treat warnings as errors &lt;/STRONG&gt;section on the &lt;STRONG&gt;Build &lt;/STRONG&gt;tab (something I definitely recommend as a best practice). Again, be sure to do this for all build configurations.&lt;/P&gt;
&lt;P&gt;Yes, this is going to be really painful for some developers.&lt;/P&gt;
&lt;P&gt;For example, you can say goodbye to using the overload of string.Format() that doesn't specify a CultureInfo:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; foo = &lt;SPAN style="COLOR: #a31515"&gt;"here"&lt;/SPAN&gt;;

            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; logMessage = &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.Format(
                &lt;SPAN style="COLOR: #a31515"&gt;"Imagine something interesting {0}."&lt;/SPAN&gt;,
                foo);&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Attempting this will now result in a broken build:&lt;/P&gt;
&lt;BLOCKQUOTE class="directQuote errorMessage"&gt;Error 2 CA1305 : Microsoft.Globalization : Because the behavior of 'string.Format(string, object)' could vary based on the current user's locale settings, replace this call in 'Program.Main(string[])' with a call to 'string.Format(IFormatProvider, string, params object[])'. If the result of 'string.Format(IFormatProvider, string, params object[])' will be displayed to the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter. Otherwise, if the result will be stored and accessed by software, such as when it is persisted to disk or to a database, specify 'CultureInfo.InvariantCulture'. &lt;/BLOCKQUOTE&gt;
&lt;P&gt;To avoid the CA1305 error, you will need to use something like this instead:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; foo = &lt;SPAN style="COLOR: #a31515"&gt;"here"&lt;/SPAN&gt;;

            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; logMessage = &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.Format(
                &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                &lt;SPAN style="COLOR: #a31515"&gt;"Imagine something interesting {0}."&lt;/SPAN&gt;,
                foo);&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;You will also need to enable signing of all assemblies with a strong name key, and also specify various assembly level attributes (e.g. &lt;A href="http://msdn.microsoft.com/en-us/library/system.clscompliantattribute.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.clscompliantattribute.aspx"&gt;&lt;CODE&gt;[assembly: CLSCompliant(true)]&lt;/CODE&gt;&lt;/A&gt;). However, if you follow the steps I've provided in a &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/04/03/shared-assembly-info-in-visual-studio-projects.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/04/03/shared-assembly-info-in-visual-studio-projects.aspx"&gt;previous post&lt;/A&gt;, this should only take you at most 1-2 minutes.&lt;/P&gt;
&lt;P&gt;Like I said before, this will probably cause some heartburn in the beginning, but trust me, developers will quickly get used to it and the code they write will be much better as a result.&lt;/P&gt;
&lt;P&gt;Now what about the other 99% of the time when you aren't starting from a clean slate, but instead are dealing with a substantial code base that causes the Code Analysis feature in Visual Studio to "light up like a Christmas tree" when you turn it on?&lt;/P&gt;
&lt;P&gt;Well, as with all software bugs, it all comes down to &lt;EM&gt;triage&lt;/EM&gt;. You obviously cannot simply halt all feature development in order to resolve code analysis issues. Instead, you should go for the "low hanging fruit" (meaning the issues that occur frequently but can be resolved with relatively little effort or risk of changing). You should also try to enable the Code Analysis rules that are most important, such as potential security issues.&lt;/P&gt;
&lt;P&gt;The following post provides some great information about which Code Analysis warnings to focus your attention on first:&lt;/P&gt;
&lt;DIV class=reference&gt;&lt;CITE&gt;What rules do Microsoft have turned on internally? 2007-08-09.&lt;/CITE&gt; 
&lt;DIV class=referenceLink&gt;&lt;A href="http://blogs.msdn.com/fxcop/archive/2007/08/09/what-rules-do-microsoft-have-turned-on-internally.aspx" mce_href="http://blogs.msdn.com/fxcop/archive/2007/08/09/what-rules-do-microsoft-have-turned-on-internally.aspx"&gt;http://blogs.msdn.com/fxcop/archive/2007/08/09/what-rules-do-microsoft-have-turned-on-internally.aspx&lt;/A&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;This article is obviously a little dated, but still very relevant over two years later.&lt;/P&gt;
&lt;P&gt;Note that you will undoubtedly need to &lt;A href="http://msdn.microsoft.com/en-us/library/ms244717.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms244717.aspx"&gt;suppress some specific Code Analysis warnings&lt;/A&gt; from time to time, and therefore you'll have to choose how to suppress the warnings (whether inline within the source, or in a GlobalSuppressions.cs file). However, I hope you'll choose to fix the underlying issue that causes the Code Analysis warning (whenever practical) instead of simply suppressing a bunch of warnings.&lt;/P&gt;
&lt;P&gt;So, in conclusion, think of the Code Analysis feature in Visual Studio as a way of &lt;EM&gt;choosing&lt;/EM&gt; a more strict compiler. For example, back in the days when I used to program in C on Unix, the compiler wouldn't complain when I wrote something like this (even though this is obviously very wrong):&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (i = 1)
            {
                ...
            }&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;I was relieved when I switched to C++ and these kinds of bugs were a thing of the past. [Note that I never switch my coding style to use something like "&lt;CODE&gt;1 == i&lt;/CODE&gt;" in order to avoid these errors.]&lt;/P&gt;
&lt;P&gt;Fortunately, in C# you don't have a choice about whether or not this compiles (it doesn't).&lt;/P&gt;
&lt;P&gt;I like to think of enabling all of the Code Analysis rules in a similar fashion. In other words, I want the compiler to tell me whenever I am doing something potentially wrong, because then I can spend just a little bit of time fixing my code to do it right. By forcing the Code Analysis warnings as errors, I don't have a choice -- meaning I have to fix them before check-in.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9915654" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Core+Development/default.aspx">Core Development</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>Recommended Check-In Policies for Team Foundation Server</title><link>http://blogs.msdn.com/jjameson/archive/2009/10/31/recommended-check-in-policies-for-team-foundation-server.aspx</link><pubDate>Sat, 31 Oct 2009 12:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9915639</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9915639.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9915639</wfw:commentRss><description>&lt;P&gt;I love using Team Foundation Server (TFS). There's just an amazing amount of "goodness" for software development that comes out-of-the-box; and there's even more available from Microsoft and other sources in the form of add-ons (many of which are free).&lt;/P&gt;
&lt;P&gt;From a source control perspective, one of my favorite features is check-in policies. Anything that improves the quality of software development with minimal effort is really a "&lt;A href="http://wordnetweb.princeton.edu/perl/webwn?s=no-brainer" mce_href="http://wordnetweb.princeton.edu/perl/webwn?s=no-brainer"&gt;no-brainer&lt;/A&gt;" in my opinion.&lt;/P&gt;
&lt;P&gt;The check-in policies that I prefer to have configured on all TFS projects are listed in the following table.&lt;/P&gt;
&lt;TABLE class=accent1 cellSpacing=0 class="accent1"&gt;
&lt;CAPTION&gt;Recommended TFS Check-In Policies&lt;/CAPTION&gt;
&lt;THEAD&gt;
&lt;TR&gt;
&lt;TH&gt;Policy Type&lt;/TH&gt;
&lt;TH&gt;Description&lt;/TH&gt;&lt;/TR&gt;&lt;/THEAD&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;Builds&lt;/TD&gt;
&lt;TD&gt;This policy requires that any code changes have been compiled and the last build was successful.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Work Items&lt;/TD&gt;
&lt;TD&gt;This policy requires that one or more work items be associated with every check-in.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Changeset Comments Policy&lt;/TD&gt;
&lt;TD&gt;Reminds users to add meaningful comments to their check-ins.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Code Analysis&lt;/TD&gt;
&lt;TD&gt;This policy requires that Code Analysis is run with a defined set of rules before check-in.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Testing Policy&lt;/TD&gt;
&lt;TD&gt;Ensures that tests from specific test lists are successfully executed before checking in.&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;The first two check-in policies are virtually painless and can be applied to any existing project at any time. These policies ship with Visual Studio Team System 2008, and assuming your developers have good software development discipline already, there's absolutely no reason not to enable these policies.&lt;/P&gt;
&lt;P&gt;After all, why would any developer want to check-in code that hasn't been verified to at least compile? Similarly, why would a developer make a code change that isn't specifically related to a work item (even if that work item is simply something like "Refactor X" or "Code cleanup (M5)")?&lt;/P&gt;
&lt;P&gt;However, the last three policies in the table above require a little more effort.&lt;/P&gt;
&lt;P&gt;The Changeset Comments Policy is included in the &lt;A href="http://msdn.microsoft.com/en-us/teamsystem/bb980963.aspx" mce_href="http://msdn.microsoft.com/en-us/teamsystem/bb980963.aspx"&gt;Team Foundation Server Power Tools&lt;/A&gt;, which means that every member of the Development team will need to download and install this in order to use it. (Note that if you don't have the Power Tools installed, you can still override the check-in policy in order to avoid being blocked.)&lt;/P&gt;
&lt;P&gt;The Code Analysis policy can definitely cause a little heartburn for your Development team, depending on how many code analysis rules you enable and whether or not you treat these warnings as errors. I'll talk more about Code Analysis in a separate post.&lt;/P&gt;
&lt;P&gt;The Testing Policy is not one that I consider essential for all projects. For projects in which you have a good set of Build Verification Tests (BVTs) that give you a signficant amount of code coverage and don't take very long to execute, then enabling this policy just makes sense. However, keep in mind that you should definitely be running BVTs as part of your automated build, so if these tests require a substantial amount of time to execute (for example, they require signficant setup or teardown), then forcing developers to run these tests before every check-in could definitely impede their productivity.&lt;/P&gt;
&lt;P&gt;Of course, you can always separate your tests into "quick tests" and "long running tests" like I've mentioned in a previous &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/03/19/argumentnullexception-with-optional-publishingpage-description-property-with-some-thoughts-on-breaking-the-build-too.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/03/19/argumentnullexception-with-optional-publishingpage-description-property-with-some-thoughts-on-breaking-the-build-too.aspx"&gt;post&lt;/A&gt;, and consequently only require the "quick tests" to be executed before check-in.&lt;/P&gt;
&lt;P&gt;If you are fortunate enough to be using TFS on your project, I hope you are reaping the benefits of check-in policies.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9915639" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Core+Development/default.aspx">Core Development</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/TFS/default.aspx">TFS</category></item><item><title>The Original "Jameson Datacenter"</title><link>http://blogs.msdn.com/jjameson/archive/2009/10/24/the-original-jameson-datacenter.aspx</link><pubDate>Sat, 24 Oct 2009 13:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9912449</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9912449.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9912449</wfw:commentRss><description>&lt;P&gt;This morning I was doing some cleanup of my documents folder and I stumbled across a rather old Visio document that showed the beginnings of&amp;nbsp;what I now refer to as the &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx"&gt;"Jameson Datacenter"&lt;/A&gt; (a.k.a. my home lab). For some geeky reason, seeing this again brought a smile to my face and a sense of nostalgia. It also caused me to recall two things:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;That old Greatful Dead song "Truckin'" -- specifically the line&lt;BR&gt;&lt;BR&gt;&lt;Q class=directQuote&gt;Lately it occurs to me: What a long, strange trip it's been.&lt;/Q&gt; 
&lt;BLOCKQUOTE class=note&gt;
&lt;DIV class=noteTitle&gt;&lt;STRONG&gt;Update&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;DIV&gt;Doh! You would think a guy with a Master of Science degree in Mechanical Engineering could spell "Grateful Dead" correctly! I suppose that I really should do more proofreading before clicking that &lt;STRONG&gt;Publish &lt;/STRONG&gt;button ;-)&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;&lt;/LI&gt;
&lt;LI&gt;An article I read about a year ago describing the origin of Google that also included some photos of the original Google infrastructure in the Stanford University computer lab.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Now, please don't misunderstand -- I most certainly am not claiming that the Jameson Datacenter will ever amount to even the most miniscule fraction of what Google grew into in less than a decade. All I'm saying is that in the incredible way the neurons are wired together in the human brain, things that we see very often trigger distant memories with amazing clarity.&lt;/P&gt;
&lt;P&gt;For those of you that may not have seen the original Google server farm, I did a quick search this morning and managed to find the following:&lt;/P&gt;
&lt;DIV class=reference&gt;&lt;CITE&gt;Google Stanford Hardware&lt;/CITE&gt; 
&lt;DIV class=referenceLink&gt;&lt;A href="http://geektechnique.org/media/google/googlehardware.html" mce_href="http://geektechnique.org/media/google/googlehardware.html"&gt;http://geektechnique.org/media/google/googlehardware.html&lt;/A&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;If you haven't seen this, take a quick peek. It will surely bring a smile -- if not a burst of laughter.&lt;/P&gt;
&lt;P&gt;After enjoying the nostalgia for a moment, I almost deleted the Visio diagram and continued my cleanup effort. However, then I decided that I might as well "archive" this on my blog. It definitely won't help your efforts of deploying Microsoft technology, but I think it's okay for a blog to wander a little every now and then -- perhaps for no other reason than to keep you guessing as to what may come next on the Random Musings of Jeremy Jameson.&lt;/P&gt;
&lt;P&gt;Here's the physical architecture of what I now refer to as the "Old Jameson Datacenter":&lt;/P&gt;
&lt;DIV class=image&gt;&lt;IMG title="" alt="" src="http://blogs.msdn.com/photos/jjameson/images/9912445/489x375.aspx" width=489 height=375 mce_src="http://blogs.msdn.com/photos/jjameson/images/9912445/489x375.aspx"&gt; 
&lt;DIV class=caption&gt;Figure 1: Old Jameson Datacenter - Physical Architecture&lt;/DIV&gt;
&lt;DIV class=imageLink&gt;&lt;A href="http://blogs.msdn.com/photos/jjameson/images/9912445/original.aspx" target=_blank mce_href="http://blogs.msdn.com/photos/jjameson/images/9912445/original.aspx"&gt;See full-sized image.&lt;/A&gt; &lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Apparently the last time I updated this Visio diagram, I still hadn't decided what to do with all of the Dell servers I had procured through various channels (primarily the Dell Outlet and ebay). Hence the Dell PowerEdge 4300 with the "??" next to it. As I mentioned in my original post on the Jameson Datacenter, this server was the original BEAST (which is now my "Production" database server). However, it has since been replaced with a home-built server.&lt;/P&gt;
&lt;P&gt;From the previous figure, you can start to see why I've consolidated these servers in recent years by leveraging virtualization. The power consumption by all of these servers was really rather ridiculous when you consider what I was using these servers for.&lt;/P&gt;
&lt;P&gt;Notice that I use to run a back-to-back firewall configuration with a perimeter network (a.k.a. DMZ):&lt;/P&gt;
&lt;DIV class=image&gt;&lt;IMG title="" alt="" src="http://blogs.msdn.com/photos/jjameson/images/9912446/477x375.aspx" width=477 height=375 mce_src="http://blogs.msdn.com/photos/jjameson/images/9912446/477x375.aspx"&gt; 
&lt;DIV class=caption&gt;Figure 2: Old Jameson Datacenter - TCP/IP Configuration&lt;/DIV&gt;
&lt;DIV class=imageLink&gt;&lt;A href="http://blogs.msdn.com/photos/jjameson/images/9912446/original.aspx" target=_blank mce_href="http://blogs.msdn.com/photos/jjameson/images/9912446/original.aspx"&gt;See full-sized image.&lt;/A&gt; &lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;This is because I had one server with a public (static) IP address and therefore ran a couple of Web sites on the old "ICEMAN" server -- hence the name "ICEMAN", because it was my "IIS" server. Get it? Yeah, I know...more geekiness.&lt;/P&gt;
&lt;P&gt;The naming convention was such that the names corresponding to &lt;A href="http://en.wikipedia.org/wiki/X-Men" mce_href="http://en.wikipedia.org/wiki/X-Men"&gt;X-Men&lt;/A&gt; heroes were all members of the TECHTOOLBOX domain, whereas servers corresponding to X-Men villains were considered "dangerous" and thus not members of the domain. Egad! Does the geekness ever end?! [I wonder if someday when my daughter is much older, she'll ever bother to read this and seriously start to question her father's sanity.]&lt;/P&gt;
&lt;P&gt;Anyway, here's the DNS and DHCP configuration for the original farm:&lt;/P&gt;
&lt;DIV class=image&gt;&lt;IMG title="" alt="" src="http://blogs.msdn.com/photos/jjameson/images/9912447/500x155.aspx" width=500 height=155 mce_src="http://blogs.msdn.com/photos/jjameson/images/9912447/500x155.aspx"&gt; 
&lt;DIV class=caption&gt;Figure 1: Old Jameson Datacenter - DNS/DHCP Configuration&lt;/DIV&gt;
&lt;DIV class=imageLink&gt;&lt;A href="http://blogs.msdn.com/photos/jjameson/images/9912447/original.aspx" target=_blank mce_href="http://blogs.msdn.com/photos/jjameson/images/9912447/original.aspx"&gt;See full-sized image.&lt;/A&gt; &lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;There's nothing really too interesting about that, I suppose.&lt;/P&gt;
&lt;P&gt;Perhaps the most laughable aspect of the Old Jameson Datacenter -- at least when compared to today -- was the storage infrastructure:&lt;/P&gt;
&lt;DIV class=image&gt;&lt;IMG title="" alt="" src="http://blogs.msdn.com/photos/jjameson/images/9912448/474x375.aspx" width=474 height=375 mce_src="http://blogs.msdn.com/photos/jjameson/images/9912448/474x375.aspx"&gt; 
&lt;DIV class=caption&gt;Figure 1: Old Jameson Datacenter - Disk Configuration&lt;/DIV&gt;
&lt;DIV class=imageLink&gt;&lt;A href="http://blogs.msdn.com/photos/jjameson/images/9912448/original.aspx" target=_blank mce_href="http://blogs.msdn.com/photos/jjameson/images/9912448/original.aspx"&gt;See full-sized image.&lt;/A&gt; &lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;I can still remember when I thought the 18 GB of RAID1 and 72 GB of RAID5 on that Dell 4300 was &lt;A href="http://www.urbandictionary.com/define.php?term=fashizzle" mce_href="http://www.urbandictionary.com/define.php?term=fashizzle"&gt;fashizzle&lt;/A&gt; ;-) [Of course, that was long before I was even aware of the term "fashizzle", but you get my point.]&lt;/P&gt;
&lt;P&gt;Anyway, I hope you enjoyed this brief diversion down Memory Lane. Perhaps it invoked some distant memories of your own experiences in the world of technology.&lt;/P&gt;
&lt;P&gt;Personally, as I'm wrapping up this post, my head is spinning with thoughts of my father's original Apple II+ (which was the first computer I ever "programmed" on) as well as my very own Commodore 64 and all those late nights my dear friend &lt;A href="http://www.imediaconnection.com/profiles/iMedia_PC_Bio.aspx?ID=2928" mce_href="http://www.imediaconnection.com/profiles/iMedia_PC_Bio.aspx?ID=2928"&gt;Chris Gatewood&lt;/A&gt; and I sat in front of it typing in hundreds of lines of code from a magazine just so we could try to play some silly game based on "sprites." [Note that the games almost never worked due to some error or another, but nevertheless we kept trying anyway.]&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9912449" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Personal/default.aspx">Personal</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Infrastructure/default.aspx">Infrastructure</category></item><item><title>Configure IntelliMirror Using Group Policy</title><link>http://blogs.msdn.com/jjameson/archive/2009/10/21/configure-intellimirror-using-group-policy.aspx</link><pubDate>Wed, 21 Oct 2009 12:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9910544</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9910544.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9910544</wfw:commentRss><description>&lt;P&gt;Yet another Group Policy object that I use in the &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx"&gt;"Jameson Datacenter"&lt;/A&gt; (a.k.a. my home lab) is one to automatically configure roaming profiles and redirect the Desktop and Documents folders to a server(a.k.a. "IntelliMirror").&lt;/P&gt;
&lt;P&gt;Even though I don't have many users in my Active Directory domain -- it's not like I have eight kids, just one -- I still want to keep user data centrally managed on a server that I backup regularly. Besides, I find it really frustrating to have some items on your desktop on one computer, but a different set of desktop items on another computer (or VM).&lt;/P&gt;
&lt;P&gt;To automatically configure this in the "Jameson Datacenter", I defined a Group Policy (named &lt;STRONG&gt;Default User Data and Settings Policy&lt;/STRONG&gt;) with the following settings:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;User Configuration&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Policies&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Windows Settings&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Folder Redirection&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class=sectionTitle tabIndex=0&gt;&lt;STRONG&gt;AppData(Roaming)&lt;/STRONG&gt;&lt;/SPAN&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class=sectionTitle tabIndex=0&gt;&lt;STRONG&gt;Setting: Basic (Redirect everyone's folder to the same location)&lt;/STRONG&gt;&lt;/SPAN&gt; 
&lt;UL&gt;
&lt;LI&gt;Path: \\beast\Users$\%USERNAME%\Application Data&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Options&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;Grant user exclusive rights to AppData(Roaming): Enabled&lt;/LI&gt;
&lt;LI&gt;Move the contents of AppData(Roaming) to the new location: Enabled&lt;/LI&gt;
&lt;LI&gt;Also apply redirection policy to Windows 2000, Windows 2000 server, Windows XP, and Windows Server 2003 operating systems: Enabled&lt;/LI&gt;
&lt;LI&gt;Policy Removal Behavior: Leave contents&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class=sectionTitle tabIndex=0&gt;&lt;STRONG&gt;Desktop&lt;/STRONG&gt;&lt;/SPAN&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class=sectionTitle tabIndex=0&gt;&lt;STRONG&gt;Setting: Basic (Redirect everyone's folder to the same location)&lt;/STRONG&gt;&lt;/SPAN&gt; 
&lt;UL&gt;
&lt;LI&gt;Path: \\beast\Users$\%USERNAME%\Desktop&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Options&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;Grant user exclusive rights to Desktop: Enabled&lt;/LI&gt;
&lt;LI&gt;Move the contents of Desktop to the new location: Enabled&lt;/LI&gt;
&lt;LI&gt;Also apply redirection policy to Windows 2000, Windows 2000 server, Windows XP, and Windows Server 2003 operating systems: Enabled&lt;/LI&gt;
&lt;LI&gt;Policy Removal Behavior: Leave contents&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class=sectionTitle tabIndex=0&gt;&lt;STRONG&gt;Documents&lt;/STRONG&gt;&lt;/SPAN&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class=sectionTitle tabIndex=0&gt;&lt;STRONG&gt;Setting: Basic (Redirect everyone's folder to the same location)&lt;/STRONG&gt;&lt;/SPAN&gt; 
&lt;UL&gt;
&lt;LI&gt;Path: \\beast\Users$\%USERNAME%\Documents&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Options&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;Grant user exclusive rights to Documents: Enabled&lt;/LI&gt;
&lt;LI&gt;Move the contents of Documentsto the new location: Enabled&lt;/LI&gt;
&lt;LI&gt;Also apply redirection policy to Windows 2000, Windows 2000 server, Windows XP, and Windows Server 2003 operating systems: Enabled&lt;/LI&gt;
&lt;LI&gt;Policy Removal Behavior: Leave contents&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Music&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;Setting: Follow the Documents folder&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Pictures&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;Setting: Follow the Documents folder&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Videos&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;Setting: Follow the Documents folder&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE class=note&gt;
&lt;DIV class=noteTitle&gt;&lt;STRONG&gt;Note&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;DIV&gt;Those of you that have a very keen eye (and also a photographic memory) might recall that in a previous post, I listed BEAST as a database server (it is currently running SQL Server 2005). Yes, it's true, I'm breaking one of my own cardinal sins by having a SQL Server also serve as a file server. I don't recommend doing this unless, like me, you are trying to go as cheap as possible -- and, even then, only for a lab environment like mine.&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;In order to allow users access to create their own folders on \\BEAST\Users$, I have configured the following permissions on C:\BackedUp\Users:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Domain Users 
&lt;UL&gt;
&lt;LI&gt;Apply onto: This folder only&lt;/LI&gt;
&lt;LI&gt;Permissions 
&lt;UL&gt;
&lt;LI&gt;List Folder / Read Data&lt;/LI&gt;
&lt;LI&gt;Create Folders / Append Data&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;CREATOR OWNER 
&lt;UL&gt;
&lt;LI&gt;Apply onto: Subfolders and files only&lt;/LI&gt;
&lt;LI&gt;Permissions 
&lt;UL&gt;
&lt;LI&gt;Full Control&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I also created a hidden share for the C:\BackedUp\Users folder and granted &lt;STRONG&gt;Full Control &lt;/STRONG&gt;to &lt;STRONG&gt;Authenticated Users &lt;/STRONG&gt;(since the NTFS permissions above ultimately determine the level of access for all users).&lt;/P&gt;
&lt;P&gt;Thus when a new user logs in for the first time, a corresponding folder is created on the server and all of the user's files are stored on the server.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9910544" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Simplify/default.aspx">Simplify</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Windows+Server/default.aspx">Windows Server</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Infrastructure/default.aspx">Infrastructure</category></item><item><title>Eliminate MBSA Warnings Using Default Security Settings Policy</title><link>http://blogs.msdn.com/jjameson/archive/2009/10/21/eliminate-mbsa-warnings-using-default-security-settings-policy.aspx</link><pubDate>Wed, 21 Oct 2009 11:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9910517</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9910517.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9910517</wfw:commentRss><description>&lt;P&gt;Another Group Policy object that I use in the &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx"&gt;"Jameson Datacenter"&lt;/A&gt; (a.k.a. my home lab) is one that I created a couple of years ago in order to eliminate various warnings from the &lt;A href="http://technet.microsoft.com/en-us/security/cc184924.aspx" mce_href="http://technet.microsoft.com/en-us/security/cc184924.aspx"&gt;Microsoft Baseline Security Advisor&lt;/A&gt; (MBSA).&lt;/P&gt;
&lt;P&gt;To automatically change the default security settings in the "Jameson Datacenter", I defined a Group Policy (named &lt;STRONG&gt;Default Security Settings Policy&lt;/STRONG&gt;) with the following settings:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Computer Configuration&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Policies&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Windows Settings&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Security Settings&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Account Policies&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Password Policy&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Maximum password age: 60 days&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Minimum password age: 1 day&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Minimum password length: 8 characters&lt;/STRONG&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Local Policies&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Security Options&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Network security: LAN Manager authentication level: Send NTLMv2 response only. Refuse LM &amp;amp; NTLM&lt;/STRONG&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;System Services&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;TlntSvr&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Startup Mode: Disabled&lt;/STRONG&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I don't know about you, but I haven't used Telnet in almost fifteen years -- back when I used to work on Unix systems ;-)&lt;/P&gt;
&lt;P&gt;This Group Policy is linked to the entire domain (i.e. &lt;STRONG&gt;corp.technologytoolbox.com&lt;/STRONG&gt;).&lt;/P&gt;
&lt;P&gt;Note that I still use the &lt;STRONG&gt;Default Domain Controllers Policy&lt;/STRONG&gt; to configure the security settings on the domain controllers (and thus domain accounts). In other words, the settings noted above only affect local accounts (e.g. COLOSSUS\Administrator, not TECHTOOLBOX\jjameson).&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9910517" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Simplify/default.aspx">Simplify</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Windows+Server/default.aspx">Windows Server</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Infrastructure/default.aspx">Infrastructure</category></item><item><title>Add Rooler to Your Web Development Toolbox</title><link>http://blogs.msdn.com/jjameson/archive/2009/10/21/add-rooler-to-your-web-development-toolbox.aspx</link><pubDate>Wed, 21 Oct 2009 10:19:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9910478</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9910478.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9910478</wfw:commentRss><description>&lt;P&gt;This past May, one of my colleagues notified me of a new tool called "Rooler" that allows you to easily measure anything displayed on your screen.&lt;/P&gt;
&lt;P&gt;I definitely consider this tool a "must have" for anyone out there doing Web development. While tools like Firebug and the new developer tools in Internet Explorer 8 are great for analyzing the layout of Web pages, I often find myself using Rooler when tweaking CSS rules in order to achieve that "pixel perfect" design. For example, yesterday I was working on styling the new customer service portal that I'm working on and I wanted to match the customer's current .com site. Rooler enabled me to identify the dimensions of the header and margins of various elements with almost no effort whatsoever.&lt;/P&gt;
&lt;P&gt;If you haven't already discovered &lt;A href="http://blois.us/Rooler/" mce_href="http://blois.us/Rooler/"&gt;Rooler&lt;/A&gt;, I strongly recommend you download it today.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9910478" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Web+Development/default.aspx">Web Development</category></item><item><title>Introducing the SharePointSmtpHelper Class</title><link>http://blogs.msdn.com/jjameson/archive/2009/10/18/introducing-the-sharepointsmtphelper-class.aspx</link><pubDate>Sun, 18 Oct 2009 14:29:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9908769</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9908769.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9908769</wfw:commentRss><description>&lt;P&gt;Continuing in the spirit of my previous posts for the &lt;CODE&gt;&lt;A href="http://blogs.msdn.com/jjameson/archive/2009/10/09/introducing-the-sharepointpublishinghelper-class.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/10/09/introducing-the-sharepointpublishinghelper-class.aspx"&gt;SharePointPublishingHelper&lt;/A&gt;&lt;/CODE&gt; class and &lt;CODE&gt;&lt;A href="http://blogs.msdn.com/jjameson/archive/2009/10/17/introducing-the-sharepointwebparthelper-class.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/10/17/introducing-the-sharepointwebparthelper-class.aspx"&gt;SharePointWebPartHelper&lt;/A&gt;&lt;/CODE&gt; class, I'd like to introduce another helper class that you may find useful when building solutions for Windows SharePoint Services (WSS) v3 and Microsoft Office SharePoint Server (MOSS) 2007.&lt;/P&gt;
&lt;P&gt;Consider the scenario where you need to send an e-mail message from a SharePoint application. Perhaps an unexpected error occurred and you want to notify the operations team, or perhaps you just want to send a confirmation message to a user who has just submitted some important information.&lt;/P&gt;
&lt;P&gt;Whatever the case, you'd like to send an e-mail message using the SMTP server configured in SharePoint Central Administration for the farm. &lt;CODE&gt;SharePointSmtpHelper&lt;/CODE&gt; makes it really easy to do this.&lt;/P&gt;
&lt;P&gt;Note that there's really not much code to the &lt;CODE&gt;SharePointSmtpHelper&lt;/CODE&gt; class -- thanks to the classes provided by the .NET Framework in the &lt;A href="http://msdn.microsoft.com/en-us/library/system.net.mail.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.net.mail.aspx"&gt;System.Net.Mail&lt;/A&gt; namespace. It may look like more code than you might expect, but that's just because of all the overloads of the &lt;CODE&gt;SendMessage&lt;/CODE&gt; method that I provide.&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Net.Mail;

&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; Microsoft.SharePoint;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; Microsoft.SharePoint.Administration;

&lt;SPAN style="COLOR: #0000ff"&gt;namespace&lt;/SPAN&gt; Fabrikam.Demo.CoreServices.SharePoint
{
    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;summary&amp;gt;
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Exposes static methods for sending e-mail messages from a SharePoint
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Web application using the Simple Mail Transfer Protocol (SMTP). The
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; SMTP server must be configured in SharePoint Central Administration.
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; This class cannot be inherited.
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/summary&amp;gt;
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;remarks&amp;gt;
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; All methods of the &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;b&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;SharePointSmtpHelper&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/b&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; class are static and
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; can therefore be called without creating an instance of the class.
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/remarks&amp;gt;
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;sealed&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;SharePointSmtpHelper
&lt;/SPAN&gt;    {
        &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt; lockObject = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt;();

        &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; smtpServer;
        &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; defaultFromAddress;
        
        &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; SharePointSmtpHelper( ) { } &lt;SPAN style="COLOR: #008000"&gt;// all members are static

&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;summary&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Sends an e-mail message using the outbound SMTP server and
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; "From address" configured in SharePoint Central Administration.
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/summary&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="toRecipients"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The recipients of the e-mail message.
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; In other words, the addresses on the To line of the e-mail.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="subject"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The subject line for the e-mail message.
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="body"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The e-mail message body.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;void&lt;/SPAN&gt; SendMessage(
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; toRecipients,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; subject,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; body)
        {
            SendMessage(
                toRecipients,
                subject,
                body,
                &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;,
                &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;,
                &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;);
        }

        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;summary&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Sends an e-mail message using the outbound SMTP server and
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; "From address" configured in SharePoint Central Administration,
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; specifying whether the body of the message is formatted using HTML.
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/summary&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="toRecipients"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The recipients of the e-mail message.
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; In other words, the addresses on the To line of the e-mail.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="subject"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The subject line for the e-mail message.
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="body"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The e-mail message body.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="isBodyHtml"&amp;gt;&amp;lt;c&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;true&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/c&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; if the mail message body is
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; formatted using HTML markup. &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;c&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;false&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/c&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; if the message is simply
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; plain text.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;void&lt;/SPAN&gt; SendMessage(
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; toRecipients,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; subject,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; body,
            &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; isBodyHtml)
        {
            SendMessage(
                toRecipients,
                subject,
                body,
                isBodyHtml,
                &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;,
                &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;);
        }

        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;summary&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Sends an e-mail message using the outbound SMTP server and
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; "From address" configured in SharePoint Central Administration,
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; specifying whether the body of the message is formatted using HTML
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; and also including carbon copy (CC) recipients.
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/summary&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="toRecipients"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The recipients of the e-mail message.
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; In other words, the addresses on the To line of the e-mail.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="subject"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The subject line for the e-mail message.
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="body"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The e-mail message body.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;        
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="isBodyHtml"&amp;gt;&amp;lt;c&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;true&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/c&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; if the mail message body is
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; formatted using HTML markup. &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;c&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;false&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/c&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; if the message is simply
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; plain text.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="ccRecipients"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The carbon copy (CC) recipients of the
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; e-mail message.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;void&lt;/SPAN&gt; SendMessage(
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; toRecipients,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; subject,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; body,
            &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; isBodyHtml,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; ccRecipients)
        {
            SendMessage(
                toRecipients,
                subject,
                body,
                isBodyHtml,
                ccRecipients,
                &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;);
        }

        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;summary&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Sends an e-mail message using the outbound SMTP server configured
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; in SharePoint Central Administration for the farm.
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/summary&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="toRecipients"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The recipients of the e-mail message.
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; In other words, the addresses on the To line of the e-mail.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="subject"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The subject line for the e-mail message.
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="body"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The e-mail message body.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;        
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="isBodyHtml"&amp;gt;&amp;lt;c&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;true&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/c&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; if the mail message body is
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; formatted using HTML markup. &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;c&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;false&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/c&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; if the message is simply
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; plain text.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="ccRecipients"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The carbon copy (CC) recipients of the
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; e-mail message.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="from"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The e-mail address of the sender.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;void&lt;/SPAN&gt; SendMessage(
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; toRecipients,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; subject,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; body,
            &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; isBodyHtml,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; ccRecipients,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; from)
        {
            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(toRecipients) == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentNullException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"toRecipients"&lt;/SPAN&gt;);
            }

            toRecipients = toRecipients.Trim();
            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(toRecipients) == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentException&lt;/SPAN&gt;(
                    &lt;SPAN style="COLOR: #a31515"&gt;"In order to send an e-mail message, "
&lt;/SPAN&gt;                        + &lt;SPAN style="COLOR: #a31515"&gt;" at least one recipient must be specified."&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"toRecipients"&lt;/SPAN&gt;);
            }

            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(subject) == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentNullException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"subject"&lt;/SPAN&gt;);
            }

            subject = subject.Trim();
            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(subject) == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentException&lt;/SPAN&gt;(
                    &lt;SPAN style="COLOR: #a31515"&gt;"In order to send an e-mail message, "
&lt;/SPAN&gt;                        + &lt;SPAN style="COLOR: #a31515"&gt;" the subject must be specified."&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"subject"&lt;/SPAN&gt;);
            }

            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(body) == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentNullException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"body"&lt;/SPAN&gt;);
            }

            body = body.Trim();
            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(body) == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentException&lt;/SPAN&gt;(
                    &lt;SPAN style="COLOR: #a31515"&gt;"In order to send an e-mail message, "
&lt;/SPAN&gt;                        + &lt;SPAN style="COLOR: #a31515"&gt;" the message body must be specified."&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"body"&lt;/SPAN&gt;);
            }

            EnsureSmtpSettings();

            &lt;SPAN style="COLOR: #008000"&gt;// If the "from" address is not specified, default to the address
&lt;/SPAN&gt;            &lt;SPAN style="COLOR: #008000"&gt;// configured in SharePoint Central Administration.
&lt;/SPAN&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(from) == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)
            {
                from = defaultFromAddress;
            }

            &lt;SPAN style="COLOR: #2b91af"&gt;SmtpClient&lt;/SPAN&gt; smtpClient = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;SmtpClient&lt;/SPAN&gt;(smtpServer);

            &lt;SPAN style="COLOR: #2b91af"&gt;MailMessage&lt;/SPAN&gt; message = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;MailMessage&lt;/SPAN&gt;(
                from,
                toRecipients,
                subject,
                body);

            message.IsBodyHtml = isBodyHtml;

            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(ccRecipients) == &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;)
            {
                message.CC.Add(ccRecipients);
            }

            smtpClient.Send(message);
        }

        &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;void&lt;/SPAN&gt; EnsureSmtpSettings()
        {
            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(smtpServer) == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #2b91af"&gt;SPContext&lt;/SPAN&gt;.Current == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
                {
                    &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;InvalidOperationException&lt;/SPAN&gt;(
                        &lt;SPAN style="COLOR: #a31515"&gt;"SharePointSmtpClient can only be called from within"
&lt;/SPAN&gt;                            + &lt;SPAN style="COLOR: #a31515"&gt;" a SharePoint site (SPContext.Current is null)."&lt;/SPAN&gt;);
                }

                &lt;SPAN style="COLOR: #0000ff"&gt;lock&lt;/SPAN&gt; (lockObject)
                {
                    &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(smtpServer) == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)
                    {
                        &lt;SPAN style="COLOR: #2b91af"&gt;SPWebApplication&lt;/SPAN&gt; webApp =
                            &lt;SPAN style="COLOR: #2b91af"&gt;SPContext&lt;/SPAN&gt;.Current.Site.WebApplication;

                        &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (webApp.OutboundMailServiceInstance != &lt;SPAN style="COLOR: #0000ff"&gt;null
&lt;/SPAN&gt;                            &amp;amp;&amp;amp; webApp.OutboundMailServiceInstance.Server != &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
                        {
                            smtpServer =
                                webApp.OutboundMailServiceInstance.Server.Address;
                        }

                        &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(smtpServer) == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)                            
                        {
                            &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;InvalidOperationException&lt;/SPAN&gt;(
                                &lt;SPAN style="COLOR: #a31515"&gt;"The outbound SMTP server is not specified in"
&lt;/SPAN&gt;                                + &lt;SPAN style="COLOR: #a31515"&gt;" SharePoint Central Administration."&lt;/SPAN&gt;);
                        }

                        defaultFromAddress = webApp.OutboundMailSenderAddress;
                    }
                }
            }
        }
    }
}&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Note that I use static members in order to only read the SMTP server configuration from SharePoint Central Administration one time.&lt;/P&gt;
&lt;P&gt;Assuming you just want to send a simple message using the default "From address" specified in SharePoint Central Administration, you only need a single line of code that passes three parameters:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;            &lt;SPAN style="COLOR: #2b91af"&gt;SharePointSmtpHelper&lt;/SPAN&gt;.SendMessage(
                &lt;SPAN style="COLOR: #a31515"&gt;"jeremy_jameson@fabrikam.com"&lt;/SPAN&gt;,
                &lt;SPAN style="COLOR: #a31515"&gt;"Test message"&lt;/SPAN&gt;,
                &lt;SPAN style="COLOR: #a31515"&gt;"Testing the SharePointSmtpHelper class"&lt;/SPAN&gt;);&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9908769" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/MOSS+2007/default.aspx">MOSS 2007</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/WSS+v3/default.aspx">WSS v3</category></item><item><title>Introducing the SharePointWebPartHelper Class</title><link>http://blogs.msdn.com/jjameson/archive/2009/10/17/introducing-the-sharepointwebparthelper-class.aspx</link><pubDate>Sat, 17 Oct 2009 12:54:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9908548</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9908548.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9908548</wfw:commentRss><description>&lt;P&gt;In a previous post, I introduced the &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/03/31/introducing-the-dr-dada-approach-to-sharepoint-development.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/03/31/introducing-the-dr-dada-approach-to-sharepoint-development.aspx"&gt;DR.DADA approach to SharePoint development&lt;/A&gt; and how I typically use the concept of a &lt;A href="http://blogs.msdn.com/jjameson/archive/2007/03/22/what-s-in-a-name-defaultfeaturereceiver-vs-featureconfigurator.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2007/03/22/what-s-in-a-name-defaultfeaturereceiver-vs-featureconfigurator.aspx"&gt;FeatureConfigurator&lt;/A&gt; to automatically configure one or more aspects of a SharePoint site when activating my feature.&lt;/P&gt;
&lt;P&gt;For example, on my latest project, we needed a login page as well as a legal disclaimer page for a customer service portal based on Microsoft Office SharePoint Server (MOSS) 2007. Thus I created a "PublicSiteConfiguration" feature that, upon activation:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Automatically creates the &lt;STRONG&gt;/Public &lt;/STRONG&gt;site&lt;/LI&gt;
&lt;LI&gt;Populates the page content on the /Public/Pages/default.aspx page and adds an instance of a custom Login Form Web Part to the page&lt;/LI&gt;
&lt;LI&gt;Creates the /Public/Pages/Disclaimer.aspx page and populates its default content&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;I've already introduced the &lt;CODE&gt;&lt;A href="http://blogs.msdn.com/jjameson/archive/2009/10/09/introducing-the-sharepointpublishinghelper-class.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/10/09/introducing-the-sharepointpublishinghelper-class.aspx"&gt;SharePointPublishingHelper&lt;/A&gt;&lt;/CODE&gt; class that performs the bulk of the work in creating and configuring publishing pages. In this post, I want to cover the &lt;CODE&gt;SharePointWebPartHelper&lt;/CODE&gt; class. Like the &lt;CODE&gt;SharePointPublishingHelper&lt;/CODE&gt; class, the &lt;CODE&gt;SharePointWebPartHelper&lt;/CODE&gt; class is simply a collection of helper methods for the SharePoint API.&lt;/P&gt;
&lt;P&gt;&lt;CODE&gt;SharePointWebPartHelper&lt;/CODE&gt; makes it really easy to:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Attempt to retrieve a reference to a Web Part by specifying an &lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webpartpages.splimitedwebpartmanager.aspx" mce_href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webpartpages.splimitedwebpartmanager.aspx"&gt;SPLimitedWebPartManager&lt;/A&gt; for a specific page and the title of the Web Part you are trying to find&lt;/LI&gt;
&lt;LI&gt;Ensure a Web Part exists on a page (creating a new Web Part as necessary)&lt;/LI&gt;
&lt;LI&gt;Ensuring a &lt;A href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webpartpages.contenteditorwebpart.aspx" mce_href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webpartpages.contenteditorwebpart.aspx"&gt;ContentEditorWebPart&lt;/A&gt; exists on a page and that it is configured with the specified HTML content and title (as well as removing the "chrome", since -- at least in my experience -- you don't want to show this to users for this type of Web Part)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Note that one could argue that the stuff specific to the Content Editor Web Part doesn't really belong in this class, but nevertheless that's where it ended up after refactoring the code a few years ago on the Agilent Technologies project. [Actually, I believe it originally ended up in an even more generic &lt;CODE&gt;SharePointHelper&lt;/CODE&gt; class, but I've since refactored it even further into the &lt;CODE&gt;SharePointWebPartHelper&lt;/CODE&gt; class.]&lt;/P&gt;
&lt;P&gt;Anyway, here's the code for the &lt;CODE&gt;SharePointWebPartHelper&lt;/CODE&gt; class:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Diagnostics;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Globalization;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.IO;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Security.Permissions;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Web.UI.WebControls.WebParts;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Xml;

&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; Microsoft.SharePoint;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; Microsoft.SharePoint.Security;
&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; SPWebPartPages = Microsoft.SharePoint.WebPartPages;

&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; Fabrikam.Demo.CoreServices.Logging;

&lt;SPAN style="COLOR: #0000ff"&gt;namespace&lt;/SPAN&gt; Fabrikam.Demo.CoreServices.SharePoint
{
    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;summary&amp;gt;
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Exposes static methods for commonly used helper functions for
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; SharePoint Web Parts. This class cannot be inherited.
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/summary&amp;gt;
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;remarks&amp;gt;
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; All methods of the &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;b&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;SharePointWebPartHelper&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/b&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; class are static and
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; can therefore be called without creating an instance of the class.
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/remarks&amp;gt;
&lt;/SPAN&gt;    [&lt;SPAN style="COLOR: #2b91af"&gt;CLSCompliant&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;)]
    [&lt;SPAN style="COLOR: #2b91af"&gt;SharePointPermission&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;SecurityAction&lt;/SPAN&gt;.LinkDemand, ObjectModel = &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)]
    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;sealed&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;SharePointWebPartHelper
&lt;/SPAN&gt;    {
        &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; SharePointWebPartHelper() { } &lt;SPAN style="COLOR: #008000"&gt;// all members are static

&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;WebPart&lt;/SPAN&gt; CreateWebPart(
            SPWebPartPages.&lt;SPAN style="COLOR: #2b91af"&gt;SPLimitedWebPartManager&lt;/SPAN&gt; wpm,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; webPartId,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; webPartFilename,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; zoneId,
            &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; zoneIndex)
        {
            &lt;SPAN style="COLOR: #2b91af"&gt;Debug&lt;/SPAN&gt;.Assert(wpm != &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;);
            &lt;SPAN style="COLOR: #2b91af"&gt;Debug&lt;/SPAN&gt;.Assert(&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(webPartId) == &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;);
            &lt;SPAN style="COLOR: #2b91af"&gt;Debug&lt;/SPAN&gt;.Assert(&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(webPartFilename) == &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;);
            &lt;SPAN style="COLOR: #2b91af"&gt;Debug&lt;/SPAN&gt;.Assert(&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(zoneId) == &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;);

            &lt;SPAN style="COLOR: #2b91af"&gt;Logger&lt;/SPAN&gt;.LogDebug(
                &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                &lt;SPAN style="COLOR: #a31515"&gt;"Creating Web Part ({0}) on page ({1})..."&lt;/SPAN&gt;,
                webPartId,
                wpm.ServerRelativeUrl);

            &lt;SPAN style="COLOR: #2b91af"&gt;WebPart&lt;/SPAN&gt; webPart = &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;;

            &lt;SPAN style="COLOR: #2b91af"&gt;SPFile&lt;/SPAN&gt; wpFile = GetWebPartFileFromGallery(
                wpm.Web.Site,
                webPartFilename);

            &lt;SPAN style="COLOR: #2b91af"&gt;Debug&lt;/SPAN&gt;.Assert(wpFile != &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;);

            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; errorMessage = &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.Empty;

            &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #2b91af"&gt;Stream&lt;/SPAN&gt; stream = wpFile.OpenBinaryStream())
            {
                &lt;SPAN style="COLOR: #2b91af"&gt;XmlReader&lt;/SPAN&gt; reader = &lt;SPAN style="COLOR: #2b91af"&gt;XmlReader&lt;/SPAN&gt;.Create(stream);
                webPart = wpm.ImportWebPart(reader, &lt;SPAN style="COLOR: #0000ff"&gt;out&lt;/SPAN&gt; errorMessage);
            }

            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(errorMessage) == &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; message =
                    &lt;SPAN style="COLOR: #a31515"&gt;"Error importing Web Part ("
&lt;/SPAN&gt;                        + webPartFilename + &lt;SPAN style="COLOR: #a31515"&gt;"): "
&lt;/SPAN&gt;                        + errorMessage;

                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; SPWebPartPages.&lt;SPAN style="COLOR: #2b91af"&gt;WebPartPageUserException&lt;/SPAN&gt;(message);
            }

            webPart.ID = webPartId;
            wpm.AddWebPart(webPart, zoneId, zoneIndex);

            &lt;SPAN style="COLOR: #008000"&gt;// HACK: When adding the first, second, third, and fourth Web Parts
&lt;/SPAN&gt;            &lt;SPAN style="COLOR: #008000"&gt;// to a zone:
&lt;/SPAN&gt;            &lt;SPAN style="COLOR: #008000"&gt;//
&lt;/SPAN&gt;            &lt;SPAN style="COLOR: #008000"&gt;//    SPLimitedWebPartManager.AddWebPart(webPart, zoneId, zoneIndex)
&lt;/SPAN&gt;            &lt;SPAN style="COLOR: #008000"&gt;//
&lt;/SPAN&gt;            &lt;SPAN style="COLOR: #008000"&gt;// behaves as expected, meaning that
&lt;/SPAN&gt;            &lt;SPAN style="COLOR: #008000"&gt;// (webPart.ZoneIndex == zoneIndex).
&lt;/SPAN&gt;            &lt;SPAN style="COLOR: #008000"&gt;//
&lt;/SPAN&gt;            &lt;SPAN style="COLOR: #008000"&gt;// However, when adding the fifth and sixth Web Parts to a zone,
&lt;/SPAN&gt;            &lt;SPAN style="COLOR: #008000"&gt;// then (webPart.ZoneIndex == zoneIndex + 1).
&lt;/SPAN&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (webPart.ZoneIndex &amp;gt; zoneIndex)
            {
                &lt;SPAN style="COLOR: #2b91af"&gt;Debug&lt;/SPAN&gt;.Assert(zoneIndex &amp;gt;= 4);

                &lt;SPAN style="COLOR: #2b91af"&gt;Logger&lt;/SPAN&gt;.LogDebug(
                    &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                    &lt;SPAN style="COLOR: #a31515"&gt;"HACK: webPart.ZoneIndex ({0})"
&lt;/SPAN&gt;                        + &lt;SPAN style="COLOR: #a31515"&gt;" is greater than zoneIndex ({1})."
&lt;/SPAN&gt;                        + &lt;SPAN style="COLOR: #a31515"&gt;" Setting zoneIndex to {0}..."&lt;/SPAN&gt;,
                    webPart.ZoneIndex,
                    zoneIndex);

                zoneIndex = webPart.ZoneIndex;
            }

            &lt;SPAN style="COLOR: #2b91af"&gt;Debug&lt;/SPAN&gt;.Assert(webPart.ZoneIndex == zoneIndex);
            zoneIndex++;
            
            &lt;SPAN style="COLOR: #2b91af"&gt;Logger&lt;/SPAN&gt;.LogInfo(
                &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                &lt;SPAN style="COLOR: #a31515"&gt;"Successfully created Web Part ({0}) on page ({1})."&lt;/SPAN&gt;,
                webPartId,
                wpm.ServerRelativeUrl);

            &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; webPart;
        }

        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;summary&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Ensures that a specific Web Part exists on a page.
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/summary&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="wpm"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The Web Part manager for the page.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="webPartId"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The unique identifier for the Web Part.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="webPartFileName"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The .dwp or .webpart file in the
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Web Part gallery (used to import the Web Part if it does not exist).
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="zoneId"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The zone the Web Part should reside in.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="zoneIndex"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The index of the Web Part relative to other
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Web Parts in the zone. If the Web Part is created, the index is
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; incremented.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;returns&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The new or existing Web Part on the page.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/returns&amp;gt;
&lt;/SPAN&gt;        [System.Diagnostics.CodeAnalysis.&lt;SPAN style="COLOR: #2b91af"&gt;SuppressMessage&lt;/SPAN&gt;(
            &lt;SPAN style="COLOR: #a31515"&gt;"Microsoft.Design"&lt;/SPAN&gt;,
            &lt;SPAN style="COLOR: #a31515"&gt;"CA1045:DoNotPassTypesByReference"&lt;/SPAN&gt;,
            Justification = &lt;SPAN style="COLOR: #a31515"&gt;"The zoneIndex is incremented when the Web Part is"
&lt;/SPAN&gt;                + &lt;SPAN style="COLOR: #a31515"&gt;" added."&lt;/SPAN&gt;)]
        &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;WebPart&lt;/SPAN&gt; EnsureWebPart(
            SPWebPartPages.&lt;SPAN style="COLOR: #2b91af"&gt;SPLimitedWebPartManager&lt;/SPAN&gt; wpm,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; webPartId,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; webPartFileName,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; zoneId,
            &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; zoneIndex)
        {
            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (wpm == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentNullException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"wpm"&lt;/SPAN&gt;);
            }

            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(webPartId) == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentException&lt;/SPAN&gt;(
                    &lt;SPAN style="COLOR: #a31515"&gt;"The Web Part Id must be specified."&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"webPartId"&lt;/SPAN&gt;);
            }

            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(webPartFileName) == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentException&lt;/SPAN&gt;(
                    &lt;SPAN style="COLOR: #a31515"&gt;"The Web Part file name must be specified."&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"webPartFileName"&lt;/SPAN&gt;);
            }

            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(zoneId) == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentException&lt;/SPAN&gt;(
                    &lt;SPAN style="COLOR: #a31515"&gt;"The Web Part zone must be specified."&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"zoneId"&lt;/SPAN&gt;);
            }

            &lt;SPAN style="COLOR: #2b91af"&gt;WebPart&lt;/SPAN&gt; webPart = wpm.WebParts[webPartId];

            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (webPart == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
            {
                webPart = CreateWebPart(wpm, webPartId, webPartFileName,
                    zoneId, &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex);
            }
            &lt;SPAN style="COLOR: #0000ff"&gt;else
&lt;/SPAN&gt;            {
                &lt;SPAN style="COLOR: #008000"&gt;// HACK: webPart.Zone appears to always be null (SharePoint bug?)
&lt;/SPAN&gt;                &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (webPart.Zone == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
                {
                    &lt;SPAN style="COLOR: #2b91af"&gt;Logger&lt;/SPAN&gt;.LogDebug(
                        &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                        &lt;SPAN style="COLOR: #a31515"&gt;"Unable to check zone for Web Part ({0})"
&lt;/SPAN&gt;                            + &lt;SPAN style="COLOR: #a31515"&gt;" because webPart.Zone is null."&lt;/SPAN&gt;,
                        webPartId);
                }
                &lt;SPAN style="COLOR: #0000ff"&gt;else&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (webPart.Zone.ID != zoneId)
                {
                    &lt;SPAN style="COLOR: #2b91af"&gt;Logger&lt;/SPAN&gt;.LogDebug(
                        &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                        &lt;SPAN style="COLOR: #a31515"&gt;"Moving Web Part ({0}) to zone ({1})..."&lt;/SPAN&gt;,
                        webPartId,
                        zoneId);

                    wpm.MoveWebPart(webPart, zoneId, zoneIndex);
                    wpm.SaveChanges(webPart);

                    &lt;SPAN style="COLOR: #2b91af"&gt;Logger&lt;/SPAN&gt;.LogInfo(
                        &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                        &lt;SPAN style="COLOR: #a31515"&gt;"Successfully moved Web Part ({0}) to zone ({1})."&lt;/SPAN&gt;,
                        webPartId,
                        zoneId);
                }
            }

            &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; webPart;
        }

        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;summary&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Finds the first Web Part with the specified title.
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/summary&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;remarks&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; This is useful in cases where the Web Part ID is not specified
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; when it was added to the collection of Web Parts (thus generating
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; a random identifier and making SPLimitedWebPartCollection[id]
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; effectively useless).
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/remarks&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="wpm"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The Web Part manager for the page.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="webPartTitle"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The title of the Web Part to find.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;returns&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;A Web Part object (if one is found), otherwise null.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/returns&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;WebPart&lt;/SPAN&gt; FindWebPartByTitle(
            SPWebPartPages.&lt;SPAN style="COLOR: #2b91af"&gt;SPLimitedWebPartManager&lt;/SPAN&gt; wpm,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; webPartTitle)
        {
            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (wpm == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentNullException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"wpm"&lt;/SPAN&gt;);
            }

            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(webPartTitle) == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentException&lt;/SPAN&gt;(
                    &lt;SPAN style="COLOR: #a31515"&gt;"The Web Part title must be specified."&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"webPartTitle"&lt;/SPAN&gt;);
            }

            &lt;SPAN style="COLOR: #2b91af"&gt;Logger&lt;/SPAN&gt;.LogDebug(
                &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                &lt;SPAN style="COLOR: #a31515"&gt;"Attemping to find Web Part ({0}) on page ({1})..."&lt;/SPAN&gt;,
                webPartTitle,
                wpm.ServerRelativeUrl);

            &lt;SPAN style="COLOR: #0000ff"&gt;for&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; i = 0; i &amp;lt; wpm.WebParts.Count; i++)
            {
                &lt;SPAN style="COLOR: #2b91af"&gt;WebPart&lt;/SPAN&gt; webPart = wpm.WebParts[i];

                &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.Compare(
                        webPart.Title,
                        webPartTitle,
                        &lt;SPAN style="COLOR: #2b91af"&gt;StringComparison&lt;/SPAN&gt;.OrdinalIgnoreCase) == 0)
                {
                    &lt;SPAN style="COLOR: #2b91af"&gt;Logger&lt;/SPAN&gt;.LogDebug(
                        &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                        &lt;SPAN style="COLOR: #a31515"&gt;"Found Web Part ({0}) on page ({1})."&lt;/SPAN&gt;,
                        webPartTitle,
                        wpm.ServerRelativeUrl);

                    &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; webPart;
                }
            }

            &lt;SPAN style="COLOR: #2b91af"&gt;Logger&lt;/SPAN&gt;.LogDebug(
                &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                &lt;SPAN style="COLOR: #a31515"&gt;"Unable to find Web Part ({0}) on page ({1})."&lt;/SPAN&gt;,
                webPartTitle,
                wpm.ServerRelativeUrl);

            &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;;
        }

        &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;SPFile&lt;/SPAN&gt; GetWebPartFileFromGallery(
            &lt;SPAN style="COLOR: #2b91af"&gt;SPSite&lt;/SPAN&gt; site,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; webPartFilename)
        {
            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (site == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentNullException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"site"&lt;/SPAN&gt;);
            }

            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (webPartFilename == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentNullException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"webPartFilename"&lt;/SPAN&gt;);
            }

            webPartFilename = webPartFilename.Trim();
            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(webPartFilename))
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentException&lt;/SPAN&gt;(
                    &lt;SPAN style="COLOR: #a31515"&gt;"The Web Part filename must be specified."&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"webPartFilename"&lt;/SPAN&gt;);
            }

            &lt;SPAN style="COLOR: #2b91af"&gt;Logger&lt;/SPAN&gt;.LogDebug(
                &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                &lt;SPAN style="COLOR: #a31515"&gt;"Getting Web Part file ({0}) from site ({1}) gallery..."&lt;/SPAN&gt;,
                webPartFilename,
                site.Url);

            &lt;SPAN style="COLOR: #2b91af"&gt;SPList&lt;/SPAN&gt; wpGallery = site.GetCatalog(&lt;SPAN style="COLOR: #2b91af"&gt;SPListTemplateType&lt;/SPAN&gt;.WebPartCatalog);

            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; camlQuery = &lt;SPAN style="COLOR: #a31515"&gt;"&amp;lt;Where&amp;gt;&amp;lt;Eq&amp;gt;&amp;lt;FieldRef Name=\"FileLeafRef\" /&amp;gt;"
&lt;/SPAN&gt;                + &lt;SPAN style="COLOR: #a31515"&gt;"&amp;lt;Value Type=\"File\"&amp;gt;"&lt;/SPAN&gt; + webPartFilename + &lt;SPAN style="COLOR: #a31515"&gt;"&amp;lt;/Value&amp;gt;&amp;lt;/Eq&amp;gt;&amp;lt;/Where&amp;gt;"&lt;/SPAN&gt;;

            &lt;SPAN style="COLOR: #2b91af"&gt;SPQuery&lt;/SPAN&gt; query = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;SPQuery&lt;/SPAN&gt;();
            query.Query = camlQuery;

            &lt;SPAN style="COLOR: #2b91af"&gt;SPListItemCollection&lt;/SPAN&gt; webParts = wpGallery.GetItems(query);
            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (webParts.Count == 0)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; message = &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.Format(
                    &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                    &lt;SPAN style="COLOR: #a31515"&gt;"Web Part ({0}) was not found in the Web Part Gallery."&lt;/SPAN&gt;,
                    webPartFilename);
                
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentException&lt;/SPAN&gt;(
                    message,
                    &lt;SPAN style="COLOR: #a31515"&gt;"webPartFilename"&lt;/SPAN&gt;);
            }

            &lt;SPAN style="COLOR: #2b91af"&gt;Logger&lt;/SPAN&gt;.LogDebug(
                &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                &lt;SPAN style="COLOR: #a31515"&gt;"Found Web Part file ({0}) in site ({1}) gallery."&lt;/SPAN&gt;,
                webPartFilename,
                site.Url);

            &lt;SPAN style="COLOR: #2b91af"&gt;Debug&lt;/SPAN&gt;.Assert(webParts.Count == 1);
            &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; webParts[0].File;
        }

        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;summary&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Ensures that a Content Editor Web Part exists on a page
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; and is configured with the specified settings.
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/summary&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="wpm"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The Web Part manager for the page.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="webPartId"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The unique identifier for the Web Part.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="zoneId"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The zone the Web Part should reside in.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="zoneIndex"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The index of the Web Part relative to other
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Web Parts in the zone. If the Web Part is created, the index is
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; incremented.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="htmlContent"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The content to display within the Web
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Part.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;param name="title"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The title of the Web Part.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/param&amp;gt;
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;returns&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;The new or existing Web Part on the page.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/returns&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;        
&lt;/SPAN&gt;        [System.Diagnostics.CodeAnalysis.&lt;SPAN style="COLOR: #2b91af"&gt;SuppressMessage&lt;/SPAN&gt;(
            &lt;SPAN style="COLOR: #a31515"&gt;"Microsoft.Design"&lt;/SPAN&gt;,
            &lt;SPAN style="COLOR: #a31515"&gt;"CA1045:DoNotPassTypesByReference"&lt;/SPAN&gt;,
            Justification=&lt;SPAN style="COLOR: #a31515"&gt;"The zoneIndex is incremented when the Web Part is"
&lt;/SPAN&gt;                + &lt;SPAN style="COLOR: #a31515"&gt;" added."&lt;/SPAN&gt;)]
        &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; SPWebPartPages.&lt;SPAN style="COLOR: #2b91af"&gt;ContentEditorWebPart
&lt;/SPAN&gt;            EnsureContentEditorWebPart(
                SPWebPartPages.&lt;SPAN style="COLOR: #2b91af"&gt;SPLimitedWebPartManager&lt;/SPAN&gt; wpm,
                &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; webPartId,
                &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; zoneId,
                &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; zoneIndex,
                &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; htmlContent,
                &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; title)
        {
            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (wpm == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentNullException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"wpm"&lt;/SPAN&gt;);
            }

            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (webPartId == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentNullException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"webPartId"&lt;/SPAN&gt;);
            }

            webPartId = webPartId.Trim();
            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(webPartId))
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentException&lt;/SPAN&gt;(
                    &lt;SPAN style="COLOR: #a31515"&gt;"The Web Part ID must be specified."&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"webPartId"&lt;/SPAN&gt;);
            }

            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (zoneId == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentNullException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"zoneId"&lt;/SPAN&gt;);
            }

            zoneId = zoneId.Trim();
            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(zoneId))
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentException&lt;/SPAN&gt;(
                    &lt;SPAN style="COLOR: #a31515"&gt;"The Web Part zone must be specified."&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"zoneId"&lt;/SPAN&gt;);
            }

            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (htmlContent == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentNullException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"htmlContent"&lt;/SPAN&gt;);
            }

            htmlContent = htmlContent.Trim();
            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.IsNullOrEmpty(htmlContent))
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentException&lt;/SPAN&gt;(
                    &lt;SPAN style="COLOR: #a31515"&gt;"The HTML content must be specified."&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"htmlContent"&lt;/SPAN&gt;);
            }

            &lt;SPAN style="COLOR: #008000"&gt;// Note: title is optional

&lt;/SPAN&gt;            &lt;SPAN style="COLOR: #2b91af"&gt;Logger&lt;/SPAN&gt;.LogDebug(
                &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                &lt;SPAN style="COLOR: #a31515"&gt;"Ensuring Content Editor Web Part ({0}) on page ({1})..."&lt;/SPAN&gt;,
                webPartId,
                wpm.ServerRelativeUrl);

            SPWebPartPages.&lt;SPAN style="COLOR: #2b91af"&gt;ContentEditorWebPart&lt;/SPAN&gt; webPart =
                (SPWebPartPages.&lt;SPAN style="COLOR: #2b91af"&gt;ContentEditorWebPart&lt;/SPAN&gt;) EnsureWebPart(
                    wpm,
                    webPartId,
                    &lt;SPAN style="COLOR: #a31515"&gt;"MSContentEditor.dwp"&lt;/SPAN&gt;,
                    zoneId,
                    &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex);

            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (webPart.Content == &lt;SPAN style="COLOR: #0000ff"&gt;null
&lt;/SPAN&gt;                || webPart.Content.InnerText != htmlContent
                || webPart.Title != title
                || webPart.ChromeType != &lt;SPAN style="COLOR: #2b91af"&gt;PartChromeType&lt;/SPAN&gt;.None)
            {
                &lt;SPAN style="COLOR: #2b91af"&gt;Logger&lt;/SPAN&gt;.LogDebug(
                    &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                    &lt;SPAN style="COLOR: #a31515"&gt;"Updating properties of Content Editor Web Part ({0}) on"
&lt;/SPAN&gt;                        + &lt;SPAN style="COLOR: #a31515"&gt;" page ({1})..."&lt;/SPAN&gt;,
                    webPartId,
                    wpm.ServerRelativeUrl);

                &lt;SPAN style="COLOR: #008000"&gt;// To bring content into the Content Editor Web Part,
&lt;/SPAN&gt;                &lt;SPAN style="COLOR: #008000"&gt;// we need to use an XML Document
&lt;/SPAN&gt;                &lt;SPAN style="COLOR: #2b91af"&gt;XmlDocument&lt;/SPAN&gt; xmlDoc = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;XmlDocument&lt;/SPAN&gt;();
                &lt;SPAN style="COLOR: #2b91af"&gt;XmlElement&lt;/SPAN&gt; xmlElement = xmlDoc.CreateElement(&lt;SPAN style="COLOR: #a31515"&gt;"HtmlContent"&lt;/SPAN&gt;);
                xmlElement.InnerText = htmlContent;
                webPart.Content = xmlElement;

                webPart.Title = title;
                webPart.ChromeType = &lt;SPAN style="COLOR: #2b91af"&gt;PartChromeType&lt;/SPAN&gt;.None;

                wpm.SaveChanges(webPart);

                &lt;SPAN style="COLOR: #2b91af"&gt;Logger&lt;/SPAN&gt;.LogInfo(
                    &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                    &lt;SPAN style="COLOR: #a31515"&gt;"Successfully updated properties of Content Editor Web Part"
&lt;/SPAN&gt;                        + &lt;SPAN style="COLOR: #a31515"&gt;" ({0}) on page ({1})."&lt;/SPAN&gt;,
                    webPartId,
                    wpm.ServerRelativeUrl);
            }
            &lt;SPAN style="COLOR: #0000ff"&gt;else
&lt;/SPAN&gt;            {
                &lt;SPAN style="COLOR: #2b91af"&gt;Logger&lt;/SPAN&gt;.LogDebug(
                    &lt;SPAN style="COLOR: #2b91af"&gt;CultureInfo&lt;/SPAN&gt;.InvariantCulture,
                    &lt;SPAN style="COLOR: #a31515"&gt;"The Content Editor Web Part ({0}) on page ({1}) is already"
&lt;/SPAN&gt;                        + &lt;SPAN style="COLOR: #a31515"&gt;" configured with the expected settings."&lt;/SPAN&gt;,
                    webPartId,
                    wpm.ServerRelativeUrl);
            }

            &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; webPart;
        }
    }
}&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Most of the code in the &lt;CODE&gt;SharePointWebPartHelper&lt;/CODE&gt; class is very straightforward. The most interesting hack -- er, I mean &lt;EM&gt;workaround&lt;/EM&gt; -- in the code is to handle the scenario where the &lt;CODE&gt;zoneIndex&lt;/CODE&gt; is sometimes mysteriously incremented by more than one, but you can read more about this in a &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/06/05/splimitedwebpartmanager-addwebpart-mysteriously-increments-zoneindex.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/06/05/splimitedwebpartmanager-addwebpart-mysteriously-increments-zoneindex.aspx"&gt;previous post&lt;/A&gt; -- if you are really interested.&lt;/P&gt;
&lt;P&gt;Using the &lt;CODE&gt;SharePointWebPartHelper&lt;/CODE&gt; class couldn't be easier. For a simple example, consider the scenario that I mentioned earlier about adding a Login Form Web Part to a page:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;            &lt;SPAN style="COLOR: #008000"&gt;// Configure Web Parts
&lt;/SPAN&gt;            SPWebPartPages.&lt;SPAN style="COLOR: #2b91af"&gt;SPLimitedWebPartManager&lt;/SPAN&gt; wpm =
                publicWeb.GetLimitedWebPartManager(
                    page.Url,
                    &lt;SPAN style="COLOR: #2b91af"&gt;PersonalizationScope&lt;/SPAN&gt;.Shared);

            &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; (wpm)
            {
                &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; zoneId = &lt;SPAN style="COLOR: #a31515"&gt;"LeftColumnZone"&lt;/SPAN&gt;;
                &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; zoneIndex = 0;

                &lt;SPAN style="COLOR: #2b91af"&gt;LoginFormWebPart&lt;/SPAN&gt; loginForm =
                    (&lt;SPAN style="COLOR: #2b91af"&gt;LoginFormWebPart&lt;/SPAN&gt;) &lt;SPAN style="COLOR: #2b91af"&gt;SharePointWebPartHelper&lt;/SPAN&gt;.EnsureWebPart(
                        wpm,
                        &lt;SPAN style="COLOR: #a31515"&gt;"LoginForm"&lt;/SPAN&gt;,
                        &lt;SPAN style="COLOR: #a31515"&gt;"Fabrikam_LoginForm.webpart"&lt;/SPAN&gt;,
                        zoneId,
                        &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex);

                loginForm.DisplayRememberMe = &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;;
                wpm.SaveChanges(loginForm);

                &lt;SPAN style="COLOR: #008000"&gt;// HACK: Avoid memory leak in SPLimitedWebPartManager
&lt;/SPAN&gt;                &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (wpm.Web != &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
                {
                    wpm.Web.Dispose();
                }
            }&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Just be sure to avoid &lt;A href="http://blogs.msdn.com/jjameson/archive/2008/04/09/memory-leak-in-splimitedwebpartmanager-a-k-a-idisposables-containing-idisposables.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2008/04/09/memory-leak-in-splimitedwebpartmanager-a-k-a-idisposables-containing-idisposables.aspx"&gt;the memory leak in SPLimitedWebPartManager&lt;/A&gt;, like I show in the code example above.&lt;/P&gt;
&lt;P&gt;Here's another code example where I configured a bunch of Web Parts on a search results page:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;SPAN style="COLOR: #0000ff"&gt;namespace&lt;/SPAN&gt; Fabrikam.Web.Search.Configuration
{
    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;summary&amp;gt;
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Exposes static methods for configuring the &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;b&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;Fabrikam.Web.Search&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/b&amp;gt;
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; feature. This class cannot be inherited.
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/summary&amp;gt;
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;remarks&amp;gt;
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; All methods of the &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;b&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;FeatureConfigurator&lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/b&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; class are static and can
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; therefore be called without creating an instance of the class.
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: #808080"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #808080"&gt;&amp;lt;/remarks&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;  
&lt;/SPAN&gt;    [CLSCompliant(&lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;)]
    [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)]
    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;sealed&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;FeatureConfigurator
&lt;/SPAN&gt;    {
        ...

        &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;void&lt;/SPAN&gt; ConfigureSearchResultsPageWebParts(
            SPWeb searchWeb,
            PublishingPage searchResultsPage,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; defaultSearchResultsPageUrl,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; scopeName,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; additionalQueryTerms,
            &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; contextualScopeUrl)
        {
            SPWebPartPages.SPLimitedWebPartManager wpm =
                searchWeb.GetLimitedWebPartManager(
                    searchResultsPage.Url, PersonalizationScope.Shared);

            &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; (wpm)
            {
&lt;SPAN style="COLOR: #0000ff"&gt;                #region&lt;/SPAN&gt; Zone1

                &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; zoneId = &lt;SPAN style="COLOR: #a31515"&gt;"Zone1"&lt;/SPAN&gt;;
                &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; zoneIndex = 0;

                SharePointWebPartHelper.EnsureContentEditorWebPart(
                    wpm,
                    &lt;SPAN style="COLOR: #a31515"&gt;"startNewSearchHeading"&lt;/SPAN&gt;,
                    zoneId,
                    &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex,
                    &lt;SPAN style="COLOR: #a31515"&gt;"&amp;lt;h2 class='accent3'&amp;gt;Start a new search&amp;lt;/h2&amp;gt;"&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"Start New Search Heading"&lt;/SPAN&gt;);

                SearchBoxEx searchBox =
                    (SearchBoxEx)SharePointWebPartHelper.EnsureWebPart(
                        wpm,
                        &lt;SPAN style="COLOR: #a31515"&gt;"searchBox"&lt;/SPAN&gt;,
                        &lt;SPAN style="COLOR: #a31515"&gt;"SearchBox.dwp"&lt;/SPAN&gt;,
                        zoneId,
                        &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex);

                searchBox.DropDownModeEx = DropDownModesEx.HideScopeDD;
                searchBox.SearchResultPageURL = defaultSearchResultsPageUrl;
                searchBox.Width = &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.Empty;

                wpm.SaveChanges(searchBox);

                SharePointWebPartHelper.EnsureContentEditorWebPart(
                    wpm,
                    &lt;SPAN style="COLOR: #a31515"&gt;"refineSearchHeading"&lt;/SPAN&gt;,
                    zoneId,
                    &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex,
                    &lt;SPAN style="COLOR: #a31515"&gt;"&amp;lt;h2 class='accent3'&amp;gt;Refine your search&amp;lt;/h2&amp;gt;"&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"Refine Search Heading"&lt;/SPAN&gt;);

                FabrikamSearchBoxWebPart searchScopeOptions =
                    (FabrikamSearchBoxWebPart)SharePointWebPartHelper.EnsureWebPart(
                        wpm,
                        &lt;SPAN style="COLOR: #a31515"&gt;"searchScopeOptions"&lt;/SPAN&gt;,
                        &lt;SPAN style="COLOR: #a31515"&gt;"FabrikamSearchBox.webpart"&lt;/SPAN&gt;,
                        zoneId,
                        &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex);

                searchScopeOptions.ShowSearchBox = &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;;
                wpm.SaveChanges(searchScopeOptions);

                ConfigureFacetedSearchWebParts(
                    wpm,
                    zoneId,
                    &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex,
                    scopeName);

&lt;SPAN style="COLOR: #0000ff"&gt;                #endregion
&lt;/SPAN&gt;                
&lt;SPAN style="COLOR: #0000ff"&gt;                #region&lt;/SPAN&gt; Zone2

                zoneId = &lt;SPAN style="COLOR: #a31515"&gt;"Zone2"&lt;/SPAN&gt;;
                zoneIndex = 0;

                SharePointWebPartHelper.EnsureWebPart(
                    wpm,
                    &lt;SPAN style="COLOR: #a31515"&gt;"searchTabs"&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"FabrikamListBoundTabStrip.webpart"&lt;/SPAN&gt;,
                    zoneId,
                    &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex);

                SharePointWebPartHelper.EnsureWebPart(
                    wpm,
                    &lt;SPAN style="COLOR: #a31515"&gt;"searchSummary"&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"SearchSummary.dwp"&lt;/SPAN&gt;,
                    zoneId,
                    &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex);

                &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; showBestBetsWebPart = &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;;

                &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.Compare(
                    searchResultsPage.Name,
                    &lt;SPAN style="COLOR: #a31515"&gt;"Results.aspx"&lt;/SPAN&gt;,
                    StringComparison.OrdinalIgnoreCase) == 0)
                {
                    showBestBetsWebPart = &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;;
                }
                &lt;SPAN style="COLOR: #0000ff"&gt;else&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;.Compare(
                    searchResultsPage.Name,
                    &lt;SPAN style="COLOR: #a31515"&gt;"AllSitesResults.aspx"&lt;/SPAN&gt;,
                    StringComparison.OrdinalIgnoreCase) == 0)
                {
                    showBestBetsWebPart = &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;;
                }

                &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (showBestBetsWebPart == &lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)
                {
                    ConfigureBestBetsWebPartForSiteSearch(
                        wpm,
                        zoneId,
                        &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex);
                }

                SearchStatsWebPart searchStats =
                    (SearchStatsWebPart) SharePointWebPartHelper.EnsureWebPart(
                        wpm,
                        &lt;SPAN style="COLOR: #a31515"&gt;"searchStats"&lt;/SPAN&gt;,
                        &lt;SPAN style="COLOR: #a31515"&gt;"searchStats.dwp"&lt;/SPAN&gt;,
                        zoneId,
                        &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex);

                searchStats.DisplayResponseTime = &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;;
                wpm.SaveChanges(searchStats);
                
                SharePointWebPartHelper.EnsureWebPart(
                    wpm,
                    &lt;SPAN style="COLOR: #a31515"&gt;"searchPaging1"&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"SearchPaging.dwp"&lt;/SPAN&gt;,
                    zoneId,
                    &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex);

                ConfigureCoreResultsWebPartsForSiteSearch(
                    wpm,
                    zoneId,
                    &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex,
                    scopeName);

                SharePointWebPartHelper.EnsureWebPart(
                    wpm,
                    &lt;SPAN style="COLOR: #a31515"&gt;"searchPaging2"&lt;/SPAN&gt;,
                    &lt;SPAN style="COLOR: #a31515"&gt;"SearchPaging.dwp"&lt;/SPAN&gt;,
                    zoneId,
                    &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex);

                &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (additionalQueryTerms != &lt;SPAN style="COLOR: #0000ff"&gt;null
&lt;/SPAN&gt;                    || contextualScopeUrl != &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
                {
                    ConfigureCoreResultsExtensionWebPart(
                        wpm,
                        additionalQueryTerms,
                        contextualScopeUrl,
                        zoneId,
                        &lt;SPAN style="COLOR: #0000ff"&gt;ref&lt;/SPAN&gt; zoneIndex);
                }

&lt;SPAN style="COLOR: #0000ff"&gt;                #endregion
&lt;/SPAN&gt;                
                &lt;SPAN style="COLOR: #008000"&gt;// HACK: Avoid memory leak in SPLimitedWebPartManager
&lt;/SPAN&gt;                &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (wpm.Web != &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)
                {
                    wpm.Web.Dispose();
                }
            }
        }
    }
}
&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Even though I didn't add any comments to this (rather lengthy) method, I think you'll find it is actually very easy to understand simply by reading the method names and parameters -- or at least that's what I hope for the people that are actually maintaining this code from my previous project ;-)&lt;/P&gt;
&lt;P&gt;I hope you find the &lt;CODE&gt;SharePointPublishingHelper&lt;/CODE&gt; and &lt;CODE&gt;SharePointWebPartHelper&lt;/CODE&gt; classes as useful as I have over the past several years.&lt;/P&gt;
&lt;P&gt;Be sure to stay tuned, because there are more SharePoint helper classes to come, but my daughter just woke up and now I need to go make some pancakes!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9908548" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/MOSS+2007/default.aspx">MOSS 2007</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/WSS+v3/default.aspx">WSS v3</category></item><item><title>Event ID 10016, KB 920783, and the WSS_WPG Group</title><link>http://blogs.msdn.com/jjameson/archive/2009/10/17/event-id-10016-kb-920783-and-the-wss-wpg-group.aspx</link><pubDate>Sat, 17 Oct 2009 11:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9908545</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9908545.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9908545</wfw:commentRss><description>&lt;P&gt;If you've ever deployed Windows SharePoint Services (WSS) v3 or Microsoft Office SharePoint Server (MOSS) 2007 in a least privilege configuration, you have undoubtedly encountered errors similar to the following in your Windows event log:&lt;/P&gt;
&lt;BLOCKQUOTE class="directQuote errorMessage"&gt;The application-specific permission settings do not grant Local Activation permission for the COM Server application with CLSID {61738644-F196-11D0-9953-00C04FD919C1} to the user TECHTOOLBOX\svc-sharepoint-dev SID (S-1-5-21-3914637029-2275272621-3670275343-1145) from address LocalHost (Using LRPC). This security permission can be modified using the Component Services administrative tool.&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Specifically, I am referring to Event ID 10016 and 10017.&lt;/P&gt;
&lt;P&gt;While these errors are apparently benign, it is still rather annoying to have your event logs flooded with this kind of "noise." [Personally, I very much like to see servers come up "clean" after a reboot (meaning no new errors or warnings in the event log). This is especially true when you use something like &lt;A href="http://www.microsoft.com/systemcenter/operationsmanager/en/us/default.aspx" mce_href="http://www.microsoft.com/systemcenter/operationsmanager/en/us/default.aspx"&gt;Systems Center Operations Manager (SCOM)&lt;/A&gt; to monitor your servers, and one or more members of the Operations team receives notification whenever an error occurs on a Production server.]&lt;/P&gt;
&lt;P&gt;There are lots of sources out on the Internet that provide the steps necessary to resolve these errors (essentially you need to grant the SharePoint service account Local Activation permission to the IIS WAMREG Admin Service).&lt;/P&gt;
&lt;P&gt;This week, I was glad to discover that Microsoft has a KnowledgeBase article (&lt;A href="http://support.microsoft.com/kb/920783" mce_href="http://support.microsoft.com/kb/920783"&gt;KB 920783&lt;/A&gt;) describing the errors and the associated workaround. [This KB article appears to have been published over two years ago, but honestly, I was completely unaware of it until just yesterday when I was building out the Production MOSS 2007 environment on my latest project.]&lt;/P&gt;
&lt;P&gt;However, I see two problems with KB 920783: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;First, it doesn't mention Microsoft Office SharePoint Server (MOSS) 2007 -- which might explain why I never came across this KB before when searching the Internet. Sure, we all know that MOSS 2007 is built on top of WSS v3 and thus KB articles that apply to "Microsoft Windows SharePoint Services 3.0" almost always apply to "Microsoft Office SharePoint Server 2007", but if you don't specifically state that, you shouldn't expect Bing or Google to return the KB article when searching for something like "MOSS 10016" or "Microsoft Office SharePoint Server 10016". Right?&lt;/LI&gt;
&lt;LI&gt;Second, and much more important, the KB article instructs you to:&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE&gt;&lt;SPAN class=directQuote&gt;"type the domain user account that you specified as the Windows SharePoint Services 3.0 service account"&lt;/SPAN&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I definitely don't recommend doing that -- unless you just like making more work for yourself than necessary. Instead, you should specify the local &lt;STRONG&gt;WSS_WPG &lt;/STRONG&gt;group rather than a specific user. This is what I've been doing for the last couple of years so trust me, it works.&lt;/P&gt;
&lt;P&gt;The reason why I recommend using the "Windows SharePoint Services Worker Process Group" instead of individual users is that you are likely (or at least hopefully) using different service accounts for your SharePoint farm (e.g. TECHTOOLBOX\svc-sharepoint) and for the application pools behind your Web applications (e.g. TECHTOOLBOX\svc-web-fabrikam). Furthermore, if you are doing a large enterprise deployment of SharePoint, you likely have multiple Web applications (e.g. SSP, My Sites, etc.) that each utilize a separate service account.&lt;/P&gt;
&lt;P&gt;Rather than granting the Local Activation permission to each of these service accounts individually, it is much more effective to just grant the permission to the WSS_WPG group instead.&lt;/P&gt;
&lt;BLOCKQUOTE class=note&gt;
&lt;DIV class=noteTitle&gt;&lt;STRONG&gt;Note&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;DIV&gt;When creating a new Web application, SharePoint automatically adds the corresponding service account to the local WSS_WPG group on each SharePoint server in your farm.&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;[Update (2009-10-29):&lt;/P&gt;
&lt;P&gt;Matt McEvoy contacted me last Monday regarding the fact that I didn't specify the &lt;STRONG&gt;WSS_ADMIN_WPG &lt;/STRONG&gt;group -- only the &lt;STRONG&gt;WSS_WPG&lt;/STRONG&gt; group.&lt;/P&gt;
&lt;P&gt;Ugh...that will teach me to try to recall something like this from memory. When I was writing this blog post, I mistakenly thought that the service account for the SharePoint farm was added to both WSS_ADMIN_WPG and WSS_WPG. However, this isn't the case.&lt;/P&gt;
&lt;P&gt;Therefore you need to be sure to apply the steps in &lt;A href="http://support.microsoft.com/kb/920783" mce_href="http://support.microsoft.com/kb/920783"&gt;KB 920783&lt;/A&gt; using both groups if you want to rid your event logs of these errors once and for all. Again, this is assuming you are using least privilege accounts -- which I certainly hope you are.&lt;/P&gt;
&lt;P&gt;Thanks, Matt, for pointing out my omission.]&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9908545" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Simplify/default.aspx">Simplify</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/MOSS+2007/default.aspx">MOSS 2007</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/WSS+v3/default.aspx">WSS v3</category></item><item><title>Managing Group Membership via Group Policy - Part 2</title><link>http://blogs.msdn.com/jjameson/archive/2009/10/15/managing-group-membership-via-group-policy-part-2.aspx</link><pubDate>Thu, 15 Oct 2009 13:04:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9907648</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9907648.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9907648</wfw:commentRss><description>&lt;P&gt;In &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/10/15/managing-group-membership-via-group-policy-part-1.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/10/15/managing-group-membership-via-group-policy-part-1.aspx"&gt;Part 1 of this post&lt;/A&gt;, I explained the Group Policy object (named &lt;STRONG&gt;Development - Restricted Groups Policy&lt;/STRONG&gt;) that I use for enforcing group membership on a specific set of servers. As a follow-up to that post, I also want to cover an alternate method of managing group membership.&lt;/P&gt;
&lt;P&gt;In the previous scenario -- i.e. ensuring that Development team leads always have administrative access to servers in their Development Integration Environment (DEV) -- we actually wanted to restrict the members of the local &lt;STRONG&gt;Administrators&lt;/STRONG&gt; group on all servers in DEV. However, what if we need to address a slightly different scenario in which we want a specific user or group to always be a member of the local &lt;STRONG&gt;Administrators &lt;/STRONG&gt;group -- in addition to other group members (that vary by server)?&lt;/P&gt;
&lt;P&gt;For example, consider the fact that I use &lt;A href="http://www.microsoft.com/systemcenter/operationsmanager/en/us/default.aspx" mce_href="http://www.microsoft.com/systemcenter/operationsmanager/en/us/default.aspx"&gt;Systems Center Operations Manager (SCOM)&lt;/A&gt; in order to monitor the various physical and virtual servers in the the &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx"&gt;"Jameson Datacenter"&lt;/A&gt; (a.k.a. my home lab). One of the things I learned while deploying SCOM is that it is, um, &lt;EM&gt;challenging&lt;/EM&gt; to deploy it in a least privilege configuration -- or at least for someone who primarily considers himself an AppDev (Application Development) flavor of Microsoft consultant.&lt;/P&gt;
&lt;P&gt;At a bare minimum, your SCOM service account needs to be a member of the &lt;STRONG&gt;Performance Monitor Users &lt;/STRONG&gt;group on each monitored server. Rather than forcing myself to configure this on all of my existing servers as well on new servers and VMs that I will undoubtedly add in the future, I decided to apply this change using Group Policy instead.&lt;/P&gt;
&lt;P&gt;However, in this scenario, I don't want to &lt;EM&gt;restrict &lt;/EM&gt;the members of the &lt;STRONG&gt;Performance Monitor Users &lt;/STRONG&gt;group on each monitored server. Rather I simply want to ensure that the SCOM service account is a member of this group &lt;EM&gt;in addition to any other members&lt;/EM&gt;.&lt;/P&gt;
&lt;P&gt;To address this scenario, I created a startup script called &lt;STRONG&gt;EnsureLocalGroupMembership.cmd &lt;/STRONG&gt;in the following folder:&lt;/P&gt;
&lt;P&gt;&lt;A href="file://corp.technologytoolbox.com/SysVol/corp.technologytoolbox.com/Policies/%7BGUID%7D/Machine/Scripts/Startup/OperationsManager" mce_href="file://corp.technologytoolbox.com/SysVol/corp.technologytoolbox.com/Policies/{GUID}/Machine/Scripts/Startup/OperationsManager"&gt;file://corp.technologytoolbox.com/SysVol/corp.technologytoolbox.com/Policies/{GUID}/Machine/Scripts/Startup/OperationsManager&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;The contents of the script are actually quite trival:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;net localgroup "Performance Monitor Users" TECHTOOLBOX\svc-mom-action /add&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;BLOCKQUOTE class=note&gt;
&lt;DIV class=noteTitle&gt;&lt;STRONG&gt;Note&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;DIV&gt;Prior to deploying SCOM 2007 in the "Jameson Datacenter" I used its predecessor -- Microsoft Operations Manager (MOM) -- and thus had already created a service account named &lt;STRONG&gt;svc-mom-action&lt;/STRONG&gt;.&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;To force this startup script to run on all monitored servers, I created a Group Policy object (named &lt;STRONG&gt;Default Operations Manager Policy&lt;/STRONG&gt;) and linked it to the corresponding OU.&lt;/P&gt;
&lt;P&gt;Here are the settings for the Group Policy:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Computer Configuration&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Policies&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Windows Settings&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Scripts (Startup/Shutdown)&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Startup&lt;/STRONG&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Name: OperationsManager\EnsureLocalGroupMembership.cmd&lt;/STRONG&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;By linking this Group Policy to the appropriate OU (i.e. &lt;STRONG&gt;IT/Resources/Servers&lt;/STRONG&gt;) the SCOM service account is ensured to be a member of the local &lt;STRONG&gt;Performance Monitor Users &lt;/STRONG&gt;group on each monitored server. Voilà!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9907648" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Simplify/default.aspx">Simplify</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Windows+Server/default.aspx">Windows Server</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Infrastructure/default.aspx">Infrastructure</category></item></channel></rss>