<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.iis.net/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Owais Shaikh&amp;#39;s Blog</title><subtitle type="html" /><id>http://blogs.iis.net/moshaikh/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.iis.net/moshaikh/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.iis.net/moshaikh/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20510.895">Community Server</generator><updated>2009-03-03T16:50:30Z</updated><entry><title>MSDeploy , XPath and XSL: Part III: Auto generate setParamFile from package and batch file to migrate apps to sites</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/moshaikh/archive/2009/09/25/msdeploy-xpath-and-xsl-part-iii-auto-generate-setparamfile-from-package-and-batch-file-to-migrate-apps-to-sites.aspx" /><id>http://blogs.iis.net/moshaikh/archive/2009/09/25/msdeploy-xpath-and-xsl-part-iii-auto-generate-setparamfile-from-package-and-batch-file-to-migrate-apps-to-sites.aspx</id><published>2009-09-26T06:14:00Z</published><updated>2009-09-26T06:14:00Z</updated><content type="html">&lt;P&gt;MSdeploy along with XSL is the way to go if you want to simplify many of the routine tasks that one needs to do. Two of the common scenarios are listed below. Before we start, you can download msxsl for free from &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=2fb55371-c94e-4373-b0e9-db4816552e41&amp;amp;DisplayLang=en" target=_blank mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=2fb55371-c94e-4373-b0e9-db4816552e41&amp;amp;DisplayLang=en"&gt;here&lt;/A&gt; and the web deployment tool (msdeploy) RTW from here (&lt;A href="http://go.microsoft.com/?linkid=9684516" mce_href="http://go.microsoft.com/?linkid=9684516"&gt;x86&lt;/A&gt; / &lt;A href="http://go.microsoft.com/?linkid=9684517" mce_href="http://go.microsoft.com/?linkid=9684517"&gt;x64&lt;/A&gt; )&lt;/P&gt;
&lt;P&gt;&lt;U&gt;&lt;/U&gt;&lt;/P&gt;
&lt;H3&gt;Auto generate set parameters XML file from a package:&lt;/H3&gt;
&lt;P&gt;If you have a package that you are trying to deploy to multiple servers and have different values to be specified for the params based on the servers (such as staging, server, production etc) then setParamFile is the switch you use to specify the file which has the values for the params defined in the package. The command is given below.&lt;/P&gt;
&lt;P&gt;msdeploy -verb:sync -source:package="c:\packages\mypackage.zip" -dest:auto,computername=StagingServer1 -setParamFile="c:\StagingParameters.xml"&lt;/P&gt;
&lt;P&gt;To create this xml file which defines the values for the parameters you can either type it manually or use the following one liner to generate it for you. Once you have this file, all you need to do is find the params that do not have a default value and specify the value and modify the defaultvalues that you expect to be different. You can download the xsl file from &lt;A href="http://blogs.iis.net/blogs/moshaikh/XSLFiles/setparamgen.xsl.txt" target=_blank&gt;here&lt;/A&gt; (As earlier rename the file to .xsl before using it)&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;I&gt;msdeploy -verb:getParameters -source:package=e:\wp\wordpress.zip -xml | c:\xsl\msxsl.exe - c:\xsl\setparamgen.xsl -o setParameters.xml&lt;/I&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;This xsl file is pasted below:&lt;/P&gt;
&lt;P&gt;&amp;lt;?xml version="1.0" ?&amp;gt;&lt;BR&gt;&amp;lt;xsl:stylesheet version="1.0"&lt;BR&gt;&amp;nbsp;&amp;nbsp; xmlns:xsl="&lt;A href="http://www.w3.org/1999/XSL/Transform"&gt;http://www.w3.org/1999/XSL/Transform&lt;/A&gt;" &amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;lt;xsl:template match ="/" &amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:apply-templates /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/xsl:template&amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;lt;xsl:template match="parameters" &amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;parameters&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;lt;xsl:for-each select="parameter" &amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;lt;xsl:element name="setParameters" &amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:attribute name="name" &amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:value-of select="@name" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;/xsl:attribute&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:attribute name="value" &amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:value-of select="@defaultValue" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;/xsl:attribute&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;/xsl:element&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;/xsl:for-each&amp;gt;&lt;BR&gt;&amp;lt;/parameters&amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;lt;/xsl:template &amp;gt;&lt;BR&gt;&amp;lt;/xsl:stylesheet &amp;gt;&lt;/P&gt;
&lt;H4&gt;&lt;/H4&gt;
&lt;H4&gt;&lt;U&gt;&lt;/U&gt;&lt;/H4&gt;
&lt;H3&gt;Migrating applications (vDirs) under a site on IIS6 to discreet sites on IIS7:&lt;/H3&gt;
&lt;P&gt;A typical scenario is a user having bunch of applications under a site on IIS6. When planning to migrate to IIS7 users want to convert these applications to discreet sites on IIS7. With msdeploy RTW you can do this as one single step as given below:&lt;/P&gt;
&lt;P&gt;msdeploy.exe -verb:sync -presync:runCommand="md D:\inetpub\wwwroot\NewContent &amp;amp; D:\Windows\System32\inetsrv\appcmd add site /name:NewSite /id:21 /bindings:http/*:8082: /physicalPath:D:\inetpub\wwwroot\NewContent " -source:metakey=/LM/W3SVC/1/Root/myapp -dest:metakey=/lm/w3svc/21/root,computername=iis7server,tempAgent=true &lt;/P&gt;
&lt;P&gt;The above command uses:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;preSync feature of msdeploy with runCommand to 
&lt;UL&gt;
&lt;LI&gt;Create an empty directory on the target server &lt;/LI&gt;
&lt;LI&gt;Create a site on the target server that points to this directory for content &lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;metaKey provider to sync the application on source to this newly created site on the target &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;This works and does the job. The issue with this command is that&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Its not easy to understand &lt;/LI&gt;
&lt;LI&gt;What if you have 30 applications that you need to convert to sites on the target. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Again we have xsl to our rescue. Here’s a one liner again that will give you the batch file that you need. All you need to do is execute the batch file and there you have 50 of your apps migrated as sites on the target iis7 server. You can download the xsl from &lt;A href="http://blogs.iis.net/blogs/moshaikh/XSLFiles/batchfilegen.xsl.txt" target=_blank&gt;here&lt;/A&gt; (As earlier rename the file to .xsl before using it). The xsl file has variables defined at the top if you want to use any value other than that I have used in this example.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;I&gt;msdeploy.exe -verb:dump -source:metakey=/lm/w3svc/1 -xml -disableLink:Content -xpath="//*[@name='AppRoot' and @value!='/LM/W3SVC/1/ROOT']" | msxsl.exe - batchfilegen.xsl -o convertappstosites.cmd&lt;/I&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;This will generate the convertapptosites.cmd which can be used to migrate apps to sites on the target. I also would like to explain that the above command is getting all the apps that are under the site with the ID 1. You can remove the trailing /1 from the source metakey to get all apps beneath all sites on the source.&lt;/P&gt;
&lt;P&gt;The xsl file for this is given below:&lt;/P&gt;
&lt;P&gt;&amp;lt;xsl:stylesheet version="1.0"&lt;BR&gt;&amp;nbsp;&amp;nbsp; xmlns:xsl="&lt;A href="http://www.w3.org/1999/XSL/Transform"&gt;http://www.w3.org/1999/XSL/Transform&lt;/A&gt;" &amp;gt;&lt;BR&gt;&amp;lt;xsl:output method="text" encoding="US-ASCII" /&amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;lt;!--&amp;nbsp;Change the server name, base binding info and the&amp;nbsp;root content path of the target server to suit your needs --&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name="s" select="'abcdefghijklmnopqrstuvwxyz'" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name="u" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name="compname" select="'myserver'" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name="serverbinding" select="'8081'" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name="RootContentDir" select="'D:\inetpub\wwwroot\'" /&amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;lt;xsl:template match ="/" &amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:apply-templates /&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/xsl:template&amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;lt;xsl:template match="output" &amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:for-each select="metaProperty" &amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:variable name="sitename" select="substring-after(substring-after(translate(@value,$s,$u),'ROOT'),'/')" /&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;lt;xsl:text&amp;gt;MSDeploy.exe -verb:sync -presync:runCommand="md &amp;lt;/xsl:text&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:value-of select="$RootContentDir" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:value-of select=" $sitename" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:text &amp;gt; &amp;amp;amp; D:\Windows\System32\inetsrv\appcmd add site /name:&amp;lt;/xsl:text&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:value-of select="$sitename" /&amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;lt;!-- it uses 20 as the increment to get a new metakey for the target site. You can change it to any value based on your&amp;nbsp;target server --&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:text&amp;gt; /id:&amp;lt;/xsl:text&amp;gt;&amp;lt;xsl:value-of select="position()+20" /&amp;gt;&amp;lt;xsl:text&amp;gt; /bindings:http/*:&amp;lt;/xsl:text&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:value-of select="position() + $serverbinding" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:text&amp;gt;: /physicalPath:&amp;lt;/xsl:text&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:value-of select="$RootContentDir" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:value-of select=" $sitename" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:text&amp;gt; " -source:metakey=&amp;lt;/xsl:text&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:value-of select="@value" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:text&amp;gt; -dest:metakey=/lm/w3svc/&amp;lt;/xsl:text&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:value-of select="position()+20" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xsl:text&amp;gt;/root,computername=&amp;lt;/xsl:text&amp;gt;&amp;lt;xsl:value-of select="$compname" /&amp;gt;&amp;lt;xsl:text&amp;gt;,tempAgent=true -verbose&lt;BR&gt;&amp;lt;/xsl:text&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xsl:for-each&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/xsl:template &amp;gt;&lt;BR&gt;&amp;lt;/xsl:stylesheet &amp;gt;&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;Happy deploying.&lt;/P&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=3426441" width="1" height="1"&gt;</content><author><name>moshaikh</name><uri>http://blogs.iis.net/members/moshaikh.aspx</uri></author><category term="Web Deployment" scheme="http://blogs.iis.net/moshaikh/archive/tags/Web+Deployment/default.aspx" /><category term="IIS" scheme="http://blogs.iis.net/moshaikh/archive/tags/IIS/default.aspx" /><category term="vdirs to site" scheme="http://blogs.iis.net/moshaikh/archive/tags/vdirs+to+site/default.aspx" /><category term="xpath" scheme="http://blogs.iis.net/moshaikh/archive/tags/xpath/default.aspx" /><category term="xsl" scheme="http://blogs.iis.net/moshaikh/archive/tags/xsl/default.aspx" /><category term="apps to site" scheme="http://blogs.iis.net/moshaikh/archive/tags/apps+to+site/default.aspx" /><category term="setparamfile" scheme="http://blogs.iis.net/moshaikh/archive/tags/setparamfile/default.aspx" /></entry><entry><title>MSDeploy , XPath and XSL: Part II: Generating formatted output</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/moshaikh/archive/2009/09/25/msdeploy-xpath-and-xsl-part-ii-generating-formatted-output.aspx" /><id>http://blogs.iis.net/moshaikh/archive/2009/09/25/msdeploy-xpath-and-xsl-part-ii-generating-formatted-output.aspx</id><published>2009-09-25T18:35:00Z</published><updated>2009-09-25T18:35:00Z</updated><content type="html">&lt;P&gt;Using xsl and msxsl with msdeploy you can generate formatted html logs. It gets even better when you use the API; you can generate better organized logs with custom messages to suit your needs. Before we start, you can download msxsl for free from &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=2fb55371-c94e-4373-b0e9-db4816552e41&amp;amp;DisplayLang=en" target=_blank mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=2fb55371-c94e-4373-b0e9-db4816552e41&amp;amp;DisplayLang=en"&gt;here&lt;/A&gt; and the web deployment tool (msdeploy) from here (&lt;A href="http://go.microsoft.com/?linkid=9684516" mce_href="http://go.microsoft.com/?linkid=9684516"&gt;x86&lt;/A&gt; / &lt;A href="http://go.microsoft.com/?linkid=9684517" mce_href="http://go.microsoft.com/?linkid=9684517"&gt;x64&lt;/A&gt; )&lt;/P&gt;
&lt;H4&gt;&lt;STRONG&gt;Using the MSDeploy.exe:&lt;/STRONG&gt;&lt;/H4&gt;
&lt;P&gt;I have a simple xsl that shows the files or directories or anything that is either added, deleted, modified or skipped in a table format. The xml spew that is generated by specifying –xml switch to msdeploy can be piped into msxsl along with the attached xsl file and then this can be opened in internet explorer or a browser of your choice all in one command. The xsl can be modified to output non xml output. For this you can look at the part III of the post.&lt;/P&gt;
&lt;P&gt;The following command creates a package of the webserver while skipping all asp files in the server and pipes the xml output to msxsl. Msxsl uses the piped xml and applies the msdeploy.xsl to it to generate out.html which is opened by the browser. &lt;/P&gt;
&lt;P&gt;C:\&amp;gt;msdeploy -verb:sync -source:webserver -dest:package=e:\pack.zip -xml -skip:objectName=filePath;absolutePath=\.asp -verbose | f:\xsl\msxsl – f:\xsl\msdeploy.xsl -o out.html &amp;amp; iexplore c:\out.html&lt;/P&gt;
&lt;P&gt;You can download the xsl file from &lt;A href="http://blogs.iis.net/blogs/moshaikh/XSLFiles/msdeploy.xsl.txt" target=_blank mce_href="http://blogs.iis.net/blogs/moshaikh/XSLFiles/msdeploy.xsl.txt"&gt;here&lt;/A&gt;. (Its currently named msdeploy.xsl.txt since uploading xsl files is not allowed. Make sure to rename it to xsl before using it)&lt;/P&gt;
&lt;H4&gt;&lt;STRONG&gt;Using the MSDeploy API:&lt;/STRONG&gt;&lt;/H4&gt;
&lt;P&gt;An xsl similar to the one above is used. For getting formatted output from the API you need to do the following: You can download the the visual studio solution for this from &lt;A href="http://blogs.iis.net/blogs/moshaikh/SourceZips/eventtracer.zip" target=_blank mce_href="http://blogs.iis.net/blogs/moshaikh/SourceZips/eventtracer.zip"&gt;here&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;1. Add traceeventhandler to the source and / or destination base options. Tracelevel needs to be verbose to get skipped object and replace rule traces. The default tracelevel is info which gives just the DeploymentObjectChangedEventArgs.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;DeploymentBaseOptions baseOptions = new DeploymentBaseOptions(); &lt;BR&gt;baseOptions.Trace += TraceEventHandler; &lt;BR&gt;baseOptions.TraceLevel = TraceLevel.Verbose;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;2. Implement the traceeventhandler function&lt;/P&gt;
&lt;P&gt;You can access the provider name, path and the operationtype easily in DeploymentObjectChangedEventArgs&amp;nbsp; but for other traceEvents you need to use reflection to access these values as shown below.&lt;/P&gt;
&lt;P&gt;private void TraceEventHandler(object sender, DeploymentTraceEventArgs e) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DeploymentObjectChangedEventArgs ChangedEvent = e as DeploymentObjectChangedEventArgs; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ChangedEvent != null) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WriteEventEntry(ChangedEvent.ProviderName, ChangedEvent.Path, ChangedEvent.OperationType.ToString(), ""); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DeploymentTraceEventArgs TraceEvent = e as DeploymentTraceEventArgs; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (TraceEvent != null) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string strMsg = TraceEvent.Message; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string strProviderName = "", strPath = "", strRuleName = ""; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (strMsg.ToLower().Contains("skip")) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //DeploymentRuleSkipObjectEvent has _object as the deploymentObject &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FieldInfo fi = TraceEvent.GetType().GetField("_object", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (fi == null) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //DeploymentRuleSkipEvent has _destObject as the deploymentObject &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fi = TraceEvent.GetType().GetField("_destObject", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (fi != null) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strPath = ((DeploymentObject)fi.GetValue(TraceEvent)).AbsolutePath; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strProviderName = ((DeploymentObject)fi.GetValue(TraceEvent)).Name; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Get the _rule object and get its name &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fi = TraceEvent.GetType().GetField("_rule", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strRuleName = fi != null ? ((DeploymentRule)fi.GetValue(TraceEvent)).Name : ""; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //We are here implies its a DeploymentSkipDirective &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fi = TraceEvent.GetType().GetField("_directiveName", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strRuleName = fi != null ? fi.GetValue(TraceEvent).ToString() : ""; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fi = TraceEvent.GetType().GetField("_objectName", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strProviderName = fi != null ? fi.GetValue(TraceEvent).ToString() : ""; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fi = TraceEvent.GetType().GetField("_absolutePath", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strPath = fi != null ? fi.GetValue(TraceEvent).ToString() : ""; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WriteEventEntry(strProviderName, strPath, "Skipped", strRuleName); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;3. Implement the writeevententry function to write xml output&lt;/P&gt;
&lt;P&gt;private void WriteEventEntry(string strProvName, string strPath, string strOperationType, string strRuleName) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlOut.WriteStartElement("object"); &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlOut.WriteStartElement("name"); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlOut.WriteValue(strProvName); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlOut.WriteEndElement(); &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlOut.WriteStartElement("path"); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlOut.WriteValue(strPath); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlOut.WriteEndElement(); &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlOut.WriteStartElement("operationType"); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlOut.WriteValue(strOperationType); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlOut.WriteEndElement(); &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlOut.WriteStartElement("Rule"); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlOut.WriteValue(strRuleName); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlOut.WriteEndElement(); &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlOut.WriteEndElement(); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;4. Call the generatehtml with the xsl provided to get transformed html&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;XPathDocument xPathDoc = new XPathDocument(m_strXmlLogFilePath); &lt;BR&gt;XslCompiledTransform xslTrans = new XslCompiledTransform(); &lt;BR&gt;xslTrans.Load(Environment.CurrentDirectory + @"\TransformOutput.xslt"); &lt;BR&gt;XmlTextWriter xW = new XmlTextWriter(m_strLogFileDir + @"\MSDepLog.html", null); &lt;BR&gt;xslTrans.Transform(xPathDoc, null, xW); &lt;BR&gt;xW.Close();&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Thats all there is to it. The xsl and the code can be modified to suit your needs such as tracing replace events etc.&lt;/P&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=3425917" width="1" height="1"&gt;</content><author><name>moshaikh</name><uri>http://blogs.iis.net/members/moshaikh.aspx</uri></author><category term="xpath" scheme="http://blogs.iis.net/moshaikh/archive/tags/xpath/default.aspx" /><category term="xsl" scheme="http://blogs.iis.net/moshaikh/archive/tags/xsl/default.aspx" /><category term="Format msdeploy output" scheme="http://blogs.iis.net/moshaikh/archive/tags/Format+msdeploy+output/default.aspx" /><category term="msdeploy api trace" scheme="http://blogs.iis.net/moshaikh/archive/tags/msdeploy+api+trace/default.aspx" /><category term="reflection" scheme="http://blogs.iis.net/moshaikh/archive/tags/reflection/default.aspx" /></entry><entry><title>MSDeploy , XPath and XSL: Part 1: Getting information</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/moshaikh/archive/2009/09/25/msdeploy-xpath-and-xsl-part-1-getting-information.aspx" /><id>http://blogs.iis.net/moshaikh/archive/2009/09/25/msdeploy-xpath-and-xsl-part-1-getting-information.aspx</id><published>2009-09-25T16:47:00Z</published><updated>2009-09-25T16:47:00Z</updated><content type="html">&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Now that MSDeploy RTW has been officially released, I want to discuss just some of the few great features it has.&lt;/P&gt;
&lt;H4&gt;Getting Information:&lt;/H4&gt;
&lt;P&gt;The tool can be used in great many ways to get remote or local system information using xpath with the different providers. A few of the scenarios are given below:&lt;/P&gt;
&lt;H4&gt;1. General Rule:&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;One general rule before we start is that, since XPath is case sensitive you can make it case insensitive in a way by using the translate function and changing the case of all the values to lower case and carrying out a lower case comparison. For e.g. if you are looking for all sites that start with “Default” and don’t care if its “Default” or “default” you can use this command as follows:&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;msdeploy -verb:dump -source:apphostconfig -xml -disableLink:content -xpath=//*[contains(translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'),'default web')]&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;This command tells xpath compiler to convert the value of @name attribute to lower case before verifying whether this value contains ‘default web’. This can be used for all examples below.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;2. Find if .net 3.5 is installed on a remote system:&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;msdeploy -verb:dump -source:regKey="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP",tempAgent=true,computername=someserver -xml -xpath=//*[@path='v3.5']&lt;/P&gt;
&lt;P&gt;If the remoteserver does have .net 3.5 installed you will see an output as:&lt;/P&gt;
&lt;P&gt;&amp;lt;output&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;regKey path="v3.5" securityDescriptor="D:"&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;regKey path="1033" securityDescriptor="D:"&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;regValue name="Version" valueType="String" value="3.5.30729.4926" /&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;regValue name="CBS" valueType="DWord" value="1" /&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;regValue name="Install" valueType="DWord" value="1" /&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;regValue name="SP" valueType="DWord" value="1" /&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/regKey&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;regValue name="Version" valueType="String" value="3.5.30729.4926" /&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;regValue name="CBS" valueType="DWord" value="1" /&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;regValue name="Install" valueType="DWord" value="1" /&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;regValue name="InstallPath" valueType="String" value="C:\Windows\Microsoft.NET\Framework\v3.5\" /&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;regValue name="SP" valueType="DWord" value="1" /&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;/regKey&amp;gt; &lt;BR&gt;&amp;lt;/output&amp;gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;3. Find all files that were modified on a specific date on a remote target or have a specific size:&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;msdeploy –verb:dump –source:dirPath=c:\inetpub\wwwroot,computername=remoteserver,tempAgent=true -xpath=//*[@path='content']/*[contains(@lastWriteTime,'7/01/2009')]&lt;/P&gt;
&lt;P&gt;This will give you all the files under the content folder that have been last modified on 7/1/2009. You can alternatively change xpath to //*[contains(@lastWriteTime,'7/01/2009')] to get all files under inetpub\wwwroot instead of just the files in content folder underneath this.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;4. Find all applications that use “mycoolAppPool”:&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;msdeploy.exe -verb:dump -source:apphostconfig -disableLink:Content -xml -xpath=//*[@applicationPool='mycoolapppool'] &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;5. Find out if more than 1 application has been set to use the port 8080:&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;msdeploy.exe -verb:dump -source:apphostconfig -disableLink:Content -xml -xpath=//*[contains(@bindingInformation,'8080')] &lt;BR&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;6. Find all the different host headers that your sites are using on port 80:&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;msdeploy.exe -verb:dump -source:apphostconfig -disableLink:Content -xml -xpath=//*[contains(@bindingInformation,'80’)] &lt;BR&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;7. Find all sites that do not have any apps or vdirs beneath them:&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;msdeploy.exe -verb:dump -source:apphostconfig -disableLink:Content -xml -xpath=//site[count(application)=1]&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;8. Find all directories that are empty&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;msdeploy.exe –verb:dump –source:dirPath=C:\inetpub\wwwroot,computername=remoteserver –xml -xpath=//dirPath[not(*)]&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=3425759" width="1" height="1"&gt;</content><author><name>moshaikh</name><uri>http://blogs.iis.net/members/moshaikh.aspx</uri></author></entry><entry><title>Web Server Change Notification or Web Server Compare or MS Deploy UI for Multi Server Sync</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/moshaikh/archive/2009/04/26/web-server-change-notification-or-web-server-compare-or-multi-server-sync-in-a-web-farm.aspx" /><id>http://blogs.iis.net/moshaikh/archive/2009/04/26/web-server-change-notification-or-web-server-compare-or-multi-server-sync-in-a-web-farm.aspx</id><published>2009-04-26T16:04:00Z</published><updated>2009-04-26T16:04:00Z</updated><content type="html">&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:59f299da-1d95-4468-a5a9-bf32271d8cad" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/web+Deployment+Tool" rel="tag"&gt;web Deployment Tool&lt;/a&gt;,&lt;a href="http://technorati.com/tags/web+server+compare+tool" rel="tag"&gt;web server compare tool&lt;/a&gt;,&lt;a href="http://technorati.com/tags/msdeploy+UI" rel="tag"&gt;msdeploy UI&lt;/a&gt;,&lt;a href="http://technorati.com/tags/web+server+change+notification" rel="tag"&gt;web server change notification&lt;/a&gt;,&lt;a href="http://technorati.com/tags/multi+server+sync" rel="tag"&gt;multi server sync&lt;/a&gt;&lt;/div&gt;  &lt;h4&gt;Introduction:&lt;/h4&gt;  &lt;p&gt;If you are interested in&amp;#160; any of the following then you can read on:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Getting notified in real time if any of the web servers in your web farm cluster has changed. This change can be in terms of:      &lt;ul&gt;       &lt;li&gt;An assembly that was added to the GAC (global assembly cache) &lt;/li&gt;        &lt;li&gt;A registry key that was added or removed or a value added &lt;/li&gt;        &lt;li&gt;Some content was added, modified, deleted or some permissions on any of the content was changed &lt;/li&gt;        &lt;li&gt;A configuration change such as addition of a new web site or an app pool etc &lt;/li&gt;        &lt;li&gt;A new module that was installed or configured &lt;/li&gt;        &lt;li&gt;Machine config or some web configuration was modified &lt;/li&gt;        &lt;li&gt;A server certificate was added / deleted &lt;/li&gt;        &lt;li&gt;A new database was created &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Comparing any two or more servers on your cluster to see how they differ in the same terms outlined above &lt;/li&gt;    &lt;li&gt;Sync the changes that happened on any of the servers to one or more servers such as GAC or ACL changes &lt;/li&gt;    &lt;li&gt;Sync the differences between servers such as      &lt;ul&gt;       &lt;li&gt;GAC all assemblies on server1 that are missing on server2 or more &lt;/li&gt;        &lt;li&gt;Copy all certificates from server1 to server2, 3, 4 … or just the delta &lt;/li&gt;        &lt;li&gt;Copy all Databases from server1 to server2, … &lt;/li&gt;        &lt;li&gt;Copy all content between servers &lt;/li&gt;        &lt;li&gt;Sync the entire web server1 to all others in the farm &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;h4&gt;&lt;/h4&gt;  &lt;p mce_keep="true"&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Some snapshots:&lt;/h4&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://blogs.iis.net/blogs/moshaikh/WebServerFarm/ChangeViewer.jpg" target="_blank" mce_href="http://blogs.iis.net/blogs/moshaikh/WebServerFarm/ChangeViewer.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="image" border="0" alt="image" src="http://blogs.iis.net/blogs/moshaikh/image_29C84ED3.png" width="244" height="141" mce_src="http://blogs.iis.net/blogs/moshaikh/image_29C84ED3.png" /&gt;&lt;/a&gt; &lt;a href="http://blogs.iis.net/blogs/moshaikh/WebServerFarm/CompareView.jpg" target="_blank" mce_href="http://blogs.iis.net/blogs/moshaikh/WebServerFarm/CompareView.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.iis.net/blogs/moshaikh/image5_14F65653.png" width="244" height="141" mce_src="http://blogs.iis.net/blogs/moshaikh/image5_14F65653.png" /&gt;&lt;/a&gt; &lt;a href="http://blogs.iis.net/blogs/moshaikh/WebServerFarm/CompareRequest.jpg" target="_blank" mce_href="http://blogs.iis.net/blogs/moshaikh/WebServerFarm/CompareRequest.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.iis.net/blogs/moshaikh/image8_3438FD26.png" width="244" height="141" mce_src="http://blogs.iis.net/blogs/moshaikh/image8_3438FD26.png" /&gt;&lt;/a&gt; &lt;a href="http://blogs.iis.net/blogs/moshaikh/WebServerFarm/SyncSelectedChanges.jpg" mce_href="http://blogs.iis.net/blogs/moshaikh/WebServerFarm/SyncSelectedChanges.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.iis.net/blogs/moshaikh/image11_7396B0B6.png" width="244" height="141" mce_src="http://blogs.iis.net/blogs/moshaikh/image11_7396B0B6.png" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;These snapshots show 4 views of the tool. From left to right, the first one shows comparison, second one shows changes since inception on a server,third and fourth are request panes showing the requests that can be submitted to the service. &lt;/p&gt;  &lt;h4&gt;Pre-Requisites:&lt;/h4&gt;  &lt;p&gt;These are only required on the primary server that behaves as the manager. Starting RTW Web Deployment Tool has a tempAgent feature that avoids the need to install it on any box including the source.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Microsoft SQL Server Express &lt;a href="http://go.microsoft.com/fwlink/?linkid=65109"&gt;2005&lt;/a&gt; or &lt;a href="http://go.microsoft.com/?linkid=9394725"&gt;2008&lt;/a&gt; [Only on the primary server that manages] &lt;/li&gt;    &lt;li&gt;Web Deployment Tool&amp;#160; &lt;a href="http://go.microsoft.com/?linkid=9684516"&gt;x86&lt;/a&gt; or &lt;a href="http://go.microsoft.com/?linkid=9684517"&gt;x64&lt;/a&gt;. [Only on the primary server that manages]&lt;/li&gt;    &lt;li&gt;MSMQ [Only on the primary server that manages. Rest the application will configure when needed or you can manually configure if you want to] &lt;/li&gt; &lt;/ol&gt;  &lt;h4&gt;How to Use:&lt;/h4&gt;  &lt;h5&gt;Step I: Install Dependencies:-&lt;/h5&gt;  &lt;ol&gt;   &lt;li&gt;On the source machine install:&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt; the database and web deployment tool.&lt;/li&gt;      &lt;li&gt;MSMQ by simply running ocssetup MSMQ-Server. It should be installed in a few minutes. &lt;/li&gt;   &lt;/ul&gt; &lt;/ol&gt;  &lt;h5&gt;Step II: Copy Files:-&lt;/h5&gt;  &lt;ol&gt;   &lt;li&gt;Copy and unzip the files from &lt;a href="http://blogs.iis.net/blogs/moshaikh/WebServerFarm/WSFM_bin.zip"&gt;here&lt;/a&gt; to any local folder of a system which you want to be the manager for the entire cluster. &lt;/li&gt;    &lt;li&gt;Run the CreateWSF_DB.sql. &lt;/li&gt;    &lt;li&gt;Run WebServerFarmManager.exe and navigate to the Administration tab on the right pane &lt;/li&gt;    &lt;li&gt;Here you can add the name of the servers that you need monitored.      &lt;ul&gt;       &lt;li&gt;For each server add the username, password, domain name, db instance name on that server and whether you want db changes to be monitored. &lt;/li&gt;        &lt;li&gt;Set DoWatch to true. Any server that has this value as false, will not be monitored. &lt;/li&gt;        &lt;li&gt;For any server if the user, that service will run as, has admin rights to all servers then you can leave the username and password fields blank. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;On this pane you can also change the default values in the app.config based on your needs.&lt;/li&gt;    &lt;ol&gt;     &lt;li&gt;Change the db connection string&lt;/li&gt;      &lt;li&gt;Change the bin path to the location you copied the binary files to&lt;/li&gt;   &lt;/ol&gt;    &lt;li&gt;Here you can also install / uninstall the webserverfarmwatch service and start and stop the service. So go ahead and install and start the service if you have already added the databases.&lt;/li&gt; &lt;/ol&gt;  &lt;h5&gt;Step III: Using the application&lt;/h5&gt;  &lt;ol&gt;   &lt;li&gt;The WebServerFarm Watch svc takes a snapshot of the all the servers in the farm that you listed on the servers page. &lt;/li&gt;    &lt;li&gt;Run webserverfarmmanager. &lt;strong&gt;One cool thing now is that it has a log messages pane that shows all the progress from all the servers in the UI. So if you happen to have connection issues or any other problems you should see that being logged in this pane.&lt;/strong&gt; You don't need to look into any other logs.&lt;/li&gt;    &lt;li&gt;In the left pane the top pane shows the changes that have happened as of now or any of the servers. Click on any server listed in the tree view to see any changes. Mind you this IS LIVE. If you go onto any server and add an assembly to the gac or add a registry key under the ones its monitoring or add / change / modify any content or set or remove ACL this view should show you immediately. The only changes that are not live and need to be requested are the configuration changes, certificate addition and db creation. But these you can easily get just by double-clicking on any of the servers in the list. It will immediately retrieve and show you all the changes including the configuration change. &lt;/li&gt;    &lt;li&gt;The lower left pane shows the server comparison report. Since you have not compared yet it will be empty.      &lt;ul&gt;       &lt;li&gt;On the right pane navigate to the “Submit Requests” tab. &lt;/li&gt;        &lt;li&gt;From the action drop down choose “Compare Servers”. From the list boxes below chose any one source server and choose any or all of the destination servers and submit request. &lt;/li&gt;        &lt;li&gt;Wait for a few minutes to process and double-click the left lower pane node or close and re-start the app. You will see a list of server comparison nodes. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Click on any of the nodes under the server comparison node in the lower left pane and you will see a comparison report of all. &lt;/li&gt;    &lt;li&gt;The name of the tabs are self explanatory. The tabs are:      &lt;ul&gt;       &lt;li&gt;Content: Content changes from inception or difference in content on source and destination.          &lt;ul&gt;           &lt;li&gt;For changes view it shows all the files that have changed in any regard or added or deleted. &lt;/li&gt;            &lt;li&gt;For comparison it shows only the content folders that are missing on source or destination &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;Registry Key:          &lt;ul&gt;           &lt;li&gt;Changes view: Any or all changes to registry since inception. The list of registry monitored is in the regkeyManifest.xml. You can change / add / remove more keys to monitored as per your needs and restart the service. If you change this file on this parent server manager it will affect all the servers but if you change this file on any given server then the change is local &lt;/li&gt;            &lt;li&gt;Comparison View: It does not compare or sync registry changes. This is because the changes to the registry are evil and I do not want to automate it. &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;Gac:          &lt;ul&gt;           &lt;li&gt;Changes View: Any file that was added to / removed from the GAC &lt;/li&gt;            &lt;li&gt;Comparison View: All assemblies that are missing on the source or destination in the GAC. It says ONLY_ON_SOURCE or ONLY_ON_DEST in the message column. &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;Certificates          &lt;ul&gt;           &lt;li&gt;Changes View: Any server certificate that was added to / removed from the MY store &lt;/li&gt;            &lt;li&gt;Comparison View: All server certificates that are missing on the source or destination in the MY store. It says ONLY_ON_SOURCE or ONLY_ON_DEST in the message column. &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;MS SQL DB          &lt;ul&gt;           &lt;li&gt;Changes View: Any database that was created since inception &lt;/li&gt;            &lt;li&gt;Comparison View: All databases that are missing on the source or destination. It says ONLY_ON_SOURCE or ONLY_ON_DEST in the message column. &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;AppHostConfig or App Pool Config or Machine Config or Root Web Config          &lt;ul&gt;           &lt;li&gt;Changes View: Any configuration changes since inception. &lt;/li&gt;            &lt;li&gt;Comparison View: All changes that would actually happen if you performed a sync. &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Functions:      &lt;ul&gt;       &lt;li&gt;Get Changes on server: This ,as explained above, is mostly live and the rest can be retrieved by double-clicking any server in the upper part of the left pane which shows servers list &lt;/li&gt;        &lt;li&gt;Compare any two servers: This was again explained above in Step III item 4 &lt;/li&gt;        &lt;li&gt;Sync Changes: This should be useful. It lets you carry over any change that happened on one server to 1 or more servers.          &lt;ul&gt;           &lt;li&gt;You can selectively propagate a type of change to any of the servers you care. &lt;/li&gt;            &lt;li&gt;For e.g. if 2 assemblies were added to the gac and a database was added on Server1 while 10 files were uploaded on server2. &lt;/li&gt;            &lt;li&gt;Navigate to the submit requests pane and choose “Sync Changes” from the action drop down &lt;/li&gt;            &lt;li&gt;Choose the GAC and DB from the changetype list. &lt;/li&gt;            &lt;li&gt;Choose Server1 and any number of destination servers. It does not let you choose multiple source because these syncs are run parallel in multiple threads and not sequentially. &lt;/li&gt;            &lt;li&gt;Submit request &lt;/li&gt;            &lt;li&gt;Then choose Server2 as source and choose content as the changetype and re-submit request. The requests sequentially submitted are processed sequentially while the multiple requests within a request are processed simultaneously. &lt;/li&gt;            &lt;li&gt;You should see the destination changes appear in the changes view &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;Sync Servers:          &lt;ul&gt;           &lt;li&gt;This lets you sync all the differences between any two or more servers. &lt;/li&gt;            &lt;li&gt;For e.g. I have 3 servers. S1, S2 and S3. &lt;/li&gt;            &lt;li&gt;S1 has 10 more assemblies gac’ed , 3 more databases and 5 extra certificates, 3 new sites, 2 new app pools than S2 and 20 more assemblies gac’ed but same number of databases and 2 fewer certificates and some apppool changes and some site differences as compared to S3. &lt;/li&gt;            &lt;li&gt;Choose Sync Servers from the drop down and choose GAC, DB, Cert, Content, Apphostconfig, apppoolconfig from the changetype list &lt;/li&gt;            &lt;li&gt;Choose S1 as the source and S2 and S3 as the destinations. &lt;/li&gt;            &lt;li&gt;Submit request. All of the above differences will be synced except for the 2 certificates that are missing in S1. &lt;/li&gt;            &lt;li&gt;Resubmit request with S3 as source and S1 as destination and change type as cert. This will sync all 3 servers. &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;Accept Changes:          &lt;ul&gt;           &lt;li&gt;As the name suggests, this is there to clear the db and cache of all the change lists once you are done dealing with them. &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;h4&gt;&amp;#160;&lt;/h4&gt;  &lt;h4&gt;How it works:&lt;/h4&gt;  &lt;p&gt;A basic representation of how it works&lt;/p&gt;  &lt;p&gt;&lt;a title="Arch Diagram" href="http://blogs.iis.net/blogs/moshaikh/WebServerFarm/WebServerFarmManager.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.iis.net/blogs/moshaikh/image_19BC386D.png" width="183" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;The service: [WebServerFarmWatcher Svc]&lt;/h5&gt;  &lt;ol&gt;   &lt;li&gt;Creates two local queues if they don’t exist with the names MSDeployRequestQueue and MSDeployResponseQueue &lt;/li&gt;    &lt;li&gt;Enumerates all the servers and for each server:      &lt;ul&gt;       &lt;li&gt;Calls the getsnapshot function of SyncManager class &lt;/li&gt;        &lt;li&gt;Instantiates an object of WebServerWatcher class &lt;/li&gt;        &lt;li&gt;It then starts listening for messges on the two queues mentioned above &lt;/li&gt;        &lt;li&gt;Any request received on MSDeployRequestQueue is processed and Queues a seperate thread to process every command within a request. Such as if a sync request is received from Server1 to Server2, Server3, Server4, it will queue 3 threads to serve this request &lt;/li&gt;        &lt;li&gt;Any response received on MSDeployResponseQueue is added to the DB &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;h5&gt;The WebServerWatcher class:&lt;/h5&gt;  &lt;ol&gt;   &lt;li&gt;It enumerates all content folders and starts listening for any and all changes to the content. &lt;/li&gt;    &lt;li&gt;Copies the remote notification svc on the server and starts it &lt;/li&gt;    &lt;li&gt;Sends a message to get an initial snapshot of GAC, Databases and certificates &lt;/li&gt;    &lt;li&gt;Any change notification it receives for content is added to the database &lt;/li&gt; &lt;/ol&gt;  &lt;h5&gt;The SyncManager class:&lt;/h5&gt;  &lt;ol&gt;   &lt;li&gt;This is just a wrapper for MSDeploy API &lt;/li&gt;    &lt;li&gt;It implements the basic sync, compare and getchanges functions along with the trace listeners. &lt;/li&gt; &lt;/ol&gt;  &lt;h5&gt;The RemNotificationSvc:&lt;/h5&gt;  &lt;ol&gt;   &lt;li&gt;On start it gets all the keys specified in regkeymanifest.xml and starts waiting on change notification for these regkeys &lt;/li&gt;    &lt;li&gt;It processes requests from the WebServerWatcher for getting a GAC , DB and certificate snapshot or for changes in DB and certificate. It also resolves any assembly that is GAC’ed and provides its complete name &lt;/li&gt; &lt;/ol&gt;  &lt;h5&gt;The WebServerFarmManager UI:&lt;/h5&gt;  &lt;ol&gt;   &lt;li&gt;All it does is display the data in the UI based on which node the data is being requested on and &lt;/li&gt;    &lt;li&gt;Submit request to the service based on the users needs. &lt;/li&gt;    &lt;li&gt;It does not listen to any MSMQ queue except the log queue.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The only ones that listen to the Queues are the parent service class on the server manager, the UI (log queue) and the remnotificationsvc on each of the servers being monitored.&lt;/p&gt;  &lt;h4&gt;Code:&lt;/h4&gt;  &lt;p&gt;You can download the entire code with the solution file from &lt;a href="http://blogs.iis.net/blogs/moshaikh/WebServerFarm/WebServerFarmMgrRTW_Src.zip"&gt;here&lt;/a&gt;&lt;/p&gt;  &lt;h5&gt;&lt;/h5&gt;  &lt;h4&gt;&lt;/h4&gt;  &lt;p&gt;Acknowledgements and tool re-use:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Madhur Joshi for taking his time to provide valuable feedback &lt;/li&gt;    &lt;li&gt;Web Deployment Tool which is the core of all the synchronization that this does. &lt;/li&gt;    &lt;li&gt;Junfeng Zhang for the GACWrapper that I used after some trimming of the stuff that I did not need. &lt;/li&gt; &lt;/ol&gt;  &lt;h4&gt;&lt;/h4&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5 align="center"&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights&lt;/h5&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=3119747" width="1" height="1"&gt;</content><author><name>moshaikh</name><uri>http://blogs.iis.net/members/moshaikh.aspx</uri></author></entry><entry><title>Writing Custom Rules for Web Deployment Tool</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/moshaikh/archive/2009/03/03/writing-custom-rules-for-web-deployment-tool.aspx" /><id>http://blogs.iis.net/moshaikh/archive/2009/03/03/writing-custom-rules-for-web-deployment-tool.aspx</id><published>2009-03-04T00:50:30Z</published><updated>2009-03-04T00:50:30Z</updated><content type="html">&lt;p&gt;One of the users posted a question on the blog that he is trying to sync two servers which are being independently modified by users of the two servers. Thus he wants the two servers to be synced using MS Deploy but at the same time wants to exclude the files that are newer at the destination. &lt;/p&gt;  &lt;p&gt;Adding this and such similar rules to customize the behavior of MS Deploy is easy and just requires a few simple steps. I am presenting a step by step guide for adding a Skip Update Newer File rule. This can be customized or modified easily to suite individuals needs. There is one such rule which comes bundled with the installation of MS Deploy by default. This is the DoNotDeleteRuleHandler which is disabled by default. &lt;/p&gt;  &lt;h4&gt;&lt;/h4&gt;  &lt;h4&gt;Download&lt;/h4&gt;  &lt;p&gt;You can download the project with the source code from &lt;a href="http://blogs.iis.net/blogs/moshaikh/SourceZips/WDCustomRules.zip"&gt;here&lt;/a&gt;. [Disclaimer: This is not an official Microsoft download and hence not supported by Microsoft. Please direct all queries about it to me and I will respond as soon as possible]&lt;/p&gt;  &lt;h4&gt;Steps to Add a Custom Rule Handler:&lt;/h4&gt;  &lt;ol&gt;   &lt;li&gt;Write a managed assembly that overrides the update process of ms deploy as follows:      &lt;ol&gt;       &lt;li&gt;A class that derives from DeploymentRuleHandler. For this you need to add a reference to Microsoft.Web.Deployment.dll in your install directory. This is just for compiling your assembly. At run time this assembly will be loaded from the GAC &lt;/li&gt;        &lt;li&gt;It should override the Update, Name, FriendlyName and Description functions of rulehandler. Below is a code snippet that does all this &lt;/li&gt;     &lt;/ol&gt;      &lt;ul&gt;       &lt;p&gt;using System;          &lt;br /&gt;using System.Collections.Generic;           &lt;br /&gt;using System.Linq;           &lt;br /&gt;using System.Text;           &lt;br /&gt;using Microsoft.Web.Deployment; &lt;/p&gt;        &lt;p&gt;namespace WDCustomRules          &lt;br /&gt;{           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public class SkipNewerFilesUpdateRuleHandler : DeploymentRuleHandler           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; #region CONSTANTS           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private const string RULENAME = &amp;quot;SkipNewerFilesUpdateRule&amp;quot;;           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private const string RULEFRIENDLYNAME = &amp;quot;Skip Newer Files on Update Rule&amp;quot;;           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private const string RULEDESCRIPTION = &amp;quot;If the dest file has a later lastwritetime than a file from the source being copied, this rule will skip it&amp;quot;;           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; #endregion &lt;/p&gt;        &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public override void Update(DeploymentSyncContext syncContext, DeploymentObject destinationObject, ref DeploymentObject sourceObject, ref bool proceed)          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (sourceObject.Name == &amp;quot;filePath&amp;quot; &amp;amp;&amp;amp; destinationObject.Name == &amp;quot;filePath&amp;quot;)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DeploymentAttribute sourceLastWriteTimeAttribute;           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DeploymentAttribute destLastWriteTimeAttribute;           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (sourceObject.Attributes.TryGetValue(&amp;quot;lastWriteTime&amp;quot;, out sourceLastWriteTimeAttribute) &amp;amp;&amp;amp;           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; destinationObject.Attributes.TryGetValue(&amp;quot;lastWriteTime&amp;quot;, out destLastWriteTimeAttribute))           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DateTime sourceLastWriteTime = DateTime.Parse(sourceLastWriteTimeAttribute.Value); //, CultureInfo.InvariantCulture: for globalization later           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DateTime destLastWriteTime = DateTime.Parse(destLastWriteTimeAttribute.Value);           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (sourceLastWriteTime &amp;lt; destLastWriteTime)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; proceed = false;           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;        &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public override string Name          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; get { return RULENAME; }           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;        &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public override string FriendlyName          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; get { return RULEFRIENDLYNAME; }           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;        &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public override string Description          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; get { return RULEDESCRIPTION; }           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;}&lt;/p&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Build this assembly as WDCustomRules.SkipNewerFilesUpdateRuleHandler.dll and GAC it as gacutil –i WDCustomRules.SkipNewerFilesUpdateRuleHandler.dll. For help on how to create a signed assembly &lt;a href="http://msdn.microsoft.com/en-us/library/ms247123.aspx"&gt;click here&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;Add the following information to the registry:      &lt;ol&gt;       &lt;li&gt;Add a key SkipNewerFilesUpdateRule under HKLM\Software\Microsoft\IIS Extensions\MSDeploy\1\Rules. This name does not have to be same as the assembly name. Any name that you think suits the purpose. &lt;/li&gt;        &lt;li&gt;To this key add two String values:          &lt;ol&gt;           &lt;li&gt;“&lt;u&gt;isdefault&lt;/u&gt;”. The value of this should be “true” or “false”. If this is true it will be applied to all verbs by default except dump. You can set it to false and enable the rule on the command line whenever you carry out a sync or migrate. &lt;/li&gt;            &lt;li&gt;“&lt;u&gt;type&lt;/u&gt;”. The value of this should be “CompleteAssemblyName, CompleteAssemblyName, Version=&amp;lt;version&amp;gt;, Culture=neutral, PublicKeyToken=&amp;lt;PublicKey&amp;gt;”. For example in this case it would be “WDCustomRules.SkipNewerFilesUpdateRuleHandler, WDCustomRules.SkipNewerFilesUpdateRuleHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8de34bc1deb35465”               &lt;br /&gt;Since the name of the assembly is WDCustomRules.SkipNewerFilesUpdateRuleHandler.dll &lt;/li&gt;         &lt;/ol&gt;       &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt;    &lt;li&gt;To verify that it does what I intend lets test it out. Create two folders test and test1 with the same content except that you have a file test.txt in test1 newer than the one in test folder. Lets run the command:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; msdeploy -verb:sync -source:contentPath=C:\test -dest:contentPath=C:\test1 –verbose &lt;/li&gt; &lt;/ol&gt;  &lt;blockquote&gt;   &lt;p&gt;Here’s the output:&lt;/p&gt;    &lt;p&gt;Informational:&amp;#160; Performing synchronization pass #1      &lt;br /&gt;Informational:&amp;#160; Destination filePath (c:\test1\test.txt) does not match source (C:\test\test.txt) differing in attributes (size['1271','1414'],lastWritTime['01/01/2009 22:07:46','03/03/2009 19:24:42']). Update pending       &lt;br /&gt;Informational:&amp;#160; Update operation on filePath (C:\test\test.txt) skipped due to rule SkipNewerFilesUpdateRule       &lt;br /&gt;Informational:&amp;#160; Synchronization completed in 1 passes       &lt;br /&gt;Change count: 0&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=2980528" width="1" height="1"&gt;</content><author><name>moshaikh</name><uri>http://blogs.iis.net/members/moshaikh.aspx</uri></author></entry></feed>