<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Colin Bowern</title>
    <description>Feed from ColinBowern.com</description>
    <link>http://www.colinbowern.com/Default.aspx</link>
    <docs>http://backend.userland.com/rss</docs>
    <geo:lat>43.3333</geo:lat><geo:long>-79.8833</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by/2.5/</creativeCommons:license><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/colinbowern" type="application/rss+xml" /><feedburner:emailServiceId>colinbowern</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fcolinbowern" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fcolinbowern" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fcolinbowern" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/colinbowern" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fcolinbowern" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fcolinbowern" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fcolinbowern" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fcolinbowern" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <title>Installing TFS 2010 on a 64-bit system</title>
      <description>&lt;p&gt;If you are one of the lucky ones with an MSDN subscription then &lt;a href="http://blogs.msdn.com/somasegar/archive/2009/05/18/visual-studio-2010-and-net-fx-4-beta-1-ships.aspx"&gt;as of today you can download the Visual Studio 2010 bits&lt;/a&gt; which includes Team Foundation Server 2010. As I blogged about yesterday &lt;a href="http://colinbowern.com/Post/09-05-18/Installing_TFS_2008_on_a_64-bit_system.aspx"&gt;the 64-bit install is both unsupported and quite involved&lt;/a&gt;.&amp;#160; On the other hand things are looking up for TFS 2010. The install process was much more straight forward with the exception of a connection and data warehouse issue at the end. I have recorded the process for anyone who is looking to build a demo machine to kick the tires with. Unlike the default installation process I have chosen to install SharePoint myself. It’s just one of those things that my experience tells me to make sure it’s working before loading other stuff on top of it. Have fun with the show:&lt;/p&gt; &lt;embed height="302" type="application/x-shockwave-flash" width="400" src="http://vimeo.com/moogaloop.swf?clip_id=4720454&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1" allowfullscreen="true" allowscriptaccess="always" /&gt;&lt;p&gt;&lt;/p&gt;&lt;/embed&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=uXetVB6k3Ts:dFJ8wiBy-60:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=uXetVB6k3Ts:dFJ8wiBy-60:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=uXetVB6k3Ts:dFJ8wiBy-60:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=uXetVB6k3Ts:dFJ8wiBy-60:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=uXetVB6k3Ts:dFJ8wiBy-60:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=uXetVB6k3Ts:dFJ8wiBy-60:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=uXetVB6k3Ts:dFJ8wiBy-60:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=uXetVB6k3Ts:dFJ8wiBy-60:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/colinbowern/~4/uXetVB6k3Ts" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/colinbowern/~3/uXetVB6k3Ts/Installing_TFS_2010_on_a_64-bit_system.aspx</link>
      <author>Colin Bowern</author>
      <comments>http://www.colinbowern.com/Post/09-05-18/Installing_TFS_2010_on_a_64-bit_system.aspx</comments>
      <guid isPermaLink="false">bc37a2ab-cf96-473b-868c-f055b5c7cfef</guid>
      <pubDate>Mon, 18 May 2009 22:55:33 GMT</pubDate>
    <feedburner:origLink>http://www.colinbowern.com/Post/09-05-18/Installing_TFS_2010_on_a_64-bit_system.aspx</feedburner:origLink></item>
    <item>
      <title>Installing TFS 2008 on a 64-bit system</title>
      <description>&lt;p&gt;If you like living on the wild side then this post is for you – it is out of the bounds as far as official support goes.  Having realized that the world is going x64 the TFS product group made a few regrettable choices with one of them being not supporting 64-bit on the application server tier. Even though they made the choice, &lt;a href="http://blogs.msdn.com/bharry/archive/2008/02/06/installing-tfs-2008-on-windows-2008.aspx#7643554"&gt;explained why&lt;/a&gt;, and &lt;a href="http://blogs.msdn.com/bharry/archive/2008/02/06/installing-tfs-2008-on-windows-2008.aspx#7816936"&gt;confessed their regrets&lt;/a&gt; the good news is that you still can install it with a few extra steps. Below you will find a video of the process:&lt;/p&gt; &lt;embed height="302" type="application/x-shockwave-flash" width="400" src="http://vimeo.com/moogaloop.swf?clip_id=4702725&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1" allowfullscreen="true" allowscriptaccess="always" /&gt; &lt;p&gt;Here are the notes from that video:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Install Windows Server 2008 R2 &lt;/li&gt; &lt;li&gt;Create a Software folder on the system drive and copy in the bits of the following to their own sub-folder:
    &lt;ul&gt; &lt;li&gt;SQL Server 2008 Standard Edition &lt;/li&gt; &lt;li&gt;SQL Server 2008 Service Pack 1 &lt;/li&gt; &lt;li&gt;Team Foundation Server 2008 Standard Edition &lt;/li&gt; &lt;li&gt;Team Foundation Server 2008 Service Pack 1 &lt;/li&gt; &lt;li&gt;Visual Studio 2008 Service Pack 1 &lt;/li&gt; &lt;li&gt;Windows SharePoint Services 3.0 with Service Pack 2 &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Add .NET Framework 3.5.1 to the server
    &lt;ul&gt; &lt;li&gt;Server Manager &amp;gt; Add Features &amp;gt; .NET Framework 3.5.1 Feature &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Create a Service Account for SQL Server
    &lt;ul&gt; &lt;li&gt;Net.exe User Service-SQL * /Add &lt;/li&gt; &lt;li&gt;WmiC.exe Path Win32_UserAccount Where Name='Service-SQL' Set PasswordExpires=False &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Install SQL Server 2008 Standard with &lt;a href="http://support.microsoft.com/default.aspx/kb/955392 "&gt;Service Pack 1 Slipstream&lt;/a&gt; &lt;ul&gt; &lt;li&gt;Command Prompt &amp;gt; C:\Software\SQLServer2008SP1-KB968369-x64-ENU.exe
        &lt;ul&gt; &lt;li&gt;Install the setup files then it will exit &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Command Prompt &amp;gt; C:\Software\SQLServer2008-Standard\Setup.exe /PCUSource=C:\Software\SQLServer2008-SP1
        &lt;ul&gt; &lt;li&gt;Select all features &lt;/li&gt; &lt;li&gt;Use the service-sql service account for all services &lt;/li&gt; &lt;li&gt;Set SQL Agent and Browser services to auto start &lt;/li&gt; &lt;li&gt;Set Mixed Mode Authentication &lt;/li&gt; &lt;li&gt;Add Administrators to SQL Server administrator &lt;/li&gt; &lt;li&gt;Add Administrators to SQL Server Analysis Services administrator &lt;/li&gt; &lt;li&gt;Use the native mode default configuration for SSRS &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Open Management Studio to verify that Service Pack 1 was installed &lt;/li&gt; &lt;li&gt;Ensure we can browse to &lt;a href="http://localhost/reports"&gt;http://localhost/reports&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Create a Service Account for SharePoint
    &lt;ul&gt; &lt;li&gt;Net.exe User Service-WSS * /ADD &lt;/li&gt; &lt;li&gt;WmiC.exe Path Win32_UserAccount Where Name='Service-WSS' Set PasswordExpires=False &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Install Windows SharePoint Services 3.0 with Service Pack 2
    &lt;ul&gt; &lt;li&gt;Command Prompt &amp;gt; C:\Software\SharePoint-3.0SP2-x64\Setup.exe
        &lt;ul&gt; &lt;li&gt;Advanced &amp;gt; Web Front End &lt;/li&gt; &lt;li&gt;Feedback tab &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Create central administration site at &lt;a href="http://localhost:8079"&gt;http://localhost:8079&lt;/a&gt; &lt;ul&gt; &lt;li&gt;Can't use 8080 - TFS wants it &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Add &lt;a href="http://colin-tfs"&gt;http://colin-tfs&lt;/a&gt; to the local intranet zone &lt;/li&gt; &lt;li&gt;Create a new web application
        &lt;ul&gt; &lt;li&gt;Use Default Web Site &lt;/li&gt; &lt;li&gt;Use Service-WSS Application Pool Identity &lt;/li&gt; &lt;li&gt;Restart IIS Automatically &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Create a new site collection
        &lt;ul&gt; &lt;li&gt;Title: Team Foundation Server &lt;/li&gt; &lt;li&gt;Site Admin: Administrator &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Ensure we can browse to &lt;a href="http://localhost"&gt;http://localhost&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Create a Service Account for TFS
    &lt;ul&gt; &lt;li&gt;Net.exe User Service-TFS * /ADD &lt;/li&gt; &lt;li&gt;WmiC.exe Path Win32_UserAccount Where Name='Service-TFS' Set PasswordExpires=False &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Install Team Foundation Server 2008 Standard with &lt;a href="http://www.woodwardweb.com/vsts/creating_a_tfs.html "&gt;Service Pack 1 Slipstream&lt;/a&gt; &lt;ul&gt; &lt;li&gt;Command Prompt &amp;gt; MSIExec.exe /A C:\Software\TFS2008-Standard\AT\VS_Setup.msi /P C:\Software\TFS2008-SP1\TFS90SP1-KB949786.msp TARGETDIR=C:\Software\TFS2008-Standard-SP1\AT &lt;/li&gt; &lt;li&gt;Modify baseline.dat to remove 64-bit blocking
        &lt;ul&gt; &lt;li&gt;[gencomp114] &amp;gt; BlockorWarn=0 &lt;/li&gt; &lt;li&gt;[gencomp114] &amp;gt; InstallOnAMD64=0 &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://support.microsoft.com/kb/969985"&gt;Modify hcpackage.xml to support SQL Server 2008 Service Pack 1&lt;/a&gt; &lt;ul&gt; &lt;li&gt;PropertyStrValue LIKE '10.%'" action="=" count="(0" /&amp;gt; &lt;/li&gt; &lt;li&gt;action="&amp;amp;lt;" version="10.2" /&amp;gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Copy SharePoint registry key to fool TfsConfigWss.exe
        &lt;ul&gt; &lt;li&gt;Reg.exe Copy "HKLM\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions" "HKLM\SOFTWARE\Wow6432Node\Microsoft\Shared Tools\Web Server Extensions" /S &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Command Prompt &amp;gt; C:\Software\TFS2008-Standard-SP1\Setup.exe
        &lt;ul&gt; &lt;li&gt;Use TFS Service Account (service-tfs) &lt;/li&gt; &lt;li&gt;Use existing SharePoint (&lt;a href="http://colin-tfs:8079"&gt;http://colin-tfs:8079&lt;/a&gt;) &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Change application pool to 32-bit applications
        &lt;ul&gt; &lt;li&gt;IIS Manager &amp;gt; Microsoft Team Foundation Server Application Pool &amp;gt; Advanced Settings &amp;gt; Enable 32-bit Applications &lt;/li&gt; &lt;li&gt;Server &amp;gt; Restart &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Modify first line of tfsredirect.aspx in C:\Software\TFS2008-Standard-SP1\AT\Program Files\Common Files
        &lt;ul&gt; &lt;li&gt;string c_rootReportServerKey = @"Software\Wow6432Node\Microsoft\VisualStudio\9.0\TeamFoundation\ReportServer\"; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;XCopy "C:\Software\TFS2008-Standard-SP1\AT\Program Files\Common Files\*.*" "C:\Program Files\Common Files" /S &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Install Team Explorer 2008 with Service Pack 1
    &lt;ul&gt; &lt;li&gt;Command Prompt &amp;gt; C:\Software\TFS2008-Standard\TFC\Setup.exe &lt;/li&gt; &lt;li&gt;Install Visual Studio 2008 Service Pack 1 which contains Team Explorer 2008 SP1 to &lt;a href="http://blogs.msdn.com/dstfs/archive/2008/10/23/my-experience-setting-up-tfs-windows-sever-sql-server-2008.aspx"&gt;take care of red X on Reports&lt;/a&gt; &lt;/li&gt; &lt;li&gt;Reboot &lt;/li&gt; &lt;li&gt;Visual Studio 2008 &amp;gt; Tools &amp;gt; Connect to Team Foundation Server &lt;/li&gt; &lt;li&gt;Add a new project &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Change the warehouse service identity to use service-tfs
    &lt;ul&gt; &lt;li&gt;Add service-sql to the TfsWarehouse SQL roles &lt;/li&gt; &lt;li&gt;Force warehouse rebuild - &lt;a href="http://localhost:8080/Warehouse/v1.0/warehousecontroller.asmx?op=Run"&gt;http://localhost:8080/Warehouse/v1.0/warehousecontroller.asmx?op=Run&lt;/a&gt; &lt;/li&gt; &lt;li&gt;Watch status - &lt;a href="http://localhost:8080/Warehouse/v1.0/warehousecontroller.asmx?op=GetWarehouseStatus"&gt;http://localhost:8080/Warehouse/v1.0/warehousecontroller.asmx?op=GetWarehouseStatus&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=8CJsp44b_pQ:chRN1s8meYM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=8CJsp44b_pQ:chRN1s8meYM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=8CJsp44b_pQ:chRN1s8meYM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=8CJsp44b_pQ:chRN1s8meYM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=8CJsp44b_pQ:chRN1s8meYM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=8CJsp44b_pQ:chRN1s8meYM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=8CJsp44b_pQ:chRN1s8meYM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=8CJsp44b_pQ:chRN1s8meYM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/colinbowern/~4/8CJsp44b_pQ" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/colinbowern/~3/8CJsp44b_pQ/Installing_TFS_2008_on_a_64-bit_system.aspx</link>
      <author>Colin Bowern</author>
      <comments>http://www.colinbowern.com/Post/09-05-18/Installing_TFS_2008_on_a_64-bit_system.aspx</comments>
      <guid isPermaLink="false">c642e083-7139-414a-b4ac-e60730b40fe8</guid>
      <pubDate>Mon, 18 May 2009 02:25:38 GMT</pubDate>
    <feedburner:origLink>http://www.colinbowern.com/Post/09-05-18/Installing_TFS_2008_on_a_64-bit_system.aspx</feedburner:origLink></item>
    <item>
      <title>Creating Control Modules for Sitefinity</title>
      <description>&lt;p&gt;As you develop your second web site and look to start sharing custom controls there is no doubt you will want to find a way to do so with ease. Sitefinity employs &lt;a href="http://www.sitefinity.com/help/developer-manual/adding-new-modules-overview.html"&gt;modules&lt;/a&gt; as their next step in the evolution of customization. While working to package up a few controls I put together a bare bones module to demonstrate how to use a module, explore the new SimpleControl class which has &lt;a href="http://blogs.sitefinity.com/DilyanRusev/DilyanPosts/09-04-23/The_Simple_Control_class.aspx"&gt;a brief mention in the documentation-by-blog&lt;/a&gt;, and an easy way to deploy the module.&lt;/p&gt; &lt;p&gt;When creating a module you derive from the &lt;a href="http://www.sitefinity.com/help/developer-manual/telerik.framework-telerik.webmodule.html"&gt;Telerik.WebModule class&lt;/a&gt;. Once you have done so there is very little you need to implement. For the sake of our sample class we will override &lt;a href="http://www.sitefinity.com/help/developer-manual/telerik.framework-telerik.webmodule-name.html"&gt;Name&lt;/a&gt;, &lt;a href="http://www.sitefinity.com/help/developer-manual/telerik.framework-telerik.webmodule-title.html"&gt;Title&lt;/a&gt;, &lt;a href="http://www.sitefinity.com/help/developer-manual/telerik.framework-telerik.webmodule-description.html"&gt;Description&lt;/a&gt;, and &lt;a href="http://www.sitefinity.com/help/developer-manual/telerik.framework-telerik.webmodule-controls.html"&gt;Controls&lt;/a&gt; properties:&lt;/p&gt; &lt;pre class="c#" name="code"&gt;public class HelloWorldModule : Telerik.WebModule
{
    #region Properties
    public override IList&lt;itoolboxitem&gt; Controls
    {
        get
        {
            return new List&lt;itoolboxitem&gt;(new ToolboxItem[] {
                new HelloWorldToolboxItem()
            });
        }
    }

    public override string Description
    {
        get
        {
            return &amp;quot;Control library demonstration&amp;quot;;
        }
    }

    public override string Name
    {
        get
        {
            return &amp;quot;Hello World Controls&amp;quot;;
        }
    }

    public override string Title
    {
        get
        {
            return &amp;quot;Hello World Controls&amp;quot;;
        }
    }
    #endregion
}&lt;/pre&gt; &lt;p&gt;The Controls property returns a list of class instances derived from the &lt;a href="http://www.sitefinity.com/help/developer-manual/telerik.framework-telerik.web.toolboxitem.html"&gt;Telerik.Web.ToolboxItem class&lt;/a&gt;.&amp;#160; This is used by Sitefinity to populate the page editor’s toolbox without having to explicitly define each control the web site’s web.config.&amp;#160; The Toolbox Item is not much more than a &lt;a href="http://www.sitefinity.com/help/developer-manual/telerik.framework-telerik.web.toolboxitem-displayname.html"&gt;DisplayName&lt;/a&gt; and &lt;a href="http://www.sitefinity.com/help/developer-manual/telerik.framework-telerik.web.toolboxitem-description.html"&gt;Description&lt;/a&gt; of the item for use in the page editor view:&lt;/p&gt; &lt;pre class="c#" name="code"&gt;public class HelloWorldToolboxItem : Telerik.Web.ToolboxItem
{
    #region Constructors
    public HelloWorldToolboxItem()
        : this(typeof(HelloWorld)) { }

    public HelloWorldToolboxItem(Type type)
        : base(typeof(HelloWorld))
    {
        base.DisplayName = &amp;quot;Hello World!&amp;quot;;
        base.Description = &amp;quot;Simple Control sample&amp;quot;;
    }
    #endregion
}&lt;/pre&gt; &lt;p&gt;The sample control is derived from &lt;a href="http://blogs.sitefinity.com/DilyanRusev/DilyanPosts/09-04-23/The_Simple_Control_class.aspx"&gt;SimpleControl&lt;/a&gt; which provides localization and embedded template support. We have included an embedded user control in the project which creates a label control and exposes that through our control interface:&lt;/p&gt; &lt;pre class="c#" name="code"&gt;[ToolboxItem(typeof(HelloWorldToolboxItem)),
 ToolboxData(&amp;quot;&amp;lt;{0}:HelloWorld runat=\&amp;quot;server\&amp;quot; /&amp;gt;&amp;quot;)]
public class HelloWorld : Telerik.Cms.Web.UI.SimpleControl
{
    #region Properties
    [Bindable(true), Category(&amp;quot;Text&amp;quot;), DefaultValue(&amp;quot;Hello world!&amp;quot;),
     Description(&amp;quot;Gets or sets the Label text.&amp;quot;),]
    public string LabelText { get; set; }

    public override string LayoutTemplateName
    {
        get
        {
            return &amp;quot;SampleControlLibrary.HelloWorld.ascx&amp;quot;;
        }
    }

    protected ITextControl Label1
    {
        get
        {
            return base.Container.GetControl&lt;itextcontrol&gt;(&amp;quot;Label1&amp;quot;, true);
        }
    }
    #endregion

    #region Constructor
    public HelloWorld()
    {
        LabelText = &amp;quot;Hello world!&amp;quot;;
    }
    #endregion

    #region Methods
    protected override void CreateChildControls()
    {
        base.CreateChildControls();
        Label1.Text = LabelText;
    }
    #endregion
}&lt;/pre&gt; &lt;p&gt;To make deployment easy I used the often forgotten &lt;a href="http://msdn.microsoft.com/library/system.configuration.install.installer.aspx"&gt;System.Configuration.Install.Installer class&lt;/a&gt; which is called by the installer utility, &lt;a href="http://msdn.microsoft.com/library/50614e95.aspx"&gt;InstallUtil.exe&lt;/a&gt;. The challenge with using this class is that there is very little guidance or examples of how to use it. I referred to an &lt;a href="http://www.installsite.org/pages/en/isnews/200108/index.htm"&gt;article on Windows Installer installation phases&lt;/a&gt;, which this class is loosely based upon, to guide my implementation. Below is a snippet of the Install method.&amp;#160; In addition I have implemented Commit, Rollback, and Uninstall.&lt;/p&gt; &lt;pre class="c#" name="code"&gt;...
public override void Install(IDictionary stateSaver)
{
    if (!File.Exists(WebConfigPath))
    {
        throw new FileNotFoundException(&amp;quot;Unable to locate web.config. Ensure that this assembly located in the web application's bin folder.&amp;quot;, WebConfigPath);
    }

    base.Context.LogMessage(string.Format(&amp;quot;Using web.config located at '{0}'&amp;quot;, WebConfigPath));

    string backupConfigFile = String.Format(&amp;quot;{0}.bak&amp;quot;, WebConfigPath);
    File.Copy(WebConfigPath, backupConfigFile, true);
    stateSaver.Add(WebConfigPath, backupConfigFile);

    XDocument configDoc = XDocument.Load(WebConfigPath);

    base.Context.LogMessage(string.Format(&amp;quot;Assembly contains {0} modules to register&amp;quot;, this.AssemblyWebModules.Count));
    if (this.AssemblyWebModules.Count &amp;gt; 0)
    {
        XElement modulesEntry = configDoc.XPathSelectElement(&amp;quot;.//telerik/framework/modules&amp;quot;);
        List&lt;xelement&gt; moduleList = modulesEntry.Descendants().ToList();

        foreach (Type module in this.AssemblyWebModules)
        {
            Regex moduleType = new Regex(string.Format(&amp;quot;^{0}, {{0,}}{1}$&amp;quot;, module.FullName, AssemblyName), RegexOptions.IgnoreCase);
            if (!moduleList.Exists(x =&amp;gt; moduleType.IsMatch(x.Attribute(&amp;quot;type&amp;quot;).Value)))
            {
                base.Context.LogMessage(string.Format(&amp;quot;Registering '{0}'&amp;quot;, module.Name));
                XElement addElement = new XElement(&amp;quot;add&amp;quot;);
                addElement.SetAttributeValue(&amp;quot;type&amp;quot;, string.Format(&amp;quot;{0}, {1}&amp;quot;, module.FullName, AssemblyName));
                modulesEntry.Add(addElement);
            }
        }

        configDoc.Save(WebConfigPath);
    }

    base.Install(stateSaver);
}
...&lt;/pre&gt; &lt;p&gt;That about wraps it up. &lt;a href="http://colinbowern.com/Libraries/Files/SampleControlLibrary.sflb.ashx"&gt;Download the project source code&lt;/a&gt; and use it to build your own control libraries.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=y8QHjxNNVS4:E-wy65MA4kY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=y8QHjxNNVS4:E-wy65MA4kY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=y8QHjxNNVS4:E-wy65MA4kY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=y8QHjxNNVS4:E-wy65MA4kY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=y8QHjxNNVS4:E-wy65MA4kY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=y8QHjxNNVS4:E-wy65MA4kY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=y8QHjxNNVS4:E-wy65MA4kY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=y8QHjxNNVS4:E-wy65MA4kY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/colinbowern/~4/y8QHjxNNVS4" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/colinbowern/~3/y8QHjxNNVS4/Creating_Control_Modules_for_Sitefinity.aspx</link>
      <author>Colin Bowern</author>
      <comments>http://www.colinbowern.com/Post/09-04-30/Creating_Control_Modules_for_Sitefinity.aspx</comments>
      <guid isPermaLink="false">b30a55e3-b84c-43c4-8f54-42d734b7ede1</guid>
      <pubDate>Thu, 30 Apr 2009 11:02:33 GMT</pubDate>
    <feedburner:origLink>http://www.colinbowern.com/Post/09-04-30/Creating_Control_Modules_for_Sitefinity.aspx</feedburner:origLink></item>
    <item>
      <title>What I Use</title>
      <description>&lt;p&gt;The computer part of my home digital eco-system is coming to a completion point quickly. The next steps are around home automation but I thought I would take a moment to take stock on where I am at now.&lt;/p&gt; &lt;p&gt;&lt;a href="http://colinbowern.com/Libraries/MetaBlogLib/WindowsLiveWriter-WhatIUse_143CB-HomeNetwork_2.sflb.ashx"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Home Network" border="0" alt="Home Network" src="http://colinbowern.com/Libraries/MetaBlogLib/WindowsLiveWriter-WhatIUse_143CB-HomeNetwork_thumb.sflb.ashx" width="640" height="402" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;I recently added a new server to get away from desktop virtualization. The new server, Metaverse, was built based on the thinking Jeff Atwood has put into &lt;a href="http://www.codinghorror.com/blog/archives/001107.html"&gt;a power bill friendly machine&lt;/a&gt;. The parts list I used is as follows:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://products.amd.com/en-us/DesktopCPUDetail.aspx?id=426"&gt;AMD Athlon 64 X2 4850e 2.5GHz Processor&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.gigabyte.com.tw/Products/Motherboard/Products_Overview.aspx?ProductID=2859"&gt;Gigabyte GA-MA78GPM-DS2H Motherboard&lt;/a&gt; &lt;/li&gt; &lt;li&gt;4x &lt;a href="http://www.patriotmemory.com/products/detailp.jsp?prodline=5&amp;amp;catid=17&amp;amp;prodgroupid=109&amp;amp;id=680&amp;amp;type=1"&gt;2GB Patriot Viper DDR2-800 Memory&lt;/a&gt; &lt;/li&gt; &lt;li&gt;2x &lt;a href="http://www.wdc.com/en/products/Products.asp?DriveID=338"&gt;Western Digital Caviar Green Power 500GB SATA2 7.2K RPM Hard Drives&lt;/a&gt; (RAID1) &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.wdc.com/en/products/products.asp?driveid=301"&gt;Western Digital Caviar Blue 500GB SATA2 7.2K RPM Hard Drive&lt;/a&gt; (JBOD) &lt;/li&gt; &lt;li&gt;LG GH22NS30 SATA DVD Writer &lt;/li&gt; &lt;li&gt;&lt;a href="http://silverstonetek.com/products/p_contents.php?pno=st50ef-plus-sc&amp;amp;area=usa"&gt;Silverstone Element ST50EF-SC 500W Power Supply&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.silverstonetek.com/products/p_contents.php?pno=SG01-F&amp;amp;area="&gt;Silverstone Sugo SG01-F Small Form Factor Case&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Metaverse runs &lt;a href="http://www.microsoft.com/servers/hyper-v-server/default.mspx"&gt;Hyper-V Server 2008 R2&lt;/a&gt; to host three servers. Freeside is a simple &lt;a href="http://technet.microsoft.com/library/cc731264.aspx"&gt;Remote Desktop Gateway&lt;/a&gt; to allow me to connect back to home without a lot of fuss. I wanted to use Windows Home Server for remote access, but the Remote Desktop Protocol (RDP) proxy port is blocked from places like the office. Remote Desktop Gateway uses the universal firewall bypass port, HTTPS (443/tcp), instead. I think it would be a good move for the Windows Home Server team to add RDP over HTTPS into the next release. Some folks have recommended using &lt;a href="http://www.mesh.com"&gt;Live Mesh&lt;/a&gt; which has a mutant remote desktop protocol over HTTPS but it hung on my first attempt and required me to be logged in on the server which does not feel like the right thing to do. Neuromancer is the actual &lt;a href="http://www.microsoft.com/windows/products/winfamily/windowshomeserver/default.mspx"&gt;Windows Home Server&lt;/a&gt; (WHS). Overall a pretty solid release I have to say. I eagerly await a release built onto &lt;a href="http://www.microsoft.com/windowsserver2008/en/us/r2.aspx"&gt;Windows Server 2008 R2&lt;/a&gt; to take advantage of performance improvements, but it is not urgent right now. This server functions mainly as a file server which is backed up using &lt;a href="http://www.jungledisk.com/"&gt;Jungle Disk&lt;/a&gt; to the &lt;a href="http://aws.amazon.com/s3/"&gt;Amazon S3&lt;/a&gt; service. Jungle Disk is doing well in the latest builds (running the regular client, not the older WHS client) and delivers data security at a dirt cheap price. In addition to regular files it also serves as a Subversion server running &lt;a href="http://www.visualsvn.com/server/"&gt;VisualSVN Server&lt;/a&gt; for all of my sandbox development projects. The third virtual machine is Wintermute which serves as a build server. Major bits on it include &lt;a href="http://www.jetbrains.com/teamcity/"&gt;JetBrains TeamCity&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/vsts2008/default.aspx"&gt;Visual Studio Team Suite&lt;/a&gt;, &lt;a href="http://www.microsoft.com/express/sql/default.aspx"&gt;SQL Server Express&lt;/a&gt;, &lt;a href="http://www.typemock.com/learn_about_typemock_isolator.html"&gt;TypeMock Isolator&lt;/a&gt;, &lt;a href="http://tortoisesvn.net/"&gt;TortoiseSVN&lt;/a&gt;, and &lt;a href="http://www.targetprocess.com/"&gt;TargetProcess&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Office is my main development desktop. It was the last to get upgraded to Windows 7. Beyond a few small bugs which I have sent feedback on it is pretty stable. It runs all of the development tools, along with things like &lt;a href="http://www.microsoft.com/expression/"&gt;Expression Suite&lt;/a&gt;, &lt;a href="http://www.newsgator.com/Individuals/FeedDemon/Default.aspx"&gt;FeedDemon&lt;/a&gt;, &lt;a href="http://office.microsoft.com/en-us/suites/FX101674121033.aspx"&gt;Office&lt;/a&gt;, and &lt;a href="http://www.zune.com"&gt;Zune&lt;/a&gt;. I built it last summer out of the following:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://processorfinder.intel.com/details.aspx?sSpec=SLAWR"&gt;Intel Quad Core Q9450 2.66GHz Processor&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.asus.com/products.aspx?modelmenu=1&amp;amp;model=2257&amp;amp;l1=3&amp;amp;l2=11&amp;amp;l3=709&amp;amp;l4=0"&gt;ASUS P5Q Deluxe Motherboard&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.arctic-cooling.com/cpu2.php?idx=79"&gt;Arctic Cooling Freezer 7 Pro Processor Cooler&lt;/a&gt; &lt;/li&gt; &lt;li&gt;4x &lt;a href="http://www.patriotmemory.com/products/detailp.jsp?prodline=5&amp;amp;catid=2&amp;amp;prodgroupid=38&amp;amp;id=593&amp;amp;type=1"&gt;2GB Patriot Extreme Performance DDR2-800 Memory&lt;/a&gt; &lt;/li&gt; &lt;li&gt;2x &lt;a href="http://www.wdc.com/en/products/products.asp?DriveID=459"&gt;Western Digital Velociraptor 300GB SATA2 10K RPM Hard Drives&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.diamondmm.com/4850PE3512.php"&gt;Diamond Radeon HD 4850 512MB DDR3 PCI-E Video Card&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.arctic-cooling.com/vga2.php?idx=147"&gt;Arctic Cooling Accelero S1 Rev 2 Passive VGA Cooler&lt;/a&gt; &lt;/li&gt; &lt;li&gt;LG GH20NS15 SATA DVD Writer &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.corsair.com/products/hx/default.aspx"&gt;Corsair CMPSU-620HX 620W Modular Power Supply&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.antec.com/usa/productDetails.php?lan=us&amp;amp;id=15300"&gt;Antec 300 Mini Tower Case&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.razerzone.com/p-87-razer-lycosa-gaming-keyboard.aspx"&gt;Razer Lycosa Keyboard&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.logitech.com/index.cfm/mice_pointers/mice/devices/191&amp;amp;cl=US,EN"&gt;Logitech MX400 Laser Mouse&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Laptop is a &lt;a href="http://www.dell.com/content/products/productdetails.aspx/inspn_e1705"&gt;Dell Inspiron E1705&lt;/a&gt; that I picked up off eBay for a good deal. I have since hacked it to add an &lt;a href="http://processorfinder.intel.com/details.aspx?sSpec=SL9SK"&gt;Intel Core 2 Duo T7400 processer&lt;/a&gt;, &lt;a href="http://ati.amd.com/products/MobilityRadeonx1400/index.html"&gt;ATI Radeon Mobility X1400&lt;/a&gt;, and &lt;font color="#ff0000"&gt;7200RPM Hard Drive&lt;/font&gt;. It contains the basic productivity bits along with music recording bits for my &lt;a href="http://line6.com/podxt"&gt;Line 6 PODxt&lt;/a&gt;. If I had to buy a laptop again, though, I would get something smaller and lighter.&lt;/p&gt; &lt;p&gt;MediaCenter is connected into the television and stereo for watching movies, listening to the music collection, and viewing photos. I have tried to keep it relatively clean by adding minimal pieces like the &lt;a href="http://www.codecguide.com/"&gt;K-Lite Codec Pack&lt;/a&gt; and &lt;a href="http://www.videolan.org/vlc/"&gt;VLC Media Player&lt;/a&gt;. I am disappointed with our local television providers in that they continue to use locked down set-top boxes. There is a great potential being wasted here and I do not want to play with hacky infra-red blasters to make it work. This summer I am contemplating plugging in an over-the-air (OTA) connection to pickup all of the local stations for free. But that will have to wait until the snow has melted before I get on the roof to do any sort of antenna mounting. The nice thing about this machine is that it is over five years old now and still able to keep up nicely (minus the VGA Cooler’s fan not working):&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://www.intel.com/products/processor/pentium4/index.htm"&gt;Intel Pentium 4 2.8GHz with Hyper Threading Processor&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.scythe-usa.com/product/cpu/032/scmnj1000_detail.html"&gt;Scythe Ninja Mini Processor Cooler&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.asus.com/products.aspx?l1=3&amp;amp;l2=12&amp;amp;l3=31&amp;amp;l4=0&amp;amp;model=177&amp;amp;modelmenu=1"&gt;ASUS P4P800 Deluxe Motherboard&lt;/a&gt; &lt;/li&gt; &lt;li&gt;4x 512MB Kingmax DDR 400 Memory &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.seagate.com/support/disc/specs/sata/st3120026as.html"&gt;Seagate Baracudda 120GB SATA 7.2K RPM Hard Drive&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://ati.amd.com/products/radeon9800/radeon9800pro/index.html"&gt;ATI Radeon 9800 Pro AGP Video Card&lt;/a&gt; &lt;/li&gt; &lt;li&gt;Thermaltake Giant II Heat Pipe VGA Cooler &lt;/li&gt; &lt;li&gt;&lt;font color="#ff0000"&gt;LG IDE DVD-ROM&lt;/font&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.antec.com/usa/productDetails.php?lan=us&amp;amp;id=27430"&gt;Antec EarthWatts 430W PSU&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a href="http://www.nmediapc.com/htpc600.htm"&gt;nMedia HTPC 600 Case&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;font color="#ff0000"&gt;RF Wireless Keyboard&lt;/font&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Everything is connected together using a &lt;a href="http://www.dlink.com/products/?pid=494"&gt;D-Link DGS-2205 Gigabit Ethernet switch&lt;/a&gt;. The internet connection is courtesy of &lt;a href="http://www.cogeco.ca/en/residential_shop_for_hsi_o.html"&gt;Cogeco Cable&lt;/a&gt; via a &lt;a href="http://www.linksysbycisco.com/US/en/products/WRT54GL"&gt;Linksys WRT54GL&lt;/a&gt; router. I have flashed the router with &lt;a href="http://www.polarcloud.com/tomato"&gt;Tomato firmware&lt;/a&gt; to get better control over the quality of service features for voice. We use voice-over-IP (VoIP) for our primary phone line which runs through a &lt;a href="http://www.amazon.com/Linksys-SPA2102-Phone-Adapter-Router/dp/B000FKP55K"&gt;Linksys SPA 2102&lt;/a&gt; phone adapter to the &lt;a href="http://www.primustel.ca/en/residential/talkbroadband/talkBroadband.htm"&gt;Primus Talk Broadband service&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;One last thing you cannot forget – the &lt;a href="http://www.nintendo.com/wii"&gt;Nintendo Wii&lt;/a&gt;. Mainly used to keep my bowling and tennis skills in shape along with entertaining friends and family when they come over.&lt;/p&gt; &lt;p&gt;The thing I find though with all this is that it’s up-to-date today, but tomorrow it’ll be old hat. There are already six-core processors on the horizon and memory gets cheaper by the week. Hopefully this holds for another couple of years, or until we all have a slice of computing time in the cloud.&lt;/p&gt; &lt;p&gt;Next steps are to start digging into home automation.&amp;#160; I would love to be able to control the temperature in the house on a more dynamic schedule and monitor the variable utilities like power, water, and natural gas. There are a few &lt;a href="http://www.kondra.com/circuit/circuit.html"&gt;prospects on the power monitoring front&lt;/a&gt;, and &lt;a href="http://www.smarthome.com"&gt;a store with all kinds of toys&lt;/a&gt; to experiment with.&amp;#160; I have a feeling, however, that it will be a lot of slow experimentation on that front given that my expertise lies mainly in the computing side.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=EgiLFCNtUHY:7gqZB472oyk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=EgiLFCNtUHY:7gqZB472oyk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=EgiLFCNtUHY:7gqZB472oyk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=EgiLFCNtUHY:7gqZB472oyk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=EgiLFCNtUHY:7gqZB472oyk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=EgiLFCNtUHY:7gqZB472oyk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=EgiLFCNtUHY:7gqZB472oyk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=EgiLFCNtUHY:7gqZB472oyk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/colinbowern/~4/EgiLFCNtUHY" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/colinbowern/~3/EgiLFCNtUHY/What_I_Use.aspx</link>
      <author>Colin Bowern</author>
      <comments>http://www.colinbowern.com/Post/09-03-25/What_I_Use.aspx</comments>
      <guid isPermaLink="false">f8a9eba8-4fb9-4a3b-a939-acce0f0be837</guid>
      <pubDate>Wed, 25 Mar 2009 00:29:06 GMT</pubDate>
    <feedburner:origLink>http://www.colinbowern.com/Post/09-03-25/What_I_Use.aspx</feedburner:origLink></item>
    <item>
      <title>Iterative Blog Design</title>
      <description>&lt;p&gt;With about 24 hours of work into it I decided to put up a drop of my new blog. I am switching over to &lt;a shape="rect" href="http://www.sitefinity.com" shape="rect"&gt;Telerik Sitefinity&lt;/a&gt; in an effort to really push the platform. There are a lot of changes happening as you might expect from a Telerik product.  With 3.6 out the door and &lt;a shape="rect" href="http://www.sitefinity.com/product/roadmap.aspx" shape="rect"&gt;a major 4.0 release coming soon&lt;/a&gt; the documentation and patterns are still evolving. I have more on to do for this site and there are some known issues, but for now enjoy and let me know if you see any quirks.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=s4lKpiAR05o:BmeNa90NxTM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=s4lKpiAR05o:BmeNa90NxTM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=s4lKpiAR05o:BmeNa90NxTM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=s4lKpiAR05o:BmeNa90NxTM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=s4lKpiAR05o:BmeNa90NxTM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=s4lKpiAR05o:BmeNa90NxTM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=s4lKpiAR05o:BmeNa90NxTM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=s4lKpiAR05o:BmeNa90NxTM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/colinbowern/~4/s4lKpiAR05o" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/colinbowern/~3/s4lKpiAR05o/Iterative_Blog_Design.aspx</link>
      <author>Colin Bowern</author>
      <comments>http://www.colinbowern.com/Post/09-03-18/Iterative_Blog_Design.aspx</comments>
      <guid isPermaLink="false">eb6beec9-bf2e-47cb-8d9c-95d24dcb3318</guid>
      <pubDate>Wed, 18 Mar 2009 12:09:42 GMT</pubDate>
    <feedburner:origLink>http://www.colinbowern.com/Post/09-03-18/Iterative_Blog_Design.aspx</feedburner:origLink></item>
    <item>
      <title>0x80300001 - What do you mean you don't know what it is</title>
      <description>&lt;p&gt;I get that stupid feeling when I see an error message like "There was an error - 0x80300001" that I am supposed to know what that means. Even with over 15 years of experience in the IT industry I still, however, have failed to develop some sort of mind reading skill to figure out these really obscure error messages. I remember walking around the Microsoft campus during my tenure there and seeing a poster that had a picture of a blue screen along with a caption that read something to the effect of "if your mom cannot figure this out what makes you think it is a good error message?". I think we need to all remember that sometimes and here's a great example of one of those that I recently hit while loading up Hyper-V Server 2008 R2 beta (also trying Windows 7 x64 beta):&lt;/p&gt; &lt;p&gt;Windows is unable to install to the selected location. Error: 0x80300001.&lt;/p&gt; &lt;p&gt;I scratched my head for a bit. This was a brand new system running a Gigabyte GA-MA78GPM-DS2H board with on-board RAID support. I configured the BIOS to use SATA ports as RAID, created the RAID array in the BIOS - this should just work, no? Apparently the message was a bit of a misdirection after doing some more poking around. I checked the setupact.log which resides on X:\Windows\Panther for clues. It had some red herring messages about not being able to find the install.wim file. I eventually figured it out, but I maintain that the error message gives me no indication that this was the next step:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Insert the install DVD &lt;/li&gt; &lt;li&gt;Boot into the setup process &lt;/li&gt; &lt;li&gt;Get to the point where you need to select a partition and click Load Driver &lt;/li&gt; &lt;li&gt;Insert driver DVD &lt;/li&gt; &lt;li&gt;Locate the storage driver, in my case the AMD AHCI Compatible RAID Controller &lt;/li&gt; &lt;li&gt;Notice the message "Windows cannot be installed on this disk. (Show details)" at the bottom &lt;/li&gt; &lt;li&gt;Insert the install DVD back into the drive &lt;/li&gt; &lt;li&gt;Expand the advanced drive options &lt;/li&gt; &lt;li&gt;Create a New partition consuming some amount of space, in my case all of it &lt;/li&gt; &lt;li&gt;Windows says it had to do some funky stuff, click OK &lt;/li&gt; &lt;li&gt;Notice that there is a 200MB system partition and a new primary partition &lt;/li&gt; &lt;li&gt;Select the new primary partition and click Next &lt;/li&gt; &lt;/ol&gt; &lt;p&gt;From there setup will continue, life will be good, and you can enjoy RAID (and probably AHCI) support on your system.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=dhPH_5z1Awg:RQrYfqHptxg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=dhPH_5z1Awg:RQrYfqHptxg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=dhPH_5z1Awg:RQrYfqHptxg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=dhPH_5z1Awg:RQrYfqHptxg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=dhPH_5z1Awg:RQrYfqHptxg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=dhPH_5z1Awg:RQrYfqHptxg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=dhPH_5z1Awg:RQrYfqHptxg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=dhPH_5z1Awg:RQrYfqHptxg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/colinbowern/~4/dhPH_5z1Awg" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/colinbowern/~3/dhPH_5z1Awg/0x80300001_-_What_do_you_mean_you_don_t_know_what_it_is.aspx</link>
      <author>Colin Bowern</author>
      <comments>http://www.colinbowern.com/Post/09-01-17/0x80300001_-_What_do_you_mean_you_don_t_know_what_it_is.aspx</comments>
      <guid isPermaLink="false">fd8bf942-b98e-49c5-916a-f628c3f3c91e</guid>
      <pubDate>Sat, 17 Jan 2009 21:41:00 GMT</pubDate>
    <feedburner:origLink>http://www.colinbowern.com/Post/09-01-17/0x80300001_-_What_do_you_mean_you_don_t_know_what_it_is.aspx</feedburner:origLink></item>
    <item>
      <title>Diagnosing the Unknown Alias problem in SharePoint</title>
      <description>&lt;p&gt;My frustraition with a product that is, in theory, action packed, but faultering in execution continues - this time it is incoming email. A well behaved mail gateway should return a non-delivery receipt if it is unable to deliver email, it's common courtesy. SharePoint, both Windows SharePoint Services and Office SharePoint Service, seems to take exception to this idea. As an IT guy it is the most frustraiting thing to see a module that was slapped together with little regard to proper protocol behaviour. My frustration started when email enabled lists just stopped capturing email randomly. I am not alone in this frustration either, there are clearly others yet not a peep from Microsoft:&lt;/p&gt; &lt;ul class="list"&gt; &lt;li&gt;&lt;a shape="rect" href="http://www.toddklindt.com/blog/Lists/Posts/Post.aspx?ID=31" shape="rect"&gt;Comments on Todd Klindt's article Incoming Email in SharePoint v3&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a shape="rect" href="http://www.sharepointu.com/forums/p/534/1300.aspx" shape="rect"&gt;Posting on SharePointU.com&lt;/a&gt; &lt;/li&gt; &lt;li&gt;Multiple postings in the SharePoint newsgroups &lt;a shape="rect" href="http://groups.google.com/group/microsoft.public.sharepoint.setup_and_administration/browse_thread/thread/ad438defcb407ce9/26a272d683796e62" shape="rect"&gt;1&lt;/a&gt;, &lt;a shape="rect" href="http://groups.google.com/group/microsoft.public.sharepoint.setup_and_administration/browse_thread/thread/6bc5368b45a3ad40/d5f6fefda3b74a9e" shape="rect"&gt;2&lt;/a&gt;, &lt;a shape="rect" href="http://groups.google.com/group/microsoft.public.sharepoint.setup_and_administration/browse_thread/thread/d613445752af1328/47f85b8bffe950c8" shape="rect"&gt;3&lt;/a&gt;, &lt;a shape="rect" href="http://groups.google.com/group/microsoft.public.sharepoint.setup_and_administration/browse_thread/thread/ad438defcb407ce9/26a272d683796e62" shape="rect"&gt;4&lt;/a&gt; &lt;/li&gt; &lt;li&gt;... and even a post on the &lt;a shape="rect" href="http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=2648312&amp;amp;SiteID=17" shape="rect"&gt;TechNet forums&lt;/a&gt; as well as &lt;a shape="rect" href="http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=2177402&amp;amp;SiteID=17" shape="rect"&gt;mine&lt;/a&gt;. &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The SPTimer service polls the SMTP drop folder on a regular basis to look for incoming messages. When the message is picked up it is read in and the alias appears to be cross referenced against an EmailEnabledLists table. I was tipped off to this by a &lt;a shape="rect" href="http://groups.google.com/group/microsoft.public.sharepoint.windowsservices/browse_thread/thread/f45f9f8879041241/cc45c61f5eec9215" shape="rect"&gt;post on the SharePoint newsgroup&lt;/a&gt;. If the logging verbosity is set and the alias is not found it will log an Unknown Alias error to both the event log and the trace logs:&lt;/p&gt; &lt;pre class="brush: plain"&gt;Type:		Warning
Date:		2/26/2008
Time:		8:42:30 AM
Event:		6873
Source:		Windows SharePoint Services 3
Category:	E-Mail
User:		N/A
Description:
An error occurred while processing the incoming e-mail file
D:\SMTP\Drop\54f3fb0601c8787d0000024f.eml. The error was: Unknown alias..
&lt;/pre&gt; &lt;p&gt;Along with the following event:&lt;/p&gt; &lt;pre class="brush: plain"&gt;Type:		Information
Date:		2/26/2008
Time:		8:42:30 AM
Event:		6871
Source:		Windows SharePoint Services 3
Category:	E-Mail
User:		N/A
Description:
The Incoming E-Mail service has completed a batch.  The elapsed time was 00:00:00.0156256.
The service processed 1 message(s) in total.


Errors occurred processing 1 message(s):

Message ID: &amp;lt;SERVERxiDd9D9DQVXwR100000a19@domain&amp;gt;

 The following aliases were unknown:
 mylist
&lt;/pre&gt; &lt;p&gt;After poking around in the database to see if I could find any hints as to why this functionality decided to stop all of a sudden. Running the following query on each content database gave me a dump of the email aliases that each list was configured against:&lt;/p&gt; &lt;pre name="code" class="sql"&gt;SELECT 	    tp_EmailAlias as EmailAlias,
            SiteId,
            tp_WebId AS WebId,
            tp_Id as ListId
FROM        AllLists
INNER JOIN  Webs ON AllLists.tp_WebId = Webs.Id
WHERE       tp_EmailAlias IS NOT NULL
&lt;/pre&gt; &lt;p&gt;Cross referencing the results with the EmailEnabledLists table I was able to find that there were some, no, a lot of missing rows. Something was deleting my email enabled lists. At this point I don't know what, but it smells like a bug. In the mean time I have created a script to re-populate the configuration database table based on the content databases.&lt;/p&gt; &lt;pre name="code" class="sql"&gt;SET NOCOUNT ON
IF OBJECT_ID('tempdb..#EmailEnabledLists') IS NOT NULL
BEGIN
   DROP TABLE #EmailEnabledLists
END

CREATE TABLE #EmailEnabledLists (
    Alias   NVARCHAR(128) NOT NULL,
    SiteId  UNIQUEIDENTIFIER NOT NULL,
    WebId   UNIQUEIDENTIFIER NOT NULL,
    ListId  UNIQUEIDENTIFIER NOT NULL)

-- TODO: Insert your SharePoint Content Database Names into the Set
DECLARE DatabaseCursor CURSOR FOR
    SELECT  [Name]
    FROM    master.[sys].databases
    WHERE   [State] = 0 AND -- State = Online
            [Name] IN ('SharePoint_ContentDatabase1', 'SharePoint_ContentDatabase2')
    ORDER BY [Name]
OPEN DatabaseCursor

DECLARE @DatabaseName VARCHAR(128)
FETCH NEXT FROM DatabaseCursor INTO @DatabaseName
WHILE @@FETCH_STATUS = 0
BEGIN

    DECLARE @Command NVARCHAR(4000)
    SET @Command =
        N'USE [' + @DatabaseName + '];' + 
        N'INSERT INTO #EmailEnabledLists (Alias, SiteId, WebId, ListId) ' +
        N'SELECT  ' +
        N'    tp_EmailAlias as Alias, ' +
        N'    SiteId, ' +
        N'    tp_WebId AS WebId, ' +
        N'    tp_Id as ListId ' +
        N'FROM ' +
        N'    AllLists ' +
        N'    INNER JOIN  ' +
        N'        Webs ' +
        N'    ON      AllLists.tp_WebId = Webs.Id ' +
        N'    WHERE   tp_EmailAlias IS NOT NULL'
    EXEC sp_executesql @Command
    
    FETCH NEXT FROM DatabaseCursor INTO @DatabaseName
END
CLOSE DatabaseCursor
DEALLOCATE DatabaseCursor

-- TODO: Insert your SharePoint Configuration Database Name
USE [SharePoint_Config]

DECLARE AliasCursor CURSOR FOR
    SELECT  [Alias]
    FROM    #EmailEnabledLists
    ORDER BY [Alias]
OPEN AliasCursor

DECLARE @AliasName NVARCHAR(128)
FETCH NEXT FROM AliasCursor INTO @AliasName
WHILE @@FETCH_STATUS = 0
BEGIN
    IF(NOT EXISTS (SELECT Alias FROM dbo.EmailEnabledLists WHERE Alias = @AliasName))
    BEGIN
        DECLARE @SiteId UNIQUEIDENTIFIER
        DECLARE @WebId UNIQUEIDENTIFIER
        DECLARE @ListId UNIQUEIDENTIFIER

        SELECT  @SiteId = SiteId,
                @WebId = WebId,
                @ListId = ListId
        FROM    #EmailEnabledLists

        PRINT 'Inserting ' + @AliasName
        INSERT  dbo.EmailEnabledLists
                (Alias, SiteId, WebId, ListId, [Deleted])
        VALUES  (@AliasName, @SiteId, @WebId, @ListId, 'FALSE')
    END

    FETCH NEXT FROM AliasCursor INTO @AliasName
END
CLOSE AliasCursor
DEALLOCATE AliasCursor

IF OBJECT_ID('tempdb..#EmailEnabledLists') IS NOT NULL
BEGIN
   DROP TABLE #EmailEnabledLists
END
&lt;/pre&gt; &lt;p&gt;Now the million dollar question - what is the root cause? If I had time I would setup a trigger on the EmailEnabledLists table to notify me when something is deleted to get an idea of time frame and then use SQL Profiler to watch that process to see what the calls looks like and where they are coming from. Better yet, maybe some folks from the SharePoint team can chime in and share some more to help us understand the quirks of a product struggling for stability in the face of mass adoption.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt; (24-Mar-08): Linked to my TechNet forums post as well, but no further progress. Looking into the Microsoft.SharePoint.Administration.SPEmailEngine class with Reflector I cannot see any code to generate NDRs either.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=yi7le9yL4u0:ZzybJeWfqFI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=yi7le9yL4u0:ZzybJeWfqFI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=yi7le9yL4u0:ZzybJeWfqFI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=yi7le9yL4u0:ZzybJeWfqFI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=yi7le9yL4u0:ZzybJeWfqFI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=yi7le9yL4u0:ZzybJeWfqFI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=yi7le9yL4u0:ZzybJeWfqFI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=yi7le9yL4u0:ZzybJeWfqFI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/colinbowern/~4/yi7le9yL4u0" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/colinbowern/~3/yi7le9yL4u0/Diagnosing_the_Unknown_Alias_problem_in_SharePoint.aspx</link>
      <author>Colin Bowern</author>
      <comments>http://www.colinbowern.com/Post/08-02-26/Diagnosing_the_Unknown_Alias_problem_in_SharePoint.aspx</comments>
      <guid isPermaLink="false">51e6767c-4b60-4e37-b885-041f89b3ca42</guid>
      <pubDate>Tue, 26 Feb 2008 10:49:00 GMT</pubDate>
    <feedburner:origLink>http://www.colinbowern.com/Post/08-02-26/Diagnosing_the_Unknown_Alias_problem_in_SharePoint.aspx</feedburner:origLink></item>
    <item>
      <title>Importing Multiple Certificates</title>
      <description>&lt;p&gt;Through a recent migration we needed to move a large number of SSL certificates. After spending a lot of time exporting through the GUI we really did not feel like importing them by hand too. CertUtil came in hand to help us&lt;/p&gt; &lt;br/&gt; &lt;code&gt;CertUtil.exe -importPFX domain.com-YYMMDD.pfx "NoExport,AT_KEYEXCHANGE" &amp;lt; keypassword.txt &lt;/code&gt; &lt;br/&gt; &lt;p&gt;The bonus is being able to pipe in the certificate password from a text file to save typing it for each time it is executed. As of Service Pack 1 on Windows Server 2003 you can &lt;a shape="rect" href="http://blogs.technet.com/pki/archive/2007/07/29/marking-private-keys-as-non-exportable-with-certutil-importpfx.aspx" shape="rect"&gt;mark the private key as non-exportable&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=9wVdySenoQ4:-x8Wq1CJhQM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=9wVdySenoQ4:-x8Wq1CJhQM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=9wVdySenoQ4:-x8Wq1CJhQM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=9wVdySenoQ4:-x8Wq1CJhQM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=9wVdySenoQ4:-x8Wq1CJhQM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=9wVdySenoQ4:-x8Wq1CJhQM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=9wVdySenoQ4:-x8Wq1CJhQM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=9wVdySenoQ4:-x8Wq1CJhQM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/colinbowern/~4/9wVdySenoQ4" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/colinbowern/~3/9wVdySenoQ4/Importing_Multiple_Certificates.aspx</link>
      <author>Colin Bowern</author>
      <comments>http://www.colinbowern.com/Post/08-02-09/Importing_Multiple_Certificates.aspx</comments>
      <guid isPermaLink="false">91c9d07f-2fb4-489e-b1b8-eaa6a5dc5f0b</guid>
      <pubDate>Sat, 09 Feb 2008 12:56:00 GMT</pubDate>
    <feedburner:origLink>http://www.colinbowern.com/Post/08-02-09/Importing_Multiple_Certificates.aspx</feedburner:origLink></item>
    <item>
      <title>Compressing IIS and Windows Media Server Logs with PowerShell</title>
      <description>&lt;p&gt;The &lt;a href="http://www.codeplex.com/PowerShellCX"&gt;PowerShell Community Extensions Project&lt;/a&gt; shipped a Write-GZip cmdlet which made me think that it's time to re-write the trusty CompressLogFiles.vbs file I've been using for a while.  After grappling with the square brackets in the WMS [Global] folder I think I finally have a viable solution.  Since many folks have IIS servers with logs rolling daily here's a great way to cut down on disk space (maybe I'll look at writing a module for IIS 7 next month to hook into the log rolling):&lt;/p&gt; &lt;pre name="code" class="c-sharp"&gt;#===========================================================================
# Compress all log files older than today within a directory structure.
#===========================================================================
# Syntax: Compress-LogFiles.ps1 {LogPath}
#===========================================================================
# Revision History:
#   1.0 - 31-Jan-08 - Initial creation.
#                   - Colin Bowern
#===========================================================================
# Stop the script in the event of an error
$ErrorActionPreference = "Stop";
trap [System.Exception]
{
    Write-Host $_.Exception.ToString();
    
    $EventLog = New-Object System.Diagnostics.EventLog
    $EventLog.Set_Log("Windows PowerShell")
    $EventLog.Set_Source("PowerShell")
    $EventLog.WriteEntry($_.Exception.ToString(), "Error")
}

# Load Dependencies
if (!(Test-Path Variable:__PscxProfileRanOnce))
{
    Write-Error "PowerShell Community Extensions is required for this script.";
}

# Parse Command Line Arguments
if($args.length -ne 1)
{
    Write-Host "NAME";
    Write-Host "    Compress-LogFiles.ps1";
    Write-Host "";
    Write-Host "SYNOPSIS";
    Write-Host "    Compress all log files older than today within a directory structure.";
    Write-Host "";
    Write-Host "SYNTAX";
    Write-Host "    Compress-LogFiles.ps1 {LogPath}";
    Write-Host "";
    Write-Host "EXAMPLE";
    Write-Host "    Compress-LogFiles.ps1 D:\LogFiles";
    Write-Host "";
    $ErrorActionPreference = "ContinueSilent";
    Write-Error "Invalid number of command line arguments." -Category SyntaxError;
    Break;
}

$LogPath = $args[0];

#===========================================================================
# For Each *.log File in $LogPath

$IISLogFileToday = [String]::Format("ex{0}.log", [DateTime]::Now.ToString("yyyyMMdd"));
$WMSLogFileToday = [String]::Format("wms_{0}.log", [DateTime]::Now.ToString("yyyyMMdd"));

[array]$LogFiles = Get-ChildItem -Path $LogPath -Recurse -Include "ex*.log",
	"wms*.log", "````[Global````]" -Exclude $IISLogFileToday, $WMSLogFileToday,
	"httperr*.log", "httperr"

if($LogFiles.Count -gt 0)
{
    $Index = 0;
    foreach ($LogFile in $LogFiles)
    {
        Write-Progress -Id 1 -activity "Compressing Files" -status $LogFile.FullName
			-percentComplete($Index / $LogFiles.Count * 100);
        if(Test-Path ("{0}.gz" -f ([Management.Automation.WildcardPattern]::Escape($LogFile.FullName))))
        {
			Write-Error "Destination file already exists." -Category ResourceExists;
		}
        Write-GZip ([Management.Automation.WildcardPattern]::Escape($LogFile.FullName)) -Level 9;
        if(Test-Path ("{0}.gz" -f ([Management.Automation.WildcardPattern]::Escape($LogFile.FullName))))
        {
            Remove-Item ([Management.Automation.WildcardPattern]::Escape($LogFile.FullName))
        }
        $Index += 1;
    }
}
else
{
	Write-Host "There were no log files found that required processing.";
}
#===========================================================================
&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=44-VUPfP-0g:FZC-f2mgMbE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=44-VUPfP-0g:FZC-f2mgMbE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=44-VUPfP-0g:FZC-f2mgMbE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=44-VUPfP-0g:FZC-f2mgMbE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=44-VUPfP-0g:FZC-f2mgMbE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=44-VUPfP-0g:FZC-f2mgMbE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=44-VUPfP-0g:FZC-f2mgMbE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=44-VUPfP-0g:FZC-f2mgMbE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/colinbowern/~4/44-VUPfP-0g" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/colinbowern/~3/44-VUPfP-0g/Compressing_IIS_and_Windows_Media_Server_Logs_with_PowerShell.aspx</link>
      <author>Colin Bowern</author>
      <comments>http://www.colinbowern.com/Post/08-01-31/Compressing_IIS_and_Windows_Media_Server_Logs_with_PowerShell.aspx</comments>
      <guid isPermaLink="false">a73c63bd-f1ae-41f9-9b5c-f9a170b9a5bb</guid>
      <pubDate>Thu, 31 Jan 2008 14:04:00 GMT</pubDate>
    <feedburner:origLink>http://www.colinbowern.com/Post/08-01-31/Compressing_IIS_and_Windows_Media_Server_Logs_with_PowerShell.aspx</feedburner:origLink></item>
    <item>
      <title>Troubleshooting RPC across Firewalls (or, what the developers forgot to explain)</title>
      <description>&lt;p&gt;Applications that want to talk to other servers will often use the Remote Procedure Call (RPC) infrastructure to communicate instead of inventing their own protocol.  From an IT perspective this is a pain because we like known protocols with defined ports.  From a development perspective this is nice because we don't want to write more code than we have to.  More modern applications are going to take advantage of technologies like &lt;a href="http://en.wikipedia.org/wiki/Windows_Communication_Foundation"&gt;Windows Communications Foundation (WCF)&lt;/a&gt; which enables administrators to configure how the applications will talk, including the transport protocol (e.g. TCP, HTTP, custom protocols), along with the transport-specific properties (e.g. ports). While we wait for the uptake on WCF we will likely be stuck with RPC-based applications for quite some time. With that being the case it is best to understand how RPC works and the implications brought forth by firewalls.&lt;/p&gt; &lt;p&gt;I've read very few good explanations for RPC that a typical systems administrator would understand (read: without the developer-speak), so here goes:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;The client application opens up a dynamic outbound port and makes a call to the server's RPC Endpoint Mapper.  There are several ways that you can talk to the endpoint mapper:
    &lt;ul&gt; &lt;li&gt;Local RPC - it just connects &lt;/li&gt; &lt;li&gt;Named Pipes - \pipe\epmapper &lt;/li&gt; &lt;li&gt;TCP - Port 135/tcp &lt;/li&gt; &lt;li&gt;UDP - Port 135/udp &lt;/li&gt; &lt;li&gt;HTTP - Port 593/tcp &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;The RPC Endpoint Mapper processes the request for access to the application.  It will handle authentication (&lt;a href="http://msdn2.microsoft.com/en-us/library/aa378646.aspx"&gt;the details about it are on MSDN&lt;/a&gt;), and a number of provisioning processes.  The server-side service will be launched using either its own custom container (e.g. WMI on Windows Vista and later uses %SYSTEMROOT%\SYSTEM32\WBEM\UnSecApp.exe, Windows Media Server uses %SYSTEMROOT%\SYSTEM32\Windows Media\Server\WMServer.exe), dllhost.exe (which really sucks &lt;a href="http://blogs.msdn.com/robgruen/archive/2004/08/18/216685.aspx"&gt;as noted by Rob Gruen&lt;/a&gt;), or svchost.exe. &lt;/li&gt; &lt;li&gt;With the service launched on the server side it will then tell the client that it needs to continue the conversation with the service on a specific port.  This port will be located in the 1024+ range on most Windows machines, however in Windows Vista and Windows Server 2008 this is &lt;a href="http://support.microsoft.com/kb/929851"&gt;now 49152 - 65535 by default&lt;/a&gt;. If you are stuck on older versions of Windows, here's some more ammo to get that upgrade going.  In the mean time I would recommend that you at least take a look at &lt;a href="http://support.microsoft.com/kb/154596"&gt;setting a specific RPC endpoint range&lt;/a&gt;. &lt;/li&gt; &lt;li&gt;The client will continue its conversation with the service it needed on the port returned by the endpoint mapper.  You can see all of this happening using NETSTAT -B: &lt;/li&gt; &lt;/ol&gt; &lt;pre class="plain"&gt;Proto  Local Address        Foreign Address      State
TCP    192.168.0.111:135    192.168.0.110:49228  ESTABLISHED
RpcSs
[Svchost.exe]
TCP    192.168.0.111:49153  192.168.0.110:49228  ESTABLISHED
[Dllhost.exe]&lt;/pre&gt; &lt;p&gt;The output shows you the client is communicating from port 49228 to 135/tcp, and subsequently established a connection to the service on port 49153 to a service which uses dllhost.exe as a container. Note that the SvcHost.exe exposes what service it is exposing through the port (more on that in a minute).&lt;/p&gt; &lt;p&gt;Most administrators and security professionals get anxious when a service is dynamically allocating random ports in a large range.  This really goes against the grain of well known ports that have specific purposes that they can lock down.  As a result of the uproar several services like &lt;a href="http://support.microsoft.com/kb/224196"&gt;NTDS&lt;/a&gt;, &lt;a href="http://support.microsoft.com/kb/224196"&gt;Netlogon&lt;/a&gt;, and &lt;a href="http://support.microsoft.com/kb/319553"&gt;FRS&lt;/a&gt; (don't forget the DFSRDiag StaticRPC port noted in &lt;a href="http://support.microsoft.com/kb/832017"&gt;KB823017&lt;/a&gt; under Distributed File Replication Service) have enabled you to specify static endpoints. This isn't something new, if the application uses Distributed COM (DCOM) then there is &lt;a href="http://support.microsoft.com/kb/217351"&gt;already an option to lock the application to a specific endpoint&lt;/a&gt;. Making these changes on an application that hasn't been tested with it though could bring unanticipated results, so consult your application vendor before going hog wild in the Component Services management console.&lt;/p&gt; &lt;p&gt;I would argue that even though ports can be locked down that unless your firewall does deep packet inspection (&lt;a href="http://www.microsoft.com/technet/isa/2006/application_filters.mspx"&gt;this is where your choice of ISA Server pays off&lt;/a&gt;, even though &lt;a href="http://blogs.technet.com/isablog/archive/2007/05/16/rpc-filter-and-enable-strict-rpc-compliance.aspx"&gt;it can be painful to configure&lt;/a&gt;)all I need to know is how to launch a service using that port to get around your firewall (port 80 comes to mind as a favourite port to launch a service under).  This deep packet inspection is exactly what Windows Firewall with Advanced Security offers in Windows Vista and Windows Server 2008. After &lt;a href="http://forums.iis.net/t/1147512.aspx"&gt;troubleshooting a problem with remotely administering IIS on Server Core recently&lt;/a&gt; I noticed that the out-of-the-box firewall has &lt;a href="http://technet2.microsoft.com/windowsserver2008/en/library/d37f96c6-c729-4b29-80a9-88db3d97b8631033.mspx"&gt;added a nifty RPC packet inspection layer&lt;/a&gt;.  Hopefully we will see IIS product group take up the use of SvcHost or a custom container soon.  In the mean time here is an example of a rule group that, when enabled, will allow you to remotely manage Task Scheduler:&lt;/p&gt; &lt;pre class="plain"&gt;Rule Name:      Remote Scheduled Tasks Management (RPC-EPMAP)
-------------------------------------------------------------------
Description:    Inbound rule for the RPCSS service to allow RPC/TCP
                traffic for the Task Scheduler service.
Enabled:        No
Direction:      In
Profiles:       Domain,Private,Public
Grouping:       Remote Scheduled Tasks Management
LocalIP:        Any
RemoteIP:       Any
Protocol:       TCP
LocalPort:      RPC-EPMap
RemotePort:     Any
Edge traversal: No
Program:        C:\Windows\system32\svchost.exe
Service:        RPCSS
InterfaceTypes: Any
Security:       NotRequired
Action:         Allow

Rule Name:      Remote Scheduled Tasks Management (RPC)
-------------------------------------------------------------------
Description:    Inbound rule for the Task Scheduler service to be
                remotely managed via RPC/TCP.
Enabled:        No
Direction:      In
Profiles:       Domain,Private,Public
Grouping:       Remote Scheduled Tasks Management
LocalIP:        Any
RemoteIP:       Any
Protocol:       TCP
LocalPort:      RPC
RemotePort:     Any
Edge traversal: No
Program:        C:\Windows\system32\svchost.exe
Service:        schedule
InterfaceTypes: Any
Security:       NotRequired
Action:         Allow&lt;/pre&gt; &lt;p&gt;In the above example you can see that the first call will come into SvcHost.exe which hosts the RPC EndPoint Mapper (noted as Service = RPCSS, LocalPort = RPC-EPMap). The subsequent calls will be to a dynamic RPC endpoint, defined in the second protocol, hosted by SvcHost.exe called Schedule. Now here's the bad part - it appears to only work for services hosted by SvcHost.exe. If the service uses DLLHost.exe then you are out of luck. If you have a custom container then you can just lock down to that already - no need to worry.&lt;/p&gt; &lt;strong&gt;UPDATE&lt;/strong&gt; &lt;p&gt;Earlier in the post I referred to an issue managing IIS on Server Core using the Microsoft.Web.Administration assembly. This was what got me started down the path and why I wrote this post. My conclusion was to add a firewall exception for dllhost.exe to allow remote procedure calls to connect with it. Simple enough you might think, but this does open up a whole host of potential security issues. Mike Volodarsky from the IIS product group has taken the problem away to the configuration team to come up with an official solution. In his post he mentioned that the AHAdmin component was the one we were communicating with. That got me thinking - how would I have figured that out on my own? That leads us to part two of this saga - how to determine which component DllHost is representing.&lt;/p&gt; &lt;p&gt;After running NETSTAT -B I was able to see my RPC endpoint mapped to DllHost.exe. Opening the firewall to that particular container leaves the a lot exposed to the world, so I really want to lock it down. Earlier in the post I mentioned that you &lt;a href="http://support.microsoft.com/kb/217351"&gt;can lock down DCOM objects&lt;/a&gt;, the trick is to know which one to lock down. Since COM has some restrictions like length of object names coupled with developer habits of choosing the most acronym loaded names it is not easy to figure out which component it is that you need to lock down. I set PowerShell on an infinite loop to make calls to my RPC endpoint to ensure it stayed alive during this investigation. NETSTAT -B gave me some clues to look for in the RPC endpoint port number. The next tool I pulled out was &lt;a href="http://technet.microsoft.com/en-ca/sysinternals/bb896653.aspx"&gt;Process Explorer&lt;/a&gt;. Thankfully it works on Server Core (I think I would be lost sometimes without this tool). Sorting the process list by name allowed me to locate instances of DllHost.exe quickly. Opening up the properties I clicked on the TCP/IP tab to confirm that it was indeed the instance I wanted based on the ports on which the process was bound. Clicking back to the Image tab the magic missing link in the Command Line text box:&lt;/p&gt; &lt;pre class="plain"&gt;DllHost.exe /Processid:{9FA5C497-F46D-447F-8011-05D03D7D7DDC}&lt;/pre&gt; &lt;p&gt;Using this piece of information I opened up the Registry Editor, went to HKEY_CLASSES_ROOT\AppID as indicated in the KB217351, and located the GUID from the command-line. This lead me to the AHAdmin object which appears to be the object being remotely instantiated (now Mike had given this away in his post, but the story sounds much more dramatic if you put that to the side for a second). I inserted the Endpoints value into the GUID key as per the KB article, and restarted the server, and kicked off my PowerShell script calls once again. This time NETSTAT -B gave me a different result - it was now using my static RPC endpoint! With that now in place I updated my new firewall rules and made some security folks very happy:&lt;/p&gt; &lt;pre class="plain"&gt;NetSh AdvFirewall Firewall Add Rule Name="Remote Web Server Management (RPC)" Dir=In Action=Allow Program="C:\WINDOWS\SYSTEM32\dllhost.exe" Protocol=TCP LocalPort=49494 
NetSh AdvFirewall Firewall Add Rule Name="Remote Web Server Management (RPC-EPMap)" Dir=In Action=Allow Program="C:\WINDOWS\SYSTEM32\SvcHost.exe" Service=RPCSS Protocol=TCP LocalPort=RPC-EPMap &lt;/pre&gt; &lt;p&gt;Now I'm left waiting to see if I messed anything up. Setting a static endpoint could have dire consequences depending on how the application is written. Since AHAdmin is a black box I'll wait for the product group to provide some more official guidance on securing the service. In the meantime the new knowledge around tracing RPC calls form client to server to object is a handy one that has helped me confirm the problem and identify a potential solution.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=CX94ibz0fsY:m5tbdW-KE3w:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=CX94ibz0fsY:m5tbdW-KE3w:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=CX94ibz0fsY:m5tbdW-KE3w:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=CX94ibz0fsY:m5tbdW-KE3w:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=CX94ibz0fsY:m5tbdW-KE3w:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=CX94ibz0fsY:m5tbdW-KE3w:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=CX94ibz0fsY:m5tbdW-KE3w:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=CX94ibz0fsY:m5tbdW-KE3w:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/colinbowern/~4/CX94ibz0fsY" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/colinbowern/~3/CX94ibz0fsY/Troubleshooting_RPC_across_Firewalls_or_what_the_developers_forgot_to_explain.aspx</link>
      <author>Colin Bowern</author>
      <comments>http://www.colinbowern.com/Post/08-01-27/Troubleshooting_RPC_across_Firewalls_or_what_the_developers_forgot_to_explain.aspx</comments>
      <guid isPermaLink="false">9a01e9ca-4c75-4c1d-996d-cb5c17144397</guid>
      <pubDate>Sun, 27 Jan 2008 14:13:00 GMT</pubDate>
    <feedburner:origLink>http://www.colinbowern.com/Post/08-01-27/Troubleshooting_RPC_across_Firewalls_or_what_the_developers_forgot_to_explain.aspx</feedburner:origLink></item>
    <item>
      <title>Locking Down DFS for Windows Firewall</title>
      <description>&lt;p&gt;Most system administrators are becoming acutely aware of port usage on their servers. The security focus is telling us we need to lock things down by default. Turning Windows Firewall on for your servers will certainly do that. For DFS there is some scattered documented things I wanted to share about locking it down.&lt;/p&gt; &lt;p&gt;Distributed File System (DFS) uses File Replication Services (FRS) which in turn uses Remote Procedure Calls (RPC). RPC uses 135/tcp as the contact point for services to say hello on, known as the Endpoint Mapper. From there RPC directs you to a dynamic port known as an RPC Endpoint. For those of us who hate the idea you can &lt;a href="http://support.microsoft.com/kb/908472"&gt;constrain RPC to a range&lt;/a&gt; using RPCCfg.exe. It still means ports are dynamic, but now they are constrained. It would be nice to do better than a dynamic port in a range. That is where a &lt;a href="http://support.microsoft.com/kb/319553"&gt;registry key&lt;/a&gt; and DFSRDiag comes in with the StaticRPC option. Buried in the &lt;a href="http://support.microsoft.com/kb/832017"&gt;KB832017&lt;/a&gt; is a reference to the fact that you can set DFS replication to use a static RPC endpoint. After adding the registry key and running that tool you should be able to see some tangible results using RPCDump:&lt;/p&gt; &lt;pre class="plain"&gt;10.0.0.1[4998] [d049b186-814f-11d1-9a3c-00c04fc9b232] NtFrs API :NOT_PINGED

10.0.0.1[4998] [f5cc59b4-4264-101a-8c59-08002b2f8426] NtFrs Service :NOT_PINGED

10.0.0.1[4999] [897e2e5f-93f3-4376-9c9c-fd2277495c27] Frs2 Service :NOT_PINGED&lt;/pre&gt; &lt;p&gt;(The IP addresses and port numbers have been changed to protect the innocent) From here on in all you need to do is open those ports on your firewall and DFS should start flowing.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=1_Ii4h88l60:kS5LHEx9Vu4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=1_Ii4h88l60:kS5LHEx9Vu4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=1_Ii4h88l60:kS5LHEx9Vu4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=1_Ii4h88l60:kS5LHEx9Vu4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=1_Ii4h88l60:kS5LHEx9Vu4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=1_Ii4h88l60:kS5LHEx9Vu4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=1_Ii4h88l60:kS5LHEx9Vu4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=1_Ii4h88l60:kS5LHEx9Vu4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/colinbowern/~4/1_Ii4h88l60" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/colinbowern/~3/1_Ii4h88l60/Locking_Down_DFS_for_Windows_Firewall.aspx</link>
      <author>Colin Bowern</author>
      <comments>http://www.colinbowern.com/Post/08-01-25/Locking_Down_DFS_for_Windows_Firewall.aspx</comments>
      <guid isPermaLink="false">5f0be6a5-ab70-42e4-bbd3-56b46a5369b3</guid>
      <pubDate>Fri, 25 Jan 2008 00:54:00 GMT</pubDate>
    <feedburner:origLink>http://www.colinbowern.com/Post/08-01-25/Locking_Down_DFS_for_Windows_Firewall.aspx</feedburner:origLink></item>
    <item>
      <title>Retrieving the Current User's Active Directory Object</title>
      <description>&lt;p&gt;If you are writing a program that leverages Active Directory then there may be times where you want to retrieve the current user's AD object. It can be handy for situations where you need the user's email address, account information, or some other piece of data stored in the directory. Below is a code snippet to retrieve the current user object as well as translate an NT domain name into a distinguished name all through managed code (as opposed to DsCrackNames which uses RPC and interop).&lt;/p&gt; &lt;pre name="code" class="c-sharp"&gt;public static DirectoryEntry CurrentUser
{
    get
    {
        string[] currentUserName = WindowsIdentity.GetCurrent().Name.Split('\\');
        string domainDistinguishedName = GetDistinguishedName(currentUserName[0]);

        DirectoryEntry domain = new DirectoryEntry("LDAP://" + domainDistinguishedName);
        DirectorySearcher searcher = new DirectorySearcher(domain,
            String.Format("(sAMAccountName={0})", currentUserName[1]));

        SearchResult result = searcher.FindOne();
        DirectoryEntry currentUser = null;
        if (result != null)
        {
            currentUser = result.GetDirectoryEntry();
        }

        return currentUser;
    }
}

public static string GetDistinguishedName(string netbiosName)
{
    if (string.IsNullOrEmpty(netbiosName))
    {
        throw new ArgumentNullException("netbiosName");
    }
    if (!Regex.IsMatch(netbiosName, @"^[-\w]{1,15}$"))
    {
        throw new ArgumentException("Invalid NetBIOS domain name format. Domain name should be a maximum of 15 alphanumeric characters (including dashes).", "netbiosName");
    }

    DirectoryEntry globalCatalog = new DirectoryEntry("LDAP://RootDSE");
    string configurationPath = (string)globalCatalog.Properties["configurationNamingContext"].Value;

    DirectoryEntry partitions = new DirectoryEntry("LDAP://CN=Partitions," + configurationPath);

    DirectorySearcher searcher = new DirectorySearcher(partitions,
        String.Format("(&amp;amp;(objectClass=crossRef)(nETBIOSName={0}))", netbiosName),
        new string[] { "nCName" },
        SearchScope.OneLevel);
    SearchResult result = searcher.FindOne();

    string distinguishedName = null;
    if (result != null)
    {
        distinguishedName = result.Properties["nCName"][0] as string;
    }
    return distinguishedName;
}
&lt;/pre&gt; &lt;p&gt;From there you can easily retrieve the user's email address:&lt;/p&gt; &lt;pre name="code" class="c-sharp"&gt;Console.WriteLine(CurrentUser.Properties["mail"].Value as string);
&lt;/pre&gt; &lt;p&gt;Enjoy!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=pwCTL8QdOs0:7XWa7GkZbAU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=pwCTL8QdOs0:7XWa7GkZbAU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=pwCTL8QdOs0:7XWa7GkZbAU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=pwCTL8QdOs0:7XWa7GkZbAU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=pwCTL8QdOs0:7XWa7GkZbAU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=pwCTL8QdOs0:7XWa7GkZbAU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=pwCTL8QdOs0:7XWa7GkZbAU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=pwCTL8QdOs0:7XWa7GkZbAU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/colinbowern/~4/pwCTL8QdOs0" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/colinbowern/~3/pwCTL8QdOs0/Retrieving_the_Current_User_s_Active_Directory_Object.aspx</link>
      <author>Colin Bowern</author>
      <comments>http://www.colinbowern.com/Post/07-11-09/Retrieving_the_Current_User_s_Active_Directory_Object.aspx</comments>
      <guid isPermaLink="false">813981c2-4d04-49f7-96e9-63a2a1de8076</guid>
      <pubDate>Fri, 09 Nov 2007 17:32:00 GMT</pubDate>
    <feedburner:origLink>http://www.colinbowern.com/Post/07-11-09/Retrieving_the_Current_User_s_Active_Directory_Object.aspx</feedburner:origLink></item>
    <item>
      <title>Create Document Libraries and Folders in SharePoint using PowerShell</title>
      <description>&lt;p&gt;If you have not used &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx" rel="external" target="_blank"&gt;PowerShell&lt;/a&gt; let me show you a nifty little script that saved hours of repetitive clicking through usability challenged tools (aka &lt;a href="http://office.microsoft.com/sharepointdesigner" rel="external" target="_blank"&gt;SharePoint Designer&lt;/a&gt;):&lt;/p&gt; &lt;pre name="code" class="c-sharp"&gt;System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");
$site = new-object Microsoft.SharePoint.SPSite("http://myweb");
$siteweb = $site.OpenWeb();
$webs = $siteweb.Webs;
foreach($web in $webs)
{
    Write-Host $web.Title;
    $listtemplate = $web.ListTemplates["Document Library"];
    $listId = $web.Lists.Add("ShortName", "", $listtemplate);
    $list = $web.Lists.GetList($listId, $true);
    $list.Title = "Long Descriptive Title";
    $list.OnQuickLaunch = $True;
    $folder = $list.Folders.Add("", [Microsoft.SharePoint.SPFileSystemObjectType]::Folder, "SubFolder1");
    $folder.Update();
    $list.Update();
}
&lt;/pre&gt; &lt;p&gt;This script will cycle through all of the sub-webs in a SharePoint site, add a new document library, and sub-folder to that library.  While it does not sound like a difficult task, going through either the web-based interface or the SharePoint Designer interface is quite mundane. There are a bunch of unnecessary clicks that, thanks to a UI that has no consideration for repetitive or advanced usage, make the process painful at best.&lt;/p&gt; &lt;p&gt;It is a shame there is not more emphasis on managing SharePoint through PowerShell.  There is a lot of opportunity to build cmdlets that would have made the above all so much cleaner.  The Exchange Server team managed to do this with success. Speaking as a user, developer, and IT Professional, I would rather have seen something like Excel Services ship as an out-of-band release in favour of having better migration, management tools, and complete documentation. For some more tips and tricks check out &lt;a href="http://blogs.flexnetconsult.co.uk/colinbyrne/CategoryView,category,PowerShell.aspx" rel="external" target="_blank"&gt;Colin Bryne's blog&lt;/a&gt; for a few other samples.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=z5QJN4_q_X4:wBcKNy0tbTM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=z5QJN4_q_X4:wBcKNy0tbTM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=z5QJN4_q_X4:wBcKNy0tbTM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=z5QJN4_q_X4:wBcKNy0tbTM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=z5QJN4_q_X4:wBcKNy0tbTM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=z5QJN4_q_X4:wBcKNy0tbTM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=z5QJN4_q_X4:wBcKNy0tbTM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=z5QJN4_q_X4:wBcKNy0tbTM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/colinbowern/~4/z5QJN4_q_X4" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/colinbowern/~3/z5QJN4_q_X4/Create_Document_Libraries_and_Folders_in_SharePoint_using_PowerShell.aspx</link>
      <author>Colin Bowern</author>
      <comments>http://www.colinbowern.com/Post/07-08-29/Create_Document_Libraries_and_Folders_in_SharePoint_using_PowerShell.aspx</comments>
      <guid isPermaLink="false">aee8d8a7-fb7a-4193-96f8-af5c2d9933ef</guid>
      <pubDate>Wed, 29 Aug 2007 18:02:00 GMT</pubDate>
    <feedburner:origLink>http://www.colinbowern.com/Post/07-08-29/Create_Document_Libraries_and_Folders_in_SharePoint_using_PowerShell.aspx</feedburner:origLink></item>
    <item>
      <title>BUG: Exchange Server 2007 rewrites Secondary Email Addresses when using POP3/IMAP</title>
      <description>&lt;p&gt;If you are using Exchange Server 2007 to receive mail addressed to multiple email addresses you might have noticed that when using POP3/IMAP that the address is not preserved.  If you are running Exchange Server 2003 and have an application that depends on secondary email addressing take note.  For example:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Mailbox primary SMTP address is colin(at)rockstarguys.com &lt;/li&gt; &lt;li&gt;Mailbox secondary email address is webmaster(at)rockstarguys.com&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If you send a message to webmaster(at)rockstarguys.com you will see one of two results:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Using a MAPI client the message will be addressed to webmaster(at)rockstarguys.com as it should &lt;/li&gt; &lt;li&gt;Using a POP3/IMAP client the message will be addressed to colin(at)rockstarguys.com with no sign of the original To address.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;To further validate this behaviour if you look at the message headers you will see that the same message has two different sets of headers:&lt;/p&gt; &lt;table&gt; &lt;tbody&gt; &lt;tr&gt; &lt;th&gt;&lt;strong&gt;Outlook&lt;/strong&gt;&lt;/th&gt; &lt;th&gt;&lt;strong&gt;POP3/IMAP&lt;/strong&gt;&lt;/th&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top"&gt;Received: from Pickup by mailserver.mydomain.net with Microsoft SMTP Server id 8.0.730.1; Tue, 21 Aug 2007 20:39:26 +0000&lt;br /&gt;
            Message-ID: &amp;lt;AC754B3E95C1445FBAB321EB67733EDF@mydomain.net&amp;gt;&lt;br /&gt;
            From: Colin Bowern &amp;lt;colinbowern(at)hotmail.com&amp;gt;&lt;br /&gt;
            To: &amp;lt;webmaster(at)rockstarguys.com&amp;gt;&lt;br /&gt;
            Subject: test&lt;br /&gt;
            Date: Fri, 3 Aug 2007 16:26:51 -0400&lt;br /&gt;
            MIME-Version: 1.0&lt;br /&gt;
            Content-Type: multipart/alternative; boundary="----=_NextPart_000_0005_01C7D5EB.18B22F30"&lt;br /&gt;
            X-Priority: 3&lt;br /&gt;
            X-MSMail-Priority: Normal&lt;br /&gt;
            X-Mailer: Microsoft Windows Mail 6.0.6000.16480&lt;br /&gt;
            X-MimeOLE: Produced By Microsoft MimeOLE V6.0.6000.16480&lt;br /&gt;
            Return-Path: colinbowern(at)rockstarguys.com&lt;/td&gt; &lt;td valign="top"&gt;Received: from Pickup by mailserver.mydomain.net with Microsoft SMTP Server id 8.0.730.1; Tue, 21 Aug 2007 20:39:26 +0000&lt;br /&gt;
            From: Colin Bowern &amp;lt;colinbowern@hotmail.com&amp;gt;&lt;br /&gt;
            To: &amp;lt;colin@rockstarguys.com&amp;gt;&lt;br /&gt;
            Date: Fri, 3 Aug 2007 16:26:51 -0400&lt;br /&gt;
            Subject: test&lt;br /&gt;
            Thread-Topic: test&lt;br /&gt;
            Thread-Index: AcfkM10x5WZAtGtVSZuvcZqm0xUwAw==&lt;br /&gt;
            Message-ID: &amp;lt;AC754B3E95C1445FBAB321EB67733EDF@mydomain.net&amp;gt;&lt;br /&gt;
            Accept-Language: en-US&lt;br /&gt;
            Content-Language: en-US&lt;br /&gt;
            X-MS-Exchange-Organization-AuthAs: Anonymous&lt;br /&gt;
            X-MS-Exchange-Organization-AuthSource: mailserver.mydomain.net&lt;br /&gt;
            X-MS-Has-Attach:&lt;br /&gt;
            X-MS-TNEF-Correlator:&lt;br /&gt;
            Content-Type: multipart/alternative; boundary="_000_AC754B3E95C1445FBAB321EB67733EDF&lt;br /&gt;
            mydomainnet_"&lt;br /&gt;
            MIME-Version: 1.0&lt;br /&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;With no response on the &lt;a href="http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=1822889&amp;amp;SiteID=17" rel="external" target="_blank"&gt;TechNet forums&lt;/a&gt;, or &lt;a href="http://forums.msexchange.org/m_1800445998/mpage_1/key_/tm.htm#1800450582" rel="external" target="_blank"&gt;MSExchange.org&lt;/a&gt; I opened a case with PSS to get a hot fix (case SRZ070803000378 for those who are seeing similar issues).  The problem now is that I'm told that it will take two to three months to get a hot fix, probably after Service Pack 1 is released.  That will only happen after the bug has been accepted which could take another couple of weeks. Argh.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=tbWKOUqodRE:KWNGTGDGwUI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=tbWKOUqodRE:KWNGTGDGwUI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=tbWKOUqodRE:KWNGTGDGwUI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=tbWKOUqodRE:KWNGTGDGwUI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=tbWKOUqodRE:KWNGTGDGwUI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=tbWKOUqodRE:KWNGTGDGwUI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=tbWKOUqodRE:KWNGTGDGwUI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=tbWKOUqodRE:KWNGTGDGwUI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/colinbowern/~4/tbWKOUqodRE" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/colinbowern/~3/tbWKOUqodRE/BUG_Exchange_Server_2007_rewrites_Secondary_Email_Addresses_when_using_POP3_IMAP.aspx</link>
      <author>Colin Bowern</author>
      <comments>http://www.colinbowern.com/Post/07-08-28/BUG_Exchange_Server_2007_rewrites_Secondary_Email_Addresses_when_using_POP3_IMAP.aspx</comments>
      <guid isPermaLink="false">8f6834d5-e22e-4fb9-bc99-be316cf7354b</guid>
      <pubDate>Tue, 28 Aug 2007 12:31:00 GMT</pubDate>
    <feedburner:origLink>http://www.colinbowern.com/Post/07-08-28/BUG_Exchange_Server_2007_rewrites_Secondary_Email_Addresses_when_using_POP3_IMAP.aspx</feedburner:origLink></item>
    <item>
      <title>Bumping the CD/DVD drive letter in Windows PE</title>
      <description>&lt;p&gt;While slogging through automating my development workstation build I found the need to have a script that bumps the CD/DVD drive letter allocations up one so I could put a partition in its place. It seems like a useful script for those situations where you might need it so I thought I would post it:&lt;/p&gt; &lt;pre name="code" class="vb"&gt;'===========================================================================
' Bumps the CD/DVD drive letter to the next available drive letter.
'===========================================================================
' Syntax: BumpCDDriveLetter.vbs
'===========================================================================
' Errorlevels:
'   0: Success
'   1: Invalid command line.
'   2: Unable to find any volumes.
'   3: Unable to remove existing volume mount point.
'   4: Unable to create new volume mount point.
'===========================================================================
' Revision History:
'   1.0 - 01-Jul-07 - Initial creation.
'                   - Colin Bowern (colin.bowern@officialcommunity.com)
'===========================================================================

Option Explicit

Const EVENT_SUCCESS = 0
Const EVENT_ERROR = 1
Const EVENT_WARNING = 2
Const EVENT_INFORMATION = 4

Const MountVolPath = """%SYSTEMROOT%\System32\MountVol.exe"""

If WScript.Arguments.Count &amp;lt;&amp;gt; 0 Then
    WScript.Echo "Syntax: " &amp;amp; WScript.ScriptName
    WScript.Quit 1
End If

Dim shell, fileSystem, wmiService, diskVolumes, diskVolume, mountPoints, _
    mountPointCount, returnCode, commandLine
Set shell = CreateObject("WScript.Shell")
Set fileSystem = CreateObject("Scripting.FileSystemObject")
Set wmiService = GetObject("winmgmts://.\root\CIMV2")
returnCode = 0
mountPointCount = 0

Set diskVolumes = wmiService.ExecQuery("SELECT * FROM Win32_Volume WHERE DriveType = '5'")
For Each diskVolume in diskVolumes
    Dim mountVolReturnCode, newDriveLetter
    newDriveLetter = GetNextAvailableDriveLetter(diskVolume.DriveLetter)
    commandLine = MountVolPath &amp;amp; " " &amp;amp; diskVolume.DriveLetter &amp;amp; " /d"
    mountVolReturnCode = shell.Run(commandLine, 0, True)
    If mountVolReturnCode = 0 Then
        commandLine = MountVolPath &amp;amp; " " &amp;amp; newDriveLetter &amp;amp; ": " &amp;amp; diskVolume.DeviceId
        mountVolReturnCode = shell.Run(commandLine, 0, True)
        If mountVolReturnCode = 0 Then
            mountPoints = mountPoints &amp;amp; diskVolume.DriveLetter &amp;amp; _
                " (" &amp;amp; diskVolume.DeviceId &amp;amp; ") changed to " &amp;amp; _
                newDriveLetter &amp;amp; ":" &amp;amp; vbCrLf
            mountPointCount = mountPointCount + 1
        Else
            LogEvent EVENT_ERROR, "Error creating new volume mount point: " &amp;amp; _
                mountVolReturnCode
            SetReturnCode 4
        End If
    Else
        LogEvent EVENT_ERROR, "Error removing existing volume mount point: " &amp;amp; _
            mountVolReturnCode
        SetReturnCode 3
    End If
Next

If mountPointCount &amp;gt; 0 Then
    LogEvent EVENT_SUCCESS, "Processed the following " &amp;amp; mountPointCount &amp;amp; _
        " volume(s):" &amp;amp; vbCrLf &amp;amp; mountPoints
Else
    LogEvent EVENT_INFORMATION, "No volume(s) were modified."
    SetReturnCode 2
End If


WScript.Quit returnCode

'---------------------------------------------------------------------------
' Log an event to the Event Log and Console
'---------------------------------------------------------------------------
Sub LogEvent(eventType, message)
    ' Event logs not supported by Windows PE, Windows PE starts on X: by default
    If shell.ExpandEnvironmentStrings("%SystemDrive%") &amp;lt;&amp;gt; "X:" Then
        shell.LogEvent eventType, "[" &amp;amp; WScript.ScriptName &amp;amp; "] " &amp;amp; message
    End If
    WScript.Echo "[" &amp;amp; FormatDateTime(Now, vbGeneralDate) &amp;amp; "] " &amp;amp; message
End Sub

'---------------------------------------------------------------------------
' Set the return code to the highest possible value.
'---------------------------------------------------------------------------
Sub SetReturnCode(newReturnCode)
    If returnCode &amp;lt; newReturnCode Then
        returnCode = newReturnCode
    End If
End Sub

'---------------------------------------------------------------------------
' Return the next available drive letter.
'---------------------------------------------------------------------------
Function GetNextAvailableDriveLetter(startingLetter)
    GetNextAvailableDriveLetter = Chr(Asc(UCase(startingLetter)) + 1)
    Do Until Not fileSystem.DriveExists(GetNextAvailableDriveLetter)
        If GetNextAvailableDriveLetter = "Z" Then
            GetNextAvailableDriveLetter = "A"
        Else
            GetNextAvailableDriveLetter = Chr(Asc(GetNextAvailableDriveLetter) + 1)
        End If
    Loop
End Function
&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=HbElXGsuIgk:ctqh61vRR24:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=HbElXGsuIgk:ctqh61vRR24:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=HbElXGsuIgk:ctqh61vRR24:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=HbElXGsuIgk:ctqh61vRR24:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=HbElXGsuIgk:ctqh61vRR24:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=HbElXGsuIgk:ctqh61vRR24:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/colinbowern?a=HbElXGsuIgk:ctqh61vRR24:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/colinbowern?i=HbElXGsuIgk:ctqh61vRR24:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/colinbowern/~4/HbElXGsuIgk" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/colinbowern/~3/HbElXGsuIgk/Bumping_the_CD_DVD_drive_letter_in_Windows_PE.aspx</link>
      <author>Colin Bowern</author>
      <comments>http://www.colinbowern.com/Post/07-07-01/Bumping_the_CD_DVD_drive_letter_in_Windows_PE.aspx</comments>
      <guid isPermaLink="false">5b8213cf-35c4-4b66-9727-60ccf1124316</guid>
      <pubDate>Sun, 01 Jul 2007 15:31:00 GMT</pubDate>
    <feedburner:origLink>http://www.colinbowern.com/Post/07-07-01/Bumping_the_CD_DVD_drive_letter_in_Windows_PE.aspx</feedburner:origLink></item>
  </channel>
</rss>
