<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Strobaek Blog</title>
	<atom:link href="http://blog.strobaek.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.strobaek.org</link>
	<description>Karsten Strøbæk&#039;s blog about current projects, code and life in general</description>
	<lastBuildDate>Fri, 30 Dec 2011 18:33:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Merry Christmas</title>
		<link>http://blog.strobaek.org/2011/12/30/merry-christmas-3/</link>
		<comments>http://blog.strobaek.org/2011/12/30/merry-christmas-3/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 18:33:06 +0000</pubDate>
		<dc:creator>strobaek</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[X-mas]]></category>

		<guid isPermaLink="false">http://blog.strobaek.org/?p=744</guid>
		<description><![CDATA[Dear Friends and Family, The best wishes for the holiday season and the new year.]]></description>
			<content:encoded><![CDATA[<p>Dear Friends and Family,</p>
<p>The best wishes for the holiday season and the new year.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strobaek.org/2011/12/30/merry-christmas-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More on TFS and xUnit</title>
		<link>http://blog.strobaek.org/2011/10/18/more-on-tfs-and-xunit/</link>
		<comments>http://blog.strobaek.org/2011/10/18/more-on-tfs-and-xunit/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 07:30:30 +0000</pubDate>
		<dc:creator>strobaek</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[UnitTest]]></category>
		<category><![CDATA[TFS]]></category>
		<category><![CDATA[xUnit]]></category>

		<guid isPermaLink="false">http://blog.strobaek.org/?p=727</guid>
		<description><![CDATA[In my previous post on TFS and xUnit I tried to describe how to get the unit testing framework xUnit to work with TFS. I have got a couple of comments about not being able to get things to work. Unfortunately I have not had time to dive deep into why this may be so. It [...]]]></description>
			<content:encoded><![CDATA[<p>In my previous <a href="http://blog.strobaek.org/2011/10/03/howto-team-foundation-server-and-xunit/">post </a>on TFS and xUnit I tried to describe how to get the unit testing framework <a href="http://xunit.codeplex.com/">xUnit</a> to work with TFS.</p>
<p>I have got a couple of comments about not being able to get things to work. Unfortunately I have not had time to dive deep into why this may be so. It may well be because the description is flawed, for which I apologize.</p>
<p>A few observations:</p>
<ul>
<li>Concerning <a href="http://nunit4teambuild.codeplex.com/">NUnitTFS</a>: apart from different arguments, it also seems like the functionality is different. Using the newest version I get the following error:<a href="http://blog.strobaek.org/wp-content/uploads/xunit2-01a.jpg"><img class="aligncenter size-medium wp-image-733" title="xunit2-01a" src="http://blog.strobaek.org/wp-content/uploads/xunit2-01a-300x95.jpg" alt="" width="300" height="95" /></a>
<p>However, using a previous (alpha) version all works as expected:</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit2-03.jpg"><img class="aligncenter size-medium wp-image-731" title="xunit2-03" src="http://blog.strobaek.org/wp-content/uploads/xunit2-03-300x93.jpg" alt="" width="300" height="93" /></a></li>
<li>If you forget to define the endpoints in the <em>NUnitTfs.exe.config</em>-file you will get an error similar to the following:<a href="http://blog.strobaek.org/wp-content/uploads/xunit2-02.jpg"><img class="aligncenter size-medium wp-image-730" title="xunit2-02" src="http://blog.strobaek.org/wp-content/uploads/xunit2-02-300x80.jpg" alt="" width="300" height="80" /></a></li>
<li>Download the <a title="TFS Template XAML-file" href="http://blog.strobaek.org/wp-content/uploads/XUnitBuildProcessTemplate.xaml">xaml </a>and <a title="NUnitTFS" href="http://blog.strobaek.org/wp-content/uploads/NUnitTfs.zip">NUnitTFS </a>I have used and try it out.</li>
</ul>
<p>&nbsp;</p>
<p>Using the <em>InvokeProcess</em> component (from the Toolbar) it should be possible to integrate any external tool into the workflow.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strobaek.org/2011/10/18/more-on-tfs-and-xunit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HowTo: Team Foundation Server and xUnit</title>
		<link>http://blog.strobaek.org/2011/10/03/howto-team-foundation-server-and-xunit/</link>
		<comments>http://blog.strobaek.org/2011/10/03/howto-team-foundation-server-and-xunit/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 10:29:39 +0000</pubDate>
		<dc:creator>strobaek</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[UnitTest]]></category>
		<category><![CDATA[TFS]]></category>
		<category><![CDATA[xUnit]]></category>

		<guid isPermaLink="false">http://blog.strobaek.org/?p=678</guid>
		<description><![CDATA[For quite some time I have been doing TDD and Continuous Integration (CI), both in my private projects as well as my professional ones. My preferred unit testing framework is xUnit and I recently had to set this up with Team Foundation Server (TFS) to do CI. It turned out this was not a trivial task. [...]]]></description>
			<content:encoded><![CDATA[<p>For quite some time I have been doing TDD and Continuous Integration (CI), both in my private projects as well as my professional ones. My preferred unit testing framework is xUnit and I recently had to set this up with Team Foundation Server (TFS) to do CI. It turned out this was not a trivial task. One think was to get TFS to run the tests, another was to get TFS Reporting to work and show the test results. This blog post will show the different steps I took. I hope it will be an inspiration to others and help them avoid some of the issues and fustrations I ran into. Any comments or feedback will be greatly appreciated.</p>
<p>First step is to install TFS 2010. The following will describe how to install it on Windows Server 2008 and SQL Server 2008. However, the steps are the same for Windows Server 2008R2 and SQL Server 2008 R2.</p>
<p>I will not go into great details of how to install the server products. There are already great guides available on the web, so please drop me a mail og reach me on twitter if you require assistance with this part of the process.</p>
<p>Install Windows Server 2008 (Enterprise) on a server and apply Service Pack 2 (SP2).</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit01.jpg"><img class="aligncenter size-medium wp-image-681" title="xunit01" src="http://blog.strobaek.org/wp-content/uploads/xunit01-300x226.jpg" alt="" width="300" height="226" /></a></p>
<p>Create a User named, e.g. TFS and add this user to the Administrators group.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit02.jpg"><img class="aligncenter size-medium wp-image-682" title="xunit02" src="http://blog.strobaek.org/wp-content/uploads/xunit02-300x241.jpg" alt="" width="300" height="241" /></a></p>
<p>Install SQL Server 2008 (Enterprise Edition) with all components. I’ve also selected to install the <em>Business Intelligence Development Studio</em>, which will allow me to create TFS Reports.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit03.jpg"><img class="aligncenter size-medium wp-image-683" title="xunit03" src="http://blog.strobaek.org/wp-content/uploads/xunit03-300x224.jpg" alt="" width="300" height="224" /></a></p>
<p>Install Reporting Services in Native mode, but select the option of NOT configuring the Reporting Services now. Do not install it in SharePoint Integrated mode.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit04.jpg"><img class="aligncenter size-medium wp-image-684" title="xunit04" src="http://blog.strobaek.org/wp-content/uploads/xunit04-300x224.jpg" alt="" width="300" height="224" /></a></p>
<p>Add the TFS user as Login to the SQL Server just installed.</p>
<p>Install WSS (Windows Sharepoint Services) 3.0 and Service Pack 2. Do not run the <em>Configuration Wizard</em> at the end.</p>
<p>At this point you should be able to see the default SharePoint site at <a href="http://localhost">http://localhost</a>.</p>
<p>Open the <em>SQL Server Reporting Services Configuration Tool</em> and configure the Reporting Services now.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit05.jpg"><img class="aligncenter size-medium wp-image-685" title="xunit05" src="http://blog.strobaek.org/wp-content/uploads/xunit05-238x300.jpg" alt="" width="238" height="300" /></a></p>
<p>The tool will take you through the configuration step by step and will allow you to specify User, Create database etc. When asked for user credentials specify the User created earlier.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit06.jpg"><img class="aligncenter size-medium wp-image-686" title="xunit06" src="http://blog.strobaek.org/wp-content/uploads/xunit06-209x300.jpg" alt="" width="209" height="300" /></a></p>
<p>When configuring the <em>Database </em>keep the default setting to <em>Native Mode </em>when asked for <em>Report Server Mode.</em></p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit07.jpg"><img class="aligncenter size-medium wp-image-687" title="xunit07" src="http://blog.strobaek.org/wp-content/uploads/xunit07-300x112.jpg" alt="" width="300" height="112" /></a>When the configuration has completed it should be possible to see the Reporting Service Portal and Web Service, e.g.  on <a href="http://localhost/Reports">http://localhost/Reports</a> and <a href="http://localhost/ReportServer">http://localhost/ReportServer</a>.</p>
<p>Now it is time to install TFS. Initiate the installation and select the features you wish to install, most likely all but the Team Foundation Server Proxy.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit08.jpg"><img class="aligncenter size-medium wp-image-688" title="xunit08" src="http://blog.strobaek.org/wp-content/uploads/xunit08-300x148.jpg" alt="" width="300" height="148" /></a></p>
<p>You properly need to restart the server during the installation – after all this is Microsoft – but otherwise the installation should run smoothly.</p>
<p>Once done, press the <em>Configure </em>buton, to launch the Configuration Tool. Select the configuration appropriate to your needs. I selected the <em>Standard </em>configuration for this lab.</p>
<p>When asked for the Service Account, enter the user you created previously.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit09.jpg"><img class="aligncenter size-medium wp-image-689" title="xunit09" src="http://blog.strobaek.org/wp-content/uploads/xunit09-300x37.jpg" alt="" width="300" height="37" /></a></p>
<p>If you are not able to pass all the verification checks, just correct then and re-run the verification. Once all is green, you should be able to complete the configuration.</p>
<p>If you want to read more about TFS, check out the blog posts by <a href="http://www.richard-banks.org/2010/07/how-to-versioning-builds-with-tfs-2010.html" target="_blank">Richard Banks</a> and <a href="http://www.ewaldhofman.nl/post/2010/04/20/Customize-Team-Build-2010-e28093-Part-1-Introduction.aspx" target="_blank">Ewald Hofman</a>.</p>
<p>You now have a running TFS, but we are far from finished. To finish what we set out to do we now have to create and modify a build configuration.</p>
<p>A disclaimer: the following example will have some hardcoded values. The correct way to do things would be to create a <em>custom action</em>, put it in TFS and refer this, but this I will leave<br />
for another post.</p>
<p>In order to run our unit tests using xUnit and publish the results, we need to copy to items to the TFS server: <a href="http://xunit.codeplex.com/" target="_blank">xUnit </a>and <a href="http://nunit4teambuild.codeplex.com/" target="_blank">NUnitTFS</a>.</p>
<p>I placed then in C:\Tools\. Do not put any spaces in the folder names; this will make your life easier later on.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit10b.jpg"><img class="aligncenter size-full wp-image-722" title="xunit10b" src="http://blog.strobaek.org/wp-content/uploads/xunit10b.jpg" alt="" width="254" height="57" /></a></p>
<p>A little tweaking is most likely required of the configuration of NUnit. You need to ensure that the client endpoints are set correctly in the config-file. By default they point to http://teamfoundation.</p>
<p>First step is to create a copy of the <em>DefaultTemplate.xaml</em> file, rename it to something – I called mine <em>xUnitTemplate.xaml</em> – and add it to TFS.</p>
<p>Open the new template in Visual Studio.</p>
<p>We need two arguments, one for the path to the xUnit console and one for the path to the NUnitTFS.exe.</p>
<p>Select <em>Arguments </em>and click <em>Create Argument.</em></p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit11.jpg"><img class="aligncenter size-medium wp-image-691" title="xunit11" src="http://blog.strobaek.org/wp-content/uploads/xunit11-300x69.jpg" alt="" width="300" height="69" /></a></p>
<p>Create the two arguments: <em>xUnit</em> and <em>TFSPublish</em>.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit12.jpg"><img class="aligncenter size-medium wp-image-692" title="xunit12" src="http://blog.strobaek.org/wp-content/uploads/xunit12-300x18.jpg" alt="" width="300" height="18" /></a></p>
<p>Click the <em>Arguments </em>to close the list.</p>
<p>Select <em>Variables </em>and create one called <em>XUnitResult</em>. This will contain the output from one of the new processes we create.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit13.jpg"><img class="aligncenter size-medium wp-image-693" title="xunit13" src="http://blog.strobaek.org/wp-content/uploads/xunit13-300x33.jpg" alt="" width="300" height="33" /></a></p>
<p>Note the <em>Variable Type </em>and <em>Scope</em>.</p>
<p>Now scroll down into the processes and locate the <em>If Statement</em> called <em>If Not Disable Tests</em> and the <em>Sequence </em>called <em>Run Tests</em>.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit14.jpg"><img class="aligncenter size-medium wp-image-694" title="xunit14" src="http://blog.strobaek.org/wp-content/uploads/xunit14-300x71.jpg" alt="" width="300" height="71" /></a></p>
<p>We want to delete the content of the <em>Run Tests</em> sequence and enter our own. Easiest way to do this is right click on <em>Run Tests</em> and select <em>Delete.</em> This will leave you with something like the following</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit15.jpg"><img class="aligncenter size-medium wp-image-695" title="xunit15" src="http://blog.strobaek.org/wp-content/uploads/xunit15-300x141.jpg" alt="" width="300" height="141" /></a></p>
<p>Now from the Toolbox find the Sequence (located under Control Flow) and drop one on the <em>Then </em>box. Rename it to <em>Run Tests</em>.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit16.jpg"><img class="aligncenter size-medium wp-image-696" title="xunit16" src="http://blog.strobaek.org/wp-content/uploads/xunit16-300x138.jpg" alt="" width="300" height="138" /></a></p>
<p>Add an Invoke Process to the Sequence and name it <em>Invoke xUnit Console</em>.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit17.jpg"><img class="aligncenter size-full wp-image-697" title="xunit17" src="http://blog.strobaek.org/wp-content/uploads/xunit17.jpg" alt="" width="239" height="279" /></a></p>
<p>The reason for the red exclamation marks is that we need to configure the new control. Open the properties and set the following:</p>
<ul>
<li>Arguments: &#8220;xUnit.Test.dll /silent /nunit results.xml&#8221; (including quotes)</li>
<li>FileName: xUnit</li>
<li>Result: XUnitResult</li>
<li>WorkingDirectory: outputDirectory</li>
</ul>
<p>As you can see we here have a hard coded value, namely the name of the assembly containing the unit tests. “It can be easily seen” as we used to say at University, when the math proof was too easy, so I will leave this as a small home assignment to you, my dear reader <img src='http://blog.strobaek.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>You also want to add two activities to output the build messages and build errors (if any).</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit18.jpg"><img class="aligncenter size-medium wp-image-698" title="xunit18" src="http://blog.strobaek.org/wp-content/uploads/xunit18-300x143.jpg" alt="" width="300" height="143" /></a></p>
<p>In the properties, set the <em>Message</em> to <em>stdOutput</em> and <em>errOutput</em> respectively.</p>
<p>We are almost done. Add a second <em>Invoke Process</em> under the newly created and name it e.g. <em>Publish xUnit Results</em>.</p>
<p>Set the <em>Argument to the following:</em></p>
<p>String.Format(&#8220;-n {0} -t {1} -p &#8221;"{2}&#8221;" -f {3} -b &#8220;&#8221;{4}&#8221;" &#8220;,<br />
&#8220;results.xml&#8221;,<br />
BuildDetail.TeamProject,<br />
BuildSettings.PlatformConfigurations(0).Platform,<br />
BuildSettings.PlatformConfigurations(0).Configuration,<br />
BuildDetail.BuildNumber)</p>
<p>And the <em>FileName </em>to <em>TFSPublish</em>  and <em>WorkingDirectory </em>to <em>outputDirectory</em> and lastly add two output handlers as above.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit19.jpg"><img class="aligncenter size-full wp-image-699" title="xunit19" src="http://blog.strobaek.org/wp-content/uploads/xunit19.jpg" alt="" width="246" height="215" /></a></p>
<p>Save the template and check it in.</p>
<p>Next step is to create a new build definition that uses the new template.</p>
<p>Open the Team Explorer, right click on <em>Builds</em> and select <em>New Build Definition</em>.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit20.jpg"><img class="aligncenter size-medium wp-image-700" title="xunit20" src="http://blog.strobaek.org/wp-content/uploads/xunit20-300x210.jpg" alt="" width="300" height="210" /></a></p>
<p>Set the name to something meaningful</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit21.jpg"><img class="aligncenter size-medium wp-image-701" title="xunit21" src="http://blog.strobaek.org/wp-content/uploads/xunit21-300x64.jpg" alt="" width="300" height="64" /></a></p>
<p>And the Trigger to <em>Continuous Integration</em></p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit22.jpg"><img class="aligncenter size-medium wp-image-702" title="xunit22" src="http://blog.strobaek.org/wp-content/uploads/xunit22-300x65.jpg" alt="" width="300" height="65" /></a></p>
<p>In Workspace, ensure that the folders you wish to include are active. Here we only got one.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit23.jpg"><img class="aligncenter size-medium wp-image-703" title="xunit23" src="http://blog.strobaek.org/wp-content/uploads/xunit23-300x50.jpg" alt="" width="300" height="50" /></a></p>
<p>Under Build Defaults set the <em>Build controller</em> and the <em>drop  folder</em>. For this test I have just shared a drive on my TFS server.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit24.jpg"><img class="aligncenter size-medium wp-image-704" title="xunit24" src="http://blog.strobaek.org/wp-content/uploads/xunit24-300x125.jpg" alt="" width="300" height="125" /></a></p>
<p>Under Process we need to set the <em>Build process template</em>. Click on <em>Show Details</em> to expand the panel.</p>
<p>Click on <em>New</em> to  set the new template we have created earlier.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit25.jpg"><img class="aligncenter size-medium wp-image-705" title="xunit25" src="http://blog.strobaek.org/wp-content/uploads/xunit25-300x63.jpg" alt="" width="300" height="63" /></a></p>
<p>Select the <em>Select an  existing XAML file</em> and click on <em>Browse…</em></p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit26.jpg"><img class="aligncenter size-medium wp-image-706" title="xunit26" src="http://blog.strobaek.org/wp-content/uploads/xunit26-277x300.jpg" alt="" width="277" height="300" /></a></p>
<p>Select the template we just created and press <em>OK</em>.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit27.jpg"><img class="aligncenter size-medium wp-image-707" title="xunit27" src="http://blog.strobaek.org/wp-content/uploads/xunit27-300x152.jpg" alt="" width="300" height="152" /></a></p>
<p>Press <em>OK</em> again to  get back to the initial screen (still under Process).</p>
<p>Under <em>4. Misc</em> you  should see the two arguments we created. Enter the values as shown below. <em></em></p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit28a.jpg"><img class="aligncenter size-medium wp-image-723" title="xunit28a" src="http://blog.strobaek.org/wp-content/uploads/xunit28a-300x38.jpg" alt="" width="300" height="38" /></a></p>
<p>If you are still seeing a yellow exclamation mark, it may be because you have to set the <em>Configurations to build</em> under <em>1. Required | Items to Build</em>.</p>
<p>To test that this is actually working, create a solution and  add a class library to hold your unit tests. Remember to name the library  xUnit.Test (or rather ensure that the assembly is named xUnit.Test.dll).</p>
<p>When you check in the test, the new build should commence.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit29.jpg"><img class="aligncenter size-medium wp-image-709" title="xunit29" src="http://blog.strobaek.org/wp-content/uploads/xunit29-300x130.jpg" alt="" width="300" height="130" /></a></p>
<p>And when done the result is shown:</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit30.jpg"><img class="aligncenter size-medium wp-image-710" title="xunit30" src="http://blog.strobaek.org/wp-content/uploads/xunit30-300x158.jpg" alt="" width="300" height="158" /></a></p>
<p>I made two small tests: one that would pass and one that would  not.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit31.jpg"><img class="aligncenter size-medium wp-image-711" title="xunit31" src="http://blog.strobaek.org/wp-content/uploads/xunit31-300x150.jpg" alt="" width="300" height="150" /></a></p>
<p>If you create a TFS report looking at the test runs (using ReportBuilder), you can see something like the following:</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/xunit32.jpg"><img class="aligncenter size-medium wp-image-712" title="xunit32" src="http://blog.strobaek.org/wp-content/uploads/xunit32-300x97.jpg" alt="" width="300" height="97" /></a></p>
<p>We are done!</p>
<p>A few things to note:</p>
<ul>
<li>To get TFS to compile and run the tests using xUnit, I create a solution folder (e.g. called <em>Lib)</em> on the same level as my projects and add all the xUnit files to this folder. I then reference <em>xunit.dll</em> from this folder.</li>
<li>NUnitTFS seems to have changed from  the Alpha version, where it was possible to give an argument “-v”. This is not  longer possible with newer versions.</li>
<li>Be sure that the process running the build has access to the drop location.</li>
</ul>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strobaek.org/2011/10/03/howto-team-foundation-server-and-xunit/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Dependency Injection in .NET by Mark Seemann</title>
		<link>http://blog.strobaek.org/2011/09/26/dependency-injection-in-net-by-mark-seemann/</link>
		<comments>http://blog.strobaek.org/2011/09/26/dependency-injection-in-net-by-mark-seemann/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 06:05:16 +0000</pubDate>
		<dc:creator>strobaek</dc:creator>
				<category><![CDATA[Writing]]></category>
		<category><![CDATA[Books]]></category>

		<guid isPermaLink="false">http://blog.strobaek.org/2011/09/26/dependency-injection-in-net-by-mark-seemann/</guid>
		<description><![CDATA[Yesterday I received the eBook of Dependency Injection in .NET, written by my good friend Mark aka @ploeh. I had the pleasure of serving as technical proofreader during production, hence the early edition. If you have not already read it through the MEAP program, you are in for a treat. No matter if you are [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I received the eBook of Dependency Injection in .NET, written by my good friend <a href="http://blog.ploeh.dk" target="_blank">Mark</a> aka <a href="http://twitter.com/ploeh" target="_blank">@ploeh</a>. I had the pleasure of serving as technical proofreader during production, hence the early edition.</p>
<p>If you have not already read it through the MEAP program, you are in for a treat. No matter if you are new to DI or an old rat this book will enlighten you, show you when and when not to use DI, the pit-falls, the tricks, basically everything you need to know to get started or continue your quest.</p>
<p>The book is very rich on extensive examples, not just the often used <em>Hello World-</em>kind<em>, </em>which does not really cut in the real world.</p>
<p>The official <a href="http://www.manning.com/DependencyInjectionin.NET" target="_blank">web site</a> should be up shortly.</p>
<p>When the printed copy comes out, I will look forward to sit in my favorite chair in my library, with a good cup of coffee and a signed copy – right, Mark? :) – and read it again.</p>
<p>Table of Contents:</p>
<p>Part 1 – Putting Dependency Injection on the map</p>
<ul>
<li><span style="background-color: #ffffff;">A Dependency Injection tasting menu</span></li>
<li>A comprehensive example</li>
<li>DI Containers</li>
</ul>
<p>Part 2 – DI catalog</p>
<ul>
<li>DI patterns</li>
<li>DI anti-patterns</li>
<li>DI refactorings</li>
</ul>
<p>Part 3 – DIY DI</p>
<ul>
<li>Object Composition</li>
<li>Object Lifetime</li>
<li>Interception</li>
</ul>
<p>Part 4 – DI Containers</p>
<ul>
<li>Castle Windsor</li>
<li>StructureMap</li>
<li>String.NET</li>
<li>Autofac</li>
<li>Unity</li>
<li>MEF</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.strobaek.org/2011/09/26/dependency-injection-in-net-by-mark-seemann/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>HowTo: Install a SQL failover cluster (in a virtual lab environment)</title>
		<link>http://blog.strobaek.org/2011/09/22/howto-install-a-sql-failover-cluster-in-a-virtual-lab-environment/</link>
		<comments>http://blog.strobaek.org/2011/09/22/howto-install-a-sql-failover-cluster-in-a-virtual-lab-environment/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 10:52:06 +0000</pubDate>
		<dc:creator>strobaek</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://blog.strobaek.org/?p=628</guid>
		<description><![CDATA[I have a couple of times had to set up a SQL Server cluster, both at clients and in my own lab. At clients the underlying Windows cluster setup is often handled by their own infrastructure people, so this is seldom a problem &#8211; if we assume they know what they are doing, which I grant, [...]]]></description>
			<content:encoded><![CDATA[<p>I have a couple of times had to set up a SQL Server cluster, both at clients and in my own lab. At clients the underlying Windows cluster setup is often handled by their own infrastructure people, so this is seldom a problem &#8211; if we assume they know what they are doing, which I grant, is not always the case. However, as I don’t have an ops person standing around behind glass, to be called upon when I need her – it should of course be a her – I need to do it myself (reminds me of a saying I once heard: it is cheaper to do it yourself, but it is a lot more fun with someone else. Can’t remember what it was about …)</p>
<p>This blog post will describe the different steps required to create a small SQL Cluster with two nodes. The following is assumed:</p>
<ul>
<li>You have a domain controller. Mine is running Windows Server 2008, but you can use an earlier version if you wish to have a small footprint.</li>
<li>You have installed Windows Server 2008 R2 on three servers. Two will be used for the cluster nodes and one as shared storage. All three servers have been joined to the domain and preferable been given a static IP-address.</li>
</ul>
<p>Until Windows 8 I am running my lab using <a href="http://www.virtualbox.org/" target="_blank">VirtualBox</a> from Oracle. This allows me to run 64-bit virtual machines on my Windows 7 laptop, without having to boot into WS2008.</p>
<p>In summary we will construct the following:</p>
<ul>
<li>Two SQL2008R2 nodes running on WS2008R2</li>
<li>One WS2008R2 server used as shared storage.</li>
</ul>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-1.jpg"><img class="aligncenter size-medium wp-image-632" title="cluster 1" src="http://blog.strobaek.org/wp-content/uploads/cluster-1-236x300.jpg" alt="" width="236" height="300" /></a></p>
<p>&nbsp;</p>
<p>First thing to do is to create a Windows cluster. I use iSCSI and install the <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=45105d7f-8c6c-4666-a305-c8189062a0d0" target="_blank">Microsoft iSCSI Software Target 3.3</a> on the storage box. There are other options. The important thing is, that you cannot create a SQL cluster, if the nodes are not able to see the same disk.</p>
<p>Run the install to unpack the files. This will open a web-page (index.htm). Select <em>Install</em>.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-2.jpg"><img class="aligncenter size-medium wp-image-633" title="cluster 2" src="http://blog.strobaek.org/wp-content/uploads/cluster-2-300x169.jpg" alt="" width="300" height="169" /></a></p>
<p>&nbsp;</p>
<p>Accept all the default values and the install is completed swiftly.</p>
<p>Start the Microsoft iSCSI Software Target console.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-3.jpg"><img class="aligncenter size-full wp-image-634" title="cluster 3" src="http://blog.strobaek.org/wp-content/uploads/cluster-3.jpg" alt="" width="260" height="189" /></a></p>
<p>Select the iSCSI Target node, right click and select <em>Create iSCSI Target</em>.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-4.jpg"><img class="aligncenter size-medium wp-image-635" title="cluster 4" src="http://blog.strobaek.org/wp-content/uploads/cluster-4-288x300.jpg" alt="" width="288" height="300" /></a></p>
<p>Enter a name for the iSCSI target and alternatively a description. Note, that the name cannot contain spaces.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-5.jpg"><img class="aligncenter size-medium wp-image-636" title="cluster 5" src="http://blog.strobaek.org/wp-content/uploads/cluster-5-300x122.jpg" alt="" width="300" height="122" /></a></p>
<p>In the iSCSI Initiators Identifiers dialog, press the <em>Advanced</em> button.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-6.jpg"><img class="aligncenter size-medium wp-image-637" title="cluster 6" src="http://blog.strobaek.org/wp-content/uploads/cluster-6-300x229.jpg" alt="" width="300" height="229" /></a></p>
<p>Enter the IP-address of the two nodes on which the SQL cluster will be installed.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-7.jpg"><img class="aligncenter size-medium wp-image-638" title="cluster 7" src="http://blog.strobaek.org/wp-content/uploads/cluster-7-300x127.jpg" alt="" width="300" height="127" /></a></p>
<p>Finish the target setup.</p>
<p>Right click the newly created iSCSI Target and select <em>Create Virtual Disk for iSCSI Target</em>.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-8.jpg"><img class="aligncenter size-medium wp-image-639" title="cluster 8" src="http://blog.strobaek.org/wp-content/uploads/cluster-8-300x182.jpg" alt="" width="300" height="182" /></a></p>
<p>Set location and size of virtual disk and finish the wizard. Upon completion you should see the newly created vdisk under the iSCSI target.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-9.jpg"><img class="aligncenter size-medium wp-image-640" title="cluster 9" src="http://blog.strobaek.org/wp-content/uploads/cluster-9-300x62.jpg" alt="" width="300" height="62" /></a></p>
<p>&nbsp;</p>
<p>Next step is to connect the just created storage with the two cluster nodes.</p>
<p>On one of the nodes, open the Control Panel and select <em>iSCSI Initiator</em>.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-10.jpg"><img class="aligncenter size-full wp-image-641" title="cluster 10" src="http://blog.strobaek.org/wp-content/uploads/cluster-10.jpg" alt="" width="296" height="114" /></a></p>
<p>If you see the following dialog</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-11.jpg"><img class="aligncenter size-medium wp-image-642" title="cluster 11" src="http://blog.strobaek.org/wp-content/uploads/cluster-11-300x119.jpg" alt="" width="300" height="119" /></a></p>
<p>just select Yes.</p>
<p>Enter the IP-address of the Storage box and press <em>Quick Connect</em>.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-12.jpg"><img class="aligncenter size-medium wp-image-643" title="cluster 12" src="http://blog.strobaek.org/wp-content/uploads/cluster-12-300x154.jpg" alt="" width="300" height="154" /></a></p>
<p>You should now see the storage server under Discovered targets.</p>
<p>Go to the <em>Volumes and Devices</em> tab a press <em>Auto Configure</em>.</p>
<p>You should now see an entry under Volume List.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-13.jpg"><img class="aligncenter size-medium wp-image-644" title="cluster 13" src="http://blog.strobaek.org/wp-content/uploads/cluster-13-300x247.jpg" alt="" width="300" height="247" /></a></p>
<p>Click OK to close the iSCSI configuration.</p>
<p>Go to the second node and repeat the above steps.</p>
<p>Open the Server Manager and go to Storage and Disk Management. You should see the disk here.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-14.jpg"><img class="aligncenter size-medium wp-image-645" title="cluster 14" src="http://blog.strobaek.org/wp-content/uploads/cluster-14-300x63.jpg" alt="" width="300" height="63" /></a></p>
<p>Now go back to the first node, set the disk online and initialize it. This step will ensure that the disk is visible in the Cluster Manager when assigning disks.</p>
<p>We now have the foundation to setup a Windows Cluster. Next step is to enable clustering on both nodes. Start the Server Manager on each node, select Features and Add Feature.</p>
<p>Check the <em>Failvoer Clustering</em> click Next and complete the setup.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-15.jpg"><img class="aligncenter size-medium wp-image-646" title="cluster 15" src="http://blog.strobaek.org/wp-content/uploads/cluster-15-238x300.jpg" alt="" width="238" height="300" /></a></p>
<p>On one of the nodes go to Start -&gt; All Programs -&gt; Administrative Tools and select <em>Failover Cluster Manager</em>.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-16.jpg"><img class="aligncenter size-full wp-image-647" title="cluster 16" src="http://blog.strobaek.org/wp-content/uploads/cluster-16.jpg" alt="" width="251" height="152" /></a></p>
<p>Select <em>Create a Cluster</em> in the middle of the page.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-17.jpg"><img class="aligncenter size-full wp-image-648" title="cluster 17" src="http://blog.strobaek.org/wp-content/uploads/cluster-17.jpg" alt="" width="287" height="48" /></a></p>
<p>Add the two nodes to the list of servers that should be included in the cluster.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-18.jpg"><img class="aligncenter size-medium wp-image-649" title="cluster 18" src="http://blog.strobaek.org/wp-content/uploads/cluster-18-300x108.jpg" alt="" width="300" height="108" /></a></p>
<p>In the next step one can run a verification report. It will take some time to complete the report, but I recommend that it is done to avoid any needless frustration later on.</p>
<p>Give the cluster a name and an IP address.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-19.jpg"><img class="aligncenter size-medium wp-image-650" title="cluster 19" src="http://blog.strobaek.org/wp-content/uploads/cluster-19-300x136.jpg" alt="" width="300" height="136" /></a></p>
<p>Press Next and finish the setup.</p>
<p>To complete the setup the disk from before needs to be allocated or assigned to the cluster. Select Storage in the tree to the left and click <em>Add a disk</em> to the right.</p>
<p>This should display something similar to the following:</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-20.jpg"><img class="aligncenter size-medium wp-image-651" title="cluster 20" src="http://blog.strobaek.org/wp-content/uploads/cluster-20-300x88.jpg" alt="" width="300" height="88" /></a></p>
<p>&nbsp;</p>
<p>Press OK to continue.</p>
<p>So far so good. We now have the foundation on which we can install SQL Server.</p>
<p>SQL Sever 2008 R2 requires the .NET Framework 3.5. If you have not already done so, add it to your servers using the Server Manage and Add Feature.</p>
<p>On the node that “owns” the shared disk, run the installation. I know that it is not really correct to talk about ownership as it is the service that owns the resource and not the node itself, but I think you get the picture.</p>
<p>From the Installation Center, select Installation and then the second option <em>New SQL Server failover cluster installation</em>. The third option will be used to add node(s) to the cluster, once it has been set up.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-21.jpg"><img class="aligncenter size-medium wp-image-652" title="cluster 21" src="http://blog.strobaek.org/wp-content/uploads/cluster-21-300x74.jpg" alt="" width="300" height="74" /></a></p>
<p>Continue through the dialogs until the Setup Support files are installed. Once this has completed a “report” is run to identify any issues. There should be no Red Lights, and only Yellow of no importance or  that can be rectified later, e.g. the network binding order.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-22.jpg"><img class="aligncenter size-medium wp-image-653" title="cluster 22" src="http://blog.strobaek.org/wp-content/uploads/cluster-22-300x258.jpg" alt="" width="300" height="258" /></a></p>
<p>On the Feature Selection page, select the features that should be installed and press Next.</p>
<p>On the Instanced Configuration page, a <em>SQL Server Network Name</em> must be specified. This is the “virtual” name applications will use to connect to.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-23.jpg"><img class="aligncenter size-medium wp-image-654" title="cluster 23" src="http://blog.strobaek.org/wp-content/uploads/cluster-23-300x45.jpg" alt="" width="300" height="45" /></a></p>
<p>Accept the default values for the <em>Cluster Resource Group</em> and the <em>Cluster Disk Selection</em>.</p>
<p>On the <em>Cluster Network Configuration</em> specify an IP-address.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-24.jpg"><img class="aligncenter size-medium wp-image-655" title="cluster 24" src="http://blog.strobaek.org/wp-content/uploads/cluster-24-300x50.jpg" alt="" width="300" height="50" /></a></p>
<p>Continue through the setup until the <em>Database Engine Configuration</em>.</p>
<p>Supply the information for the Account Provisioning. On the Data Directories tab it can be seen that the shared or clustered drive has been selected. If you had multiple disks in your cluster and had selected them in the Cluster Disk Selected step, it would here be possible to place the data one one disk and the logs on another. For this test-lab all is installed on the same disk.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-25.jpg"><img class="aligncenter size-medium wp-image-656" title="cluster 25" src="http://blog.strobaek.org/wp-content/uploads/cluster-25-300x127.jpg" alt="" width="300" height="127" /></a></p>
<p>Continue with the configuration and end by pressing the Install button.</p>
<p>At this point it would be a good idea to get a cup of coffee as the installation might take some time.</p>
<p>Eventually something like this should be displayed</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-26.jpg"><img class="aligncenter size-medium wp-image-657" title="cluster 26" src="http://blog.strobaek.org/wp-content/uploads/cluster-26-300x40.jpg" alt="" width="300" height="40" /></a></p>
<p>We have now configured and installed the first node in our failover SQL Cluster and we now just have to add the second node and we are done.</p>
<p>Start the install from the second node, select the Installation menu item, and as previous noted, select the third menu option <em>Add node to a SQL Server failover cluster</em>.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-27.jpg"><img class="aligncenter size-medium wp-image-658" title="cluster 27" src="http://blog.strobaek.org/wp-content/uploads/cluster-27-300x74.jpg" alt="" width="300" height="74" /></a></p>
<p>As before the installation process will begin by installing a number of setup files.</p>
<p>On the <em>Cluster Node Configuration</em> screen select the cluster to join.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-28.jpg"><img class="aligncenter size-medium wp-image-659" title="cluster 28" src="http://blog.strobaek.org/wp-content/uploads/cluster-28-300x86.jpg" alt="" width="300" height="86" /></a></p>
<p>Continue through the rest of the setup and press Install at the end.</p>
<p>If all goes well, the completion screen will be displayed.</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/cluster-29.jpg"><img class="aligncenter size-medium wp-image-660" title="cluster 29" src="http://blog.strobaek.org/wp-content/uploads/cluster-29-300x37.jpg" alt="" width="300" height="37" /></a></p>
<p>That’s it! We now have a two node SQL failover cluster.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strobaek.org/2011/09/22/howto-install-a-sql-failover-cluster-in-a-virtual-lab-environment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More on Grooming IIS Logs</title>
		<link>http://blog.strobaek.org/2011/09/09/more-on-grooming-iis-logs/</link>
		<comments>http://blog.strobaek.org/2011/09/09/more-on-grooming-iis-logs/#comments</comments>
		<pubDate>Fri, 09 Sep 2011 08:25:21 +0000</pubDate>
		<dc:creator>strobaek</dc:creator>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://blog.strobaek.org/?p=613</guid>
		<description><![CDATA[I previously blogged about how to delete blob entries older than a given date. I have extended the script slightly to first download entries, zip then and upload them again to another storage container, before actually doing the removal. Before the deletion is carried out a simple check of file size is performed to ensure [...]]]></description>
			<content:encoded><![CDATA[<p>I <a href="http://blog.strobaek.org/2011/08/17/grooming-windows-azure-diagnostics-storage-and-iis-logs/" target="_blank">previously</a> blogged about how to delete blob entries older than a given date.</p>
<p>I have extended the script slightly to first download entries, zip then and upload them again to another storage container, before actually doing the removal. Before the deletion is carried out a simple check of file size is performed to ensure the upload succeced.</p>
<p>The sequence is illustrated below:</p>
<p><a href="http://blog.strobaek.org/wp-content/uploads/groom-iis-logs.jpg"><img class="aligncenter size-medium wp-image-614" title="groom iis logs" src="http://blog.strobaek.org/wp-content/uploads/groom-iis-logs-300x202.jpg" alt="" width="420" height="291" /></a></p>
<p>And the script:</p>
<table width="520" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="518"><span style="font-family: courier new;"><strong><span style="font-size: x-small;">function FileIsLocked( [string] $filePath )<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">{<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">    $script:locked = $false<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">    $fileInfo = New-Object System.IO.FileInfo $filePath<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">    trap<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">    {<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">        # if we are in here, the file is locked<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">        $script:locked = $true<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">        continue<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">    }<br />
</span></strong></span><span><strong><span style="font-family: Courier New;"><span style="font-size: x-small;"><span>    $fileStream = $fileInfo.Open<br />
[System.IO.FileMode]::OpenOrCreate,<br />
[System.IO.FileAccess]::ReadWrite,<br />
[System.IO.FileShare]::None )</span> if ($fileStream)<br />
{<br />
$fileStream.Close()<br />
}<br />
</span></span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">    $script:locked<br />
</span></strong></span><strong><strong><span style="font-family: Courier New;"><span style="font-size: x-small;"><span>}</span></span></span></strong></strong># Name of your account</p>
<p><strong><strong><span style="font-family: Courier New;"><span style="font-size: x-small;"><span style="font-family: courier new;">$accountName = &lt;Account Name&gt;</span></span></span></strong></strong>&nbsp;</p>
<p><strong><span style="font-size: x-small;"><span style="font-family: courier new;"># Account key<br />
</span><span style="font-family: courier new;">$accountKey = &lt;Account Key&gt;<br />
</span></span></strong>&nbsp;</p>
<p><strong><span style="font-size: x-small;"><span style="font-family: courier new;"># Get current date on format YYYYMMDD, e.g. 20110906<br />
</span><span style="font-family: courier new;">$datePart = Get-Date -f &#8220;yyyyMMdd&#8221;</span></span></strong></p>
<p><strong><span style="font-size: x-small;"><span style="font-family: courier new;">#Location of where blob entries should be downloaded to<br />
</span><span style="font-family: courier new;">$downloadLocation = &#8220;C:Temp&#8221; + $datePart</span></span></strong></p>
<p><span style="font-family: courier new;"><strong><span style="font-size: x-small;"># Name of source and target storage container<br />
</span></strong></span><strong><span style="font-size: x-small;"><span style="font-family: courier new;">$containerName = &#8220;wad-iis-logfiles&#8221;<br />
</span><span style="font-family: courier new;">$targetContainerName = &#8220;backup&#8221;</span></span></strong></p>
<p><strong><span style="font-size: x-small;"><span style="font-family: courier new;"># Download and removed blob entries older than 90 days<br />
</span><span style="font-family: courier new;">$endTime = (get-date).adddays(-90)</span></span></strong></p>
<p><span style="font-family: courier new;"><strong><span style="font-size: x-small;"># Download blob entries<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">Write-Host &#8220;Export-BlobContainer”<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">Export-BlobContainer<br />
-Name $containerName<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">    -DownloadLocation $downloadLocation<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">    -MaximumBlobLastModifiedDateTime $endTime<br />
</span></strong></span><strong><span style="font-size: x-small;"><span style="font-family: courier new;">    -AccountName $accountName<br />
</span><span style="font-family: courier new;">    -AccountKey $accountKey</span></span></strong></p>
<p><span style="font-family: courier new;"><strong><span style="font-size: x-small;"># Zip files<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">Write-Host &#8220;Zip logfiles&#8221;<br />
</span></strong></span><strong><span style="font-size: x-small;"><span style="font-family: courier new;">$zipFileName = $downloadLocation + &#8220;IISLog&#8221; + $datePart + &#8220;.zip&#8221;<br />
</span><span style="font-family: courier new;">set-content $zipFileName (&#8220;PK&#8221; + [char]5 + [char]6 + (&#8220;$([char]0)&#8221; * 18))<br />
</span></span></strong><strong><span style="font-size: x-small;"><span style="font-family: courier new;">(dir $zipFileName).IsReadOnly = $false<br />
</span><span style="font-family: courier new;">$zipFile = (new-object -com shell.application).NameSpace($zipFileName) </span></span></strong><span style="font-family: courier new;"><br />
<strong><span style="font-size: x-small;">$zipFile.CopyHere($downloadLocation)</span></strong></span></p>
<p><span style="font-family: courier new;"><strong><span style="font-size: x-small;">Write-Host &#8220;Check if File is locked&#8221;<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">Start-Sleep -s 30<br />
</span></strong></span><strong><span style="font-size: x-small;"><span style="font-family: courier new;">$fileIsLocked = FileIsLocked $zipFileName<br />
</span><span style="font-family: courier new;">Write-Host $fileIsLocked</span></span></strong></p>
<p><span style="font-family: courier new;"><strong><span style="font-size: x-small;">while ($fileIsLocked)<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">{<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">    Write-Host &#8220;File Locked&#8221;<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">    Start-Sleep -s 30<br />
</span></strong></span><strong><span style="font-size: x-small;"><span style="font-family: courier new;">    $fileIsLocked = FileIsLocked $zipFileName<br />
</span><span style="font-family: courier new;">}</span></span></strong></p>
<p><span style="font-family: courier new;"><strong><span style="font-size: x-small;"># Upload zip-file<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">Write-Host &#8220;Import-File&#8221;<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">Import-File<br />
-File $zipFileName<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">    -BlobContainerName $targetContainerName<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">    -CompressBlob<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">    -LoggingLevel &#8220;Detailed&#8221;<br />
</span></strong></span><strong><span style="font-size: x-small;"><span style="font-family: courier new;">    -AccountName $accountName<br />
</span><span style="font-family: courier new;">    -AccountKey $accountKey</span></span></strong></p>
<p><span style="font-family: courier new;"><strong><span style="font-size: x-small;"># Check if upload went well by comparing file size<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">$ext = &#8220;zip&#8221;<br />
</span></strong></span><strong><span style="font-size: x-small;"><span style="font-family: courier new;">$timeTo = (Get-Date -f &#8220;yyyy-MM-dd&#8221;).ToString() + &#8221; 23:59:59&#8243;<br />
</span><span style="font-family: courier new;">$timeFrom = (Get-Date -f &#8220;yyyy-MM-dd&#8221;).ToString() + &#8221; 00:00:00&#8243;</span></span></strong></p>
<p><span style="font-family: courier new;"><strong><span style="font-size: x-small;">$bfc = New-Object Cerebrata.AzureUtilities.ManagementClient.StorageManagementEntities.BlobsFilterCriteria<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">$bfc.BlobNameEndsWith = $ext<br />
</span></strong></span><strong><span style="font-size: x-small;"><span style="font-family: courier new;">$bfc.LastModifiedDateTimeTo = $timeTo<br />
</span><span style="font-family: courier new;">$bfc.LastModifiedDateTimeFrom = $timeFrom </span></span></strong></p>
<p><span style="font-family: courier new;"><strong><span style="font-size: x-small;">$blobInfo = Get-Blob<br />
-BlobContainerName $targetContainerName<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">    -IncludeMetadata<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">    -BlobsFilterCriteria $bfc<br />
</span></strong></span><strong><span style="font-size: x-small;"><span style="font-family: courier new;">    -AccountName $accountName<br />
</span><span style="font-family: courier new;">    -AccountKey $accountKey</span></span></strong></p>
<p><span style="font-family: courier new;"><strong><span style="font-size: x-small;">$fileInfo = (New-Object IO.FileInfo &#8220;$zipFileName&#8221;)</span></strong></span></p>
<p><span style="font-family: courier new;"><strong><span style="font-size: x-small;">if ($blobInfo.Size -eq $fileInfo.Length)<br />
</span></strong></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;">{<br />
</span></strong></span><strong><span style="font-size: x-small;"><span style="font-family: courier new;">    # Delete downloaded files (and zip-file)<br />
</span><span style="font-family: courier new;">    Remove-Item -Recurse -Force $downloadLocation</span></span></strong></p>
<p><span style="font-family: courier new;"><span><strong><span style="font-size: x-small;">    # Remove downloaded blob entries<br />
</span></strong></span></span><span style="font-family: courier new;"><span><strong><span style="font-size: x-small;">    Remove-Blob<br />
-BlobContainerName $containerName<br />
</span></strong></span></span><span style="font-family: courier new;"><span><strong><span style="font-size: x-small;">        -BlobsFilterCriteria $bfc<br />
</span></strong></span></span><span style="font-family: courier new;"><span><strong><span style="font-size: x-small;">        -AccountName $accountName<br />
</span></strong></span></span><span style="font-family: courier new;"><strong><span style="font-size: x-small;"><span>        -AccountKey $accountKey<br />
</span><span>}</span></span></strong></span></td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://blog.strobaek.org/2011/09/09/more-on-grooming-iis-logs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Review of books: SOA patterns and PowerShell/WMI</title>
		<link>http://blog.strobaek.org/2011/08/29/review-of-books-soa-patterns-and-powershellwmi/</link>
		<comments>http://blog.strobaek.org/2011/08/29/review-of-books-soa-patterns-and-powershellwmi/#comments</comments>
		<pubDate>Mon, 29 Aug 2011 06:43:50 +0000</pubDate>
		<dc:creator>strobaek</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Books]]></category>

		<guid isPermaLink="false">http://blog.strobaek.org/?p=607</guid>
		<description><![CDATA[I have recently read two manuscripts from Manning: SOA patterns by Rotem et all and PowerShell and WMI by Siddaway. None of them are published yet, but both are available through Mannings MEA program. Like I have done previously I will try to write up a small review of each, but right now I do [...]]]></description>
			<content:encoded><![CDATA[<p>I have recently read two manuscripts from Manning: <a title="SOA Patterns" href="http://www.manning.com/rotem/" target="_blank">SOA patterns</a> by Rotem et all and <a title="PowerShell and WMI" href="http://www.manning.com/siddaway2/" target="_blank">PowerShell and WMI</a> by Siddaway. None of them are published yet, but both are available through Mannings MEA program.</p>
<p>Like I have done previously I will try to write up a small review of each, but right now I do not have the bandwidth, so it will have to wait a little.</p>
<p>I can say that I found both books interesting. Howerver, PowerShell and WMI is not the most exciting subject, so this was somewhat difficult to get through. A lot of very good and usefull examples, though, which helped a lot.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strobaek.org/2011/08/29/review-of-books-soa-patterns-and-powershellwmi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grooming Windows Azure Diagnostics Storage and IIS Logs</title>
		<link>http://blog.strobaek.org/2011/08/17/grooming-windows-azure-diagnostics-storage-and-iis-logs/</link>
		<comments>http://blog.strobaek.org/2011/08/17/grooming-windows-azure-diagnostics-storage-and-iis-logs/#comments</comments>
		<pubDate>Wed, 17 Aug 2011 10:06:30 +0000</pubDate>
		<dc:creator>strobaek</dc:creator>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://blog.strobaek.org/?p=600</guid>
		<description><![CDATA[People working with Windows Azure are aware that the storage used for diagnostics will continue to grow perpetually if nothing is done about it. With the introduction of the Windows Azure Management Pack – I call it WAMP; don’t know if it has an official acronym yet &#8211; System Center Operations Manager (SCOM) is able [...]]]></description>
			<content:encoded><![CDATA[<p>People working with Windows Azure are aware that the storage used for diagnostics will continue to grow perpetually if nothing is done about it.</p>
<p>With the introduction of the <a href="http://www.microsoft.com/download/en/details.aspx?id=11324" target="_blank">Windows Azure Management Pack</a> – I call it WAMP; don’t know if it has an official acronym yet &#8211; System Center Operations Manager (SCOM) is able to groom the tables.</p>
<p>By default the following three rules are disabled in WAMP:</p>
<ul>
<li>Windows Azure Role Performance Counter Grooming</li>
<li>Windows Azure Role .NET Trace Grooming</li>
<li>Windows Azure Role NET Event Log Grooming</li>
</ul>
<ul>Once they have been enabled the rule will run on a periodic basis and will delete data from the relevant table older than T hours.</ul>
<p>An online guide to WAMP is available <a href="http://technet.microsoft.com/en-us/library/gg276367.aspx" target="_blank">here</a>.</p>
<p>Unfortunately WAMP/SCOM does not come with a similar functionality to groom the IIS logs located in blob storage. By default these logs are written to the blob storage once every hour, so after a few months in production there are quite a number of them. And remember, that it is one log entry per instance.</p>
<p>The cost of storage is not very big, so it would be difficult to argue for an automated solution to groom the logs if price is the only parameter considered. However, as the number of entries grow it will take longer and longer to actually identify the relevant one.</p>
<p>To overcome this challenge one can write a small PowerShell script using e.g. the <a href="https://www.cerebrata.com/Products/AzureManagementCmdlets/Default.aspx" target="_blank">Azure Management Cmdlets</a> developed by <a href="https://www.cerebrata.com/" target="_blank">Cerebrata</a>.</p>
<p>The script could look like the following:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="586"><strong><span style="font-family: Courier New;"># Name of your account</span></strong><br />
<strong><span style="font-family: Courier New;">$accountName = &lt;account name&gt;</span></strong><br />
<strong><span style="font-family: Courier New;"># Account key </span></strong><br />
<strong><span style="font-family: Courier New;">$accountKey = &lt;acount key&gt;</span></strong><strong><span style="font-family: Courier New;"># Name of container, e.g. wad-iis-logfiles</span></strong><br />
<strong><span style="font-family: Courier New;">$containerName = &lt;Container Name&gt;</span></strong><br />
<strong><span style="font-family: Courier New;">$lastModified = &lt;UTC Date&gt;</span></strong></p>
<p><strong><span style="font-family: Courier New;">$bfc = New-Object Cerebrata.AzureUtilities.ManagementClient.StorageManagementEntities.BlobsFilterCriteria</span></strong></p>
<p><strong><span style="font-family: Courier New;">$bfc.LastModifiedDateTimeTo = $lastModified</span></strong></p>
<p><strong><span style="font-family: Courier New;">Remove-Blob -BlobContainerName $containerName </span></strong><br />
<strong><span style="font-family: Courier New;">-BlobsFilterCriteria $bfc </span></strong><br />
<strong><span style="font-family: Courier New;">-AccountName $accountName </span></strong><br />
<span style="font-family: Courier New;"><strong>-AccountKey $accountKey</strong><strong></strong></span></td>
</tr>
</tbody>
</table>
<p>The script will remove all blob entries older than the date given.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strobaek.org/2011/08/17/grooming-windows-azure-diagnostics-storage-and-iis-logs/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>From the Trenches: SQL Cluster Installation</title>
		<link>http://blog.strobaek.org/2011/07/15/from-the-trenches-sql-cluster-installation/</link>
		<comments>http://blog.strobaek.org/2011/07/15/from-the-trenches-sql-cluster-installation/#comments</comments>
		<pubDate>Fri, 15 Jul 2011 17:54:28 +0000</pubDate>
		<dc:creator>strobaek</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://blog.strobaek.org/?p=584</guid>
		<description><![CDATA[I recently had to install a SQL Server 2008 R2 cluster at a client. My previous experience was, that once the underlying Windows cluster and the shared storage, e.g. in form of a SAN have been set up, the installation of SQL server is relatively straight forward. Well, not this time around. Before you begin [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had to install a SQL Server 2008 R2 cluster at a client. My previous experience was, that once the underlying Windows cluster and the shared storage, e.g. in form of a SAN have been set up, the installation of SQL server is relatively straight forward.</p>
<p>Well, not this time around.</p>
<p>Before you begin the installation of the SQL cluster, you can run some verifying tests of the Windows cluster. These were all green. During the SQL installation process all the Setup Support Rules are checked, and these were also all green.</p>
<p>The actual installation completed, but at the very end I got the following error:</p>
<p><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://blog.strobaek.org/wp-content/uploads/trenches_sql_1.jpg" alt="image" width="594" height="166" border="0" /></p>
<p>Looking in the event log, the following error could be seen:</p>
<p><em><span style="color: #0000ff;">Cluster network name resource &#8216;SQL Network Name (BJSQCON)&#8217; failed to create its associated computer object in domain &#8216;xxxx.com&#8217; for the following reason: Unable to create computer account.</span></em></p>
<p><em><span style="color: #0000ff;">The text for the associated error code is: Access is denied.</span></em></p>
<p>“Access is denied”. This sounds like an AD problem, but the installing user should have all the required access rights (this at least according to the infrastructure team).</p>
<p>After some investigation I opened the (advanced) properties in AD for the computer object of the SQL cluster (sorry for the black; client confidentiality)</p>
<p><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://blog.strobaek.org/wp-content/uploads/trenches_sql_2.jpg" alt="image" width="411" height="459" border="0" /></p>
<p>What was missing was the computer object for the Windows cluster, here shown after being added.</p>
<p>So after having pre-staged the AD, I removed the SQL node from the cluster and tried the installation again and this time all went fine.</p>
<p>Interested parties can read more about Failover Cluster setup and pre-staging here <a title="http://technet.microsoft.com/en-us/library/cc731002(WS.10).aspx#BKMK_steps_precreating" href="http://technet.microsoft.com/en-us/library/cc731002(WS.10).aspx#BKMK_steps_precreating">http://technet.microsoft.com/en-us/library/cc731002(WS.10).aspx#BKMK_steps_precreating</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strobaek.org/2011/07/15/from-the-trenches-sql-cluster-installation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Review of book: Machine Learning in Action</title>
		<link>http://blog.strobaek.org/2011/05/16/review-of-book-machine-learning-in-action/</link>
		<comments>http://blog.strobaek.org/2011/05/16/review-of-book-machine-learning-in-action/#comments</comments>
		<pubDate>Mon, 16 May 2011 09:30:22 +0000</pubDate>
		<dc:creator>strobaek</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Books]]></category>

		<guid isPermaLink="false">http://blog.strobaek.org/2011/05/16/review-of-book-machine-learning-in-action/</guid>
		<description><![CDATA[My last review for Manning Publications Co. can’t have been all bad, because they asked me to do another one. The book this time is Machine Learning in Action by Peter Harrington and currently available in MEAP. The review is a so called “2/3” review as the book is not complete. I had the pleasure [...]]]></description>
			<content:encoded><![CDATA[<p>My <a href="http://blog.strobaek.org/2011/04/26/review-of-book-rabbitmq-in-action/">last review</a> for Manning Publications Co. can’t have been all bad, because they asked me to do another one. The book this time is <em><a href="http://www.manning.com/pharrington/" target="_blank">Machine Learning in Action</a></em> by Peter Harrington and currently available in MEAP. The review is a so called “2/3” review as the book is not complete. I had the pleasure of reading chapters 1 through 10 as well as some of the appendixes.</p>
<p>Many years ago I did my Master thesis on the mathematical properties of artificial neural networks. I haven’t been working much in this area lately, so it was quite fun to “re-visit” some of the theory and applications used both in ANN and machine learning.</p>
<p>The book is very application oriented and gives some very good and illustrative examples of algorithms which can be used for classification, forecasting or unsupervised learning. It uses Python for all the code examples, but gives very good directions on how to install and use it, so if you are new to Python or have never used it before, this should not hinder you from getting value from the examples.</p>
<p>The author has included a lot of references to background material, enabling the reader to seek more information on areas of specific interest.</p>
<p>One area I find is a little weak is the handling or explanation of the underlying statistics. Machine learning is really just a form of Non-linear optimization and we know when these models are better then OLS (Ordinary Least Squares) or “regular” regression. If a certain set of conditions are met, the OLS estimate is the Maximum Likelihood (ML) estimate, and then we really can’t do any better. What this means is, that machine learning or neural networks or whatever we call it, will only be better if these conditions are not met.</p>
<p>One could fear, that the inexperienced user, would draw conclusions which on first sight would seem correct, but which would actually be wrong, because the underlying model was incorrect or the supplied data did not support it.</p>
<p>This being said, I found the book a very good read and a good introduction to Machine Learning. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strobaek.org/2011/05/16/review-of-book-machine-learning-in-action/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

