<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" version="2.0">
  <channel>
    <title>Code Assassin</title>
    <link>http://www.codeassassin.com/blog/</link>
    <description>Silently disposing your objects in the dead of night</description>
    <language>en-au</language>
    <copyright>Jason Stangroome</copyright>
    <lastBuildDate>Tue, 14 Jul 2009 06:22:08 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.6264.0</generator>
    <managingEditor>contact@codeassassin.com</managingEditor>
    <webMaster>contact@codeassassin.com</webMaster>
    <geo:lat>-27.28</geo:lat><geo:long>153.01</geo:long><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/CodeAssassin" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <trackback:ping>http://www.codeassassin.com/blog/Trackback.aspx?guid=b0e64a4d-876e-47c6-8a2c-8bd9ca768a48</trackback:ping>
      <pingback:server>http://www.codeassassin.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.codeassassin.com/blog/PermaLink,guid,b0e64a4d-876e-47c6-8a2c-8bd9ca768a48.aspx</pingback:target>
      <dc:creator>Jason</dc:creator>
      <wfw:comment>http://www.codeassassin.com/blog/CommentView,guid,b0e64a4d-876e-47c6-8a2c-8bd9ca768a48.aspx</wfw:comment>
      <wfw:commentRss>http://www.codeassassin.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=b0e64a4d-876e-47c6-8a2c-8bd9ca768a48</wfw:commentRss>
      <title>Generic batch file wrapper for PowerShell scripts</title>
      <guid isPermaLink="false">http://www.codeassassin.com/blog/PermaLink,guid,b0e64a4d-876e-47c6-8a2c-8bd9ca768a48.aspx</guid>
      <link>http://www.codeassassin.com/blog/PermaLink,guid,b0e64a4d-876e-47c6-8a2c-8bd9ca768a48.aspx</link>
      <pubDate>Tue, 14 Jul 2009 06:22:08 GMT</pubDate>
      <description>&lt;p&gt;
Integrating PowerShell scripts into older style processes that are only designed to
call out to executables or batch files (or “command scripts” as they have been known
since NT4) can be slightly messy primarily due to the argument parsing semantics around
double-quotes and file paths with spaces. I often end up writing a simple command
script to wrap each PowerShell script to simplify this but it is tedious and repetitive
and I’ve finally decided to create a generic script that works for any PowerShell
script.
&lt;/p&gt;
&lt;p&gt;
Simply save the following code as a text file and save it with the same name as your
PowerShell script but replace the .ps1 extension with a .cmd extension.
&lt;/p&gt;
&lt;pre&gt;@echo off
setlocal
set tempscript=%temp%\%~n0.%random%.ps1
echo $ErrorActionPreference="Stop" &gt;"%tempscript%"
echo ^&amp; "%~dpn0.ps1" %* &gt;&gt;"%tempscript%"
powershell.exe "%tempscript%"
set errlvl=%ERRORLEVEL%
del "%tempscript%"
exit /b %errlvl%&lt;/pre&gt;
&lt;p&gt;
Now if your script is called “Get-Something.ps1”, you can simply run it like this:
&lt;/p&gt;
&lt;pre&gt;Get-Something “c:\some path\some.file” –SecondArg 3.14&lt;/pre&gt;
&lt;img width="0" height="0" src="http://www.codeassassin.com/blog/aggbug.ashx?id=b0e64a4d-876e-47c6-8a2c-8bd9ca768a48" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=zgzbfk24ac8:1Hx_fMZ5pmc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=zgzbfk24ac8:1Hx_fMZ5pmc:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=zgzbfk24ac8:1Hx_fMZ5pmc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=zgzbfk24ac8:1Hx_fMZ5pmc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=zgzbfk24ac8:1Hx_fMZ5pmc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=zgzbfk24ac8:1Hx_fMZ5pmc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=zgzbfk24ac8:1Hx_fMZ5pmc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeAssassin/~4/zgzbfk24ac8" height="1" width="1"/&gt;</description>
      <comments>http://www.codeassassin.com/blog/CommentView,guid,b0e64a4d-876e-47c6-8a2c-8bd9ca768a48.aspx</comments>
      <category>PowerShell</category>
    </item>
    <item>
      <trackback:ping>http://www.codeassassin.com/blog/Trackback.aspx?guid=543994df-954d-436b-b050-c3f93c746c11</trackback:ping>
      <pingback:server>http://www.codeassassin.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.codeassassin.com/blog/PermaLink,guid,543994df-954d-436b-b050-c3f93c746c11.aspx</pingback:target>
      <dc:creator>Jason</dc:creator>
      <wfw:comment>http://www.codeassassin.com/blog/CommentView,guid,543994df-954d-436b-b050-c3f93c746c11.aspx</wfw:comment>
      <wfw:commentRss>http://www.codeassassin.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=543994df-954d-436b-b050-c3f93c746c11</wfw:commentRss>
      
      <title>PowerShell for Developers</title>
      <guid isPermaLink="false">http://www.codeassassin.com/blog/PermaLink,guid,543994df-954d-436b-b050-c3f93c746c11.aspx</guid>
      <link>http://www.codeassassin.com/blog/PermaLink,guid,543994df-954d-436b-b050-c3f93c746c11.aspx</link>
      <pubDate>Wed, 20 May 2009 05:41:30 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
Several weeks ago &lt;a href="http://richardsbraindump.blogspot.com/"&gt;Richard Banks&lt;/a&gt; (&lt;a href="http://twitter.com/rbanks54"&gt;@rbanks54&lt;/a&gt;)&#xD;
coerced me to find time to present to the Australian Virtual Alt.NET User Group between&#xD;
moving house and deploying a new website to production for my current client.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I agreed and with an absurdly short amount of preparation presented to a small group&#xD;
online using Microsoft Live Meeting and a shared PowerShell console window. You can &lt;a href="http://ozalt.net/blog/virtual-alt-net-11-may-09-powershell-and-ngourd/"&gt;watch&#xD;
the presentation&lt;/a&gt; on the &lt;a href="http://ozalt.net/blog/"&gt;Oz Alt.NET Community&#xD;
Blog&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The “slides” and example scripts can be &lt;a href="http://dl.getdropbox.com/u/255217/OzVAN-PowerShell.zip"&gt;downloaded&#xD;
here&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.codeassassin.com/blog/aggbug.ashx?id=543994df-954d-436b-b050-c3f93c746c11"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=YHutY8QatUg:ZaQl6klNWFk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=YHutY8QatUg:ZaQl6klNWFk:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=YHutY8QatUg:ZaQl6klNWFk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=YHutY8QatUg:ZaQl6klNWFk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=YHutY8QatUg:ZaQl6klNWFk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=YHutY8QatUg:ZaQl6klNWFk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=YHutY8QatUg:ZaQl6klNWFk:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeAssassin/~4/YHutY8QatUg" height="1" width="1"/&gt;</description>
      <comments>http://www.codeassassin.com/blog/CommentView,guid,543994df-954d-436b-b050-c3f93c746c11.aspx</comments>
      <category>PowerShell</category>
    </item>
    <item>
      <trackback:ping>http://www.codeassassin.com/blog/Trackback.aspx?guid=60340df4-9866-4c2b-80fc-7daf7103d5d8</trackback:ping>
      <pingback:server>http://www.codeassassin.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.codeassassin.com/blog/PermaLink,guid,60340df4-9866-4c2b-80fc-7daf7103d5d8.aspx</pingback:target>
      <dc:creator>Jason</dc:creator>
      <wfw:comment>http://www.codeassassin.com/blog/CommentView,guid,60340df4-9866-4c2b-80fc-7daf7103d5d8.aspx</wfw:comment>
      <wfw:commentRss>http://www.codeassassin.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=60340df4-9866-4c2b-80fc-7daf7103d5d8</wfw:commentRss>
      <slash:comments>1</slash:comments>
      
      <title>Code Coverage Delta with Team System and PowerShell</title>
      <guid isPermaLink="false">http://www.codeassassin.com/blog/PermaLink,guid,60340df4-9866-4c2b-80fc-7daf7103d5d8.aspx</guid>
      <link>http://www.codeassassin.com/blog/PermaLink,guid,60340df4-9866-4c2b-80fc-7daf7103d5d8.aspx</link>
      <pubDate>Sun, 01 Mar 2009 11:37:09 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
My last post documented my first venture into working with Visual Studio's Code Analysis&#xD;
output with PowerShell to find classes that need more testing. Since then I've taken&#xD;
the idea further to analyse how coverage has changed over a series of builds from&#xD;
TFS.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
What resulted is a PowerShell script that takes, as a minimum, the name of a TFS Project&#xD;
and the name of a Build Definition within that project. The script will then, by default,&#xD;
locate the two most recent successful builds, grab the code coverage data from the&#xD;
test runs of each of those builds and output a list of classes whose coverage has&#xD;
changed between those builds, citing the change in the number of blocks not covered.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Additional parameters to the script allow partially successful or failed builds to&#xD;
be considered and also to analyse coverage change over a span of several builds rather&#xD;
just two consecutive builds.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The primary motivator behind developing this script was to be able to identify more&#xD;
accurately where coverage was lost when a new build has an overall coverage percentage&#xD;
lower than the last. This then helps to locate, among other things, where new code&#xD;
has been added without testing or where existing tests have been deleted or disabled.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
A code base with a strong commitment to the Single Responsibility Principle should&#xD;
find class-level granularity sufficient but extending the script to support method-level&#xD;
reporting should be trivial given that the Coverage Analysis DataSet already includes&#xD;
all the required information.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The script requires the Team Foundation Server PowerShell Snapin from the TFS October&#xD;
2008 Power Tools and the Visual Studio Coverage Analysis assemblies presumably available&#xD;
in Visual Studio 2008 Professional or higher. These dependencies only support 32-bit&#xD;
PowerShell so my script unfortunately suffers the same constraint.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://www.codeassassin.com/public/Compare-TfsBuildCoverage.zip"&gt;Download&#xD;
the script here&lt;/a&gt;, and use it something like this:&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
PS C:\TfsWorkspace\&amp;gt; C:\Scripts\Compare-TfsBuildCoverage.ps1 -project Foo -build&#xD;
FooBuild | sort DeltaBlocksNotCovered&#xD;
&lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.codeassassin.com/blog/aggbug.ashx?id=60340df4-9866-4c2b-80fc-7daf7103d5d8"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=6fMRXZ5MSo0:DU7dkPk3uP0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=6fMRXZ5MSo0:DU7dkPk3uP0:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=6fMRXZ5MSo0:DU7dkPk3uP0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=6fMRXZ5MSo0:DU7dkPk3uP0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=6fMRXZ5MSo0:DU7dkPk3uP0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=6fMRXZ5MSo0:DU7dkPk3uP0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=6fMRXZ5MSo0:DU7dkPk3uP0:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeAssassin/~4/6fMRXZ5MSo0" height="1" width="1"/&gt;</description>
      <comments>http://www.codeassassin.com/blog/CommentView,guid,60340df4-9866-4c2b-80fc-7daf7103d5d8.aspx</comments>
      <category>PowerShell;Team Foundation Server;Unit Testing</category>
    </item>
    <item>
      <trackback:ping>http://www.codeassassin.com/blog/Trackback.aspx?guid=4d951141-cd88-40c0-b717-953424416007</trackback:ping>
      <pingback:server>http://www.codeassassin.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.codeassassin.com/blog/PermaLink,guid,4d951141-cd88-40c0-b717-953424416007.aspx</pingback:target>
      <dc:creator>Jason</dc:creator>
      <wfw:comment>http://www.codeassassin.com/blog/CommentView,guid,4d951141-cd88-40c0-b717-953424416007.aspx</wfw:comment>
      <wfw:commentRss>http://www.codeassassin.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=4d951141-cd88-40c0-b717-953424416007</wfw:commentRss>
      
      <title>Analyse Code Coverage with PowerShell</title>
      <guid isPermaLink="false">http://www.codeassassin.com/blog/PermaLink,guid,4d951141-cd88-40c0-b717-953424416007.aspx</guid>
      <link>http://www.codeassassin.com/blog/PermaLink,guid,4d951141-cd88-40c0-b717-953424416007.aspx</link>
      <pubDate>Fri, 13 Feb 2009 14:28:20 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
Visual Studio 2008 Team System's built-in Code Coverage is nice but the standard results&#xD;
window only allows you to drill down through each assembly, then namespace, class,&#xD;
and finally method. You can't easily find the class with the least blocks covered,&#xD;
something I needed to do the other day.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I found &lt;a href="http://blogs.msdn.com/ms_joc/articles/406608.aspx"&gt;John Cunningham's&#xD;
blog about "off-road" code coverage&lt;/a&gt; and was pleased to see that Microsoft had&#xD;
provided an assembly in Visual Studio that can be used to parse the *.coverage file&#xD;
output by a test run. I followed his example to write a PowerShell script to provide&#xD;
basic access to the data.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
You can &lt;a href="/public/Get-CodeCoverageDataSet.zip"&gt;download my script here&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Then you can use it like this:&#xD;
&lt;/p&gt;&#xD;
        &lt;pre name="code" class="ps1"&gt;$CoverageDS = ./Get-CodeCoverageDataSet.ps1 "data.coverage"&#xD;
$CoverageDS.Class `&#xD;
  | Sort-Object -Property BlocksNotCovered -Descending `&#xD;
  | Select-Object `&#xD;
    -First 25 `&#xD;
    -Property `&#xD;
      BlocksNotCovered, `&#xD;
      @{ &#xD;
        Name = "Namespace"; &#xD;
        Expression = { &#xD;
          $CoverageDS.NamespaceTable.FindByNamespaceKeyName($_.NamespaceKeyName).NamespaceName&#xD;
        }&#xD;
      }, `&#xD;
      ClassName&#xD;
&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
The coverage file is typically found in the TestResults\[TestRunName]\In\[ComputerName]\&#xD;
folder. You can easily perform queries over methods or lines rather than classes by&#xD;
using the other tables in the returned dataset. You can also use the ConvertTo-Html&#xD;
cmdlet to easily create a report for your team.&#xD;
&lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.codeassassin.com/blog/aggbug.ashx?id=4d951141-cd88-40c0-b717-953424416007"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=YPrVzp64qo8:PFwW1S-DOE0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=YPrVzp64qo8:PFwW1S-DOE0:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=YPrVzp64qo8:PFwW1S-DOE0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=YPrVzp64qo8:PFwW1S-DOE0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=YPrVzp64qo8:PFwW1S-DOE0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=YPrVzp64qo8:PFwW1S-DOE0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=YPrVzp64qo8:PFwW1S-DOE0:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeAssassin/~4/YPrVzp64qo8" height="1" width="1"/&gt;</description>
      <comments>http://www.codeassassin.com/blog/CommentView,guid,4d951141-cd88-40c0-b717-953424416007.aspx</comments>
      <category>PowerShell;Unit Testing</category>
    </item>
    <item>
      <trackback:ping>http://www.codeassassin.com/blog/Trackback.aspx?guid=f3ff2ae9-23fe-4636-99fd-4e0b0b7ff01d</trackback:ping>
      <pingback:server>http://www.codeassassin.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.codeassassin.com/blog/PermaLink,guid,f3ff2ae9-23fe-4636-99fd-4e0b0b7ff01d.aspx</pingback:target>
      <dc:creator>Jason</dc:creator>
      <wfw:comment>http://www.codeassassin.com/blog/CommentView,guid,f3ff2ae9-23fe-4636-99fd-4e0b0b7ff01d.aspx</wfw:comment>
      <wfw:commentRss>http://www.codeassassin.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=f3ff2ae9-23fe-4636-99fd-4e0b0b7ff01d</wfw:commentRss>
      
      <title>Is -ism me?</title>
      <guid isPermaLink="false">http://www.codeassassin.com/blog/PermaLink,guid,f3ff2ae9-23fe-4636-99fd-4e0b0b7ff01d.aspx</guid>
      <link>http://www.codeassassin.com/blog/PermaLink,guid,f3ff2ae9-23fe-4636-99fd-4e0b0b7ff01d.aspx</link>
      <pubDate>Tue, 10 Feb 2009 12:27:50 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
In a sad attempt to get blogging again, I am going to start by responding to &lt;a href="http://www.nervoustych.com/blog/PermaLink,guid,826827b3-3f22-47cf-a034-5c127578977c.aspx"&gt;this&#xD;
blatant prod&lt;/a&gt;. I agree with some of &lt;a href="http://www.linkedin.com/pub/7/b62/608"&gt;Jim&lt;/a&gt;'s&#xD;
answers but to keep it interesting I've selected a disjoint set and &lt;a href="http://futurama.wikia.com/wiki/Elzar"&gt;knocked&#xD;
it up a notch&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I am:&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Pragmatic about &lt;a href="http://www.imdb.com/title/tt0120655/"&gt;dogmatism&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Practicing &lt;a href="http://www.codeassassin.com/dvds.txt"&gt;consumerism&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Prone to &lt;a href="http://en.wikipedia.org/wiki/Defeatism"&gt;defeatism&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Parodying &lt;a href="http://www.polar.fi/au-en/products/running_multisport/RS200"&gt;athleticism&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Proof of &lt;a href="http://xkcd.com/505/"&gt;determinism&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
To keep it going, the same rule applies: if you've read this then follow suit blogging&#xD;
your own answers, even if you are busy writing your own blog engine.&#xD;
&lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.codeassassin.com/blog/aggbug.ashx?id=f3ff2ae9-23fe-4636-99fd-4e0b0b7ff01d"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=oBl6-t_sbcw:SIjphq9h_W8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=oBl6-t_sbcw:SIjphq9h_W8:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=oBl6-t_sbcw:SIjphq9h_W8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=oBl6-t_sbcw:SIjphq9h_W8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=oBl6-t_sbcw:SIjphq9h_W8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=oBl6-t_sbcw:SIjphq9h_W8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=oBl6-t_sbcw:SIjphq9h_W8:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeAssassin/~4/oBl6-t_sbcw" height="1" width="1"/&gt;</description>
      <comments>http://www.codeassassin.com/blog/CommentView,guid,f3ff2ae9-23fe-4636-99fd-4e0b0b7ff01d.aspx</comments>
      <category>Metablog</category>
    </item>
    <item>
      <trackback:ping>http://www.codeassassin.com/blog/Trackback.aspx?guid=cc3a732c-4eb2-4487-acf8-9f964c32347d</trackback:ping>
      <pingback:server>http://www.codeassassin.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.codeassassin.com/blog/PermaLink,guid,cc3a732c-4eb2-4487-acf8-9f964c32347d.aspx</pingback:target>
      <dc:creator>Jason</dc:creator>
      <wfw:comment>http://www.codeassassin.com/blog/CommentView,guid,cc3a732c-4eb2-4487-acf8-9f964c32347d.aspx</wfw:comment>
      <wfw:commentRss>http://www.codeassassin.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=cc3a732c-4eb2-4487-acf8-9f964c32347d</wfw:commentRss>
      
      <title>Adelaide Geek Dinner Handover</title>
      <guid isPermaLink="false">http://www.codeassassin.com/blog/PermaLink,guid,cc3a732c-4eb2-4487-acf8-9f964c32347d.aspx</guid>
      <link>http://www.codeassassin.com/blog/PermaLink,guid,cc3a732c-4eb2-4487-acf8-9f964c32347d.aspx</link>
      <pubDate>Tue, 21 Oct 2008 11:03:03 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
As I have recently accepted a new job interstate, I will no longer be organising dinners&#xD;
for fellow developers in Adelaide. However, rather than allow such a fun event to&#xD;
disappear, I am passing the awesome responsibility of organising the dinners to my&#xD;
friend and colleague, &lt;a href="http://nervoustych.com/blog/" target="_blank"&gt;Jim Burger&lt;/a&gt;,&#xD;
whom many of you have met on previous occasions.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I will be giving Jim a hard time to make sure he continues to arrange a dinner at&#xD;
least once each quarter and I believe it will also help to ensure he remembers to&#xD;
attend them himself ;). Names and contact details of previous attendees and people&#xD;
who have registered their interest will be given to Jim so he can send you the next&#xD;
invite but let him or I know if you'd rather be removed from the list.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
If you've never been invited to an Adelaide Geek Dinner before but want to be on the&#xD;
list, just contact Jim or I and you'll surely be invited to the next one.&#xD;
&lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.codeassassin.com/blog/aggbug.ashx?id=cc3a732c-4eb2-4487-acf8-9f964c32347d"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=rxL99f_mO5g:nPcj2S0TEZo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=rxL99f_mO5g:nPcj2S0TEZo:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=rxL99f_mO5g:nPcj2S0TEZo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=rxL99f_mO5g:nPcj2S0TEZo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=rxL99f_mO5g:nPcj2S0TEZo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=rxL99f_mO5g:nPcj2S0TEZo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=rxL99f_mO5g:nPcj2S0TEZo:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeAssassin/~4/rxL99f_mO5g" height="1" width="1"/&gt;</description>
      <comments>http://www.codeassassin.com/blog/CommentView,guid,cc3a732c-4eb2-4487-acf8-9f964c32347d.aspx</comments>
      <category>Geek Dinner</category>
    </item>
    <item>
      <trackback:ping>http://www.codeassassin.com/blog/Trackback.aspx?guid=41a7b075-4ae8-4742-a3b1-0df55577fb00</trackback:ping>
      <pingback:server>http://www.codeassassin.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.codeassassin.com/blog/PermaLink,guid,41a7b075-4ae8-4742-a3b1-0df55577fb00.aspx</pingback:target>
      <dc:creator>Jason</dc:creator>
      <wfw:comment>http://www.codeassassin.com/blog/CommentView,guid,41a7b075-4ae8-4742-a3b1-0df55577fb00.aspx</wfw:comment>
      <wfw:commentRss>http://www.codeassassin.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=41a7b075-4ae8-4742-a3b1-0df55577fb00</wfw:commentRss>
      
      <title>Strongly Typed Windows Forms Data Binding</title>
      <guid isPermaLink="false">http://www.codeassassin.com/blog/PermaLink,guid,41a7b075-4ae8-4742-a3b1-0df55577fb00.aspx</guid>
      <link>http://www.codeassassin.com/blog/PermaLink,guid,41a7b075-4ae8-4742-a3b1-0df55577fb00.aspx</link>
      <pubDate>Tue, 14 Oct 2008 11:12:36 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
I was recently inspired by a &lt;a href="http://stackoverflow.com/questions/152250/get-class-property-name" target="_blank"&gt;question&#xD;
about property names in strings&lt;/a&gt; on &lt;a href="http://stackoverflow.com/" target="_blank"&gt;Stack&#xD;
Overflow&lt;/a&gt;. The problem is that Windows Forms data binding takes the names&#xD;
of properties to bind as string parameters and if these properties change or are removed,&#xD;
errors won't surface until the bound control is exercised at run-time. So, using &lt;a href="http://www.paulstovell.com/blog/" target="_blank"&gt;Paul's&lt;/a&gt;&lt;a href="http://www.paulstovell.com/blog/strongly-typed-property-names" target="_blank"&gt;strongly&#xD;
typed property name ideas&lt;/a&gt;, I propose this alternative syntax for programmatic&#xD;
data binding in Windows Forms:&#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="c#" name="code"&gt;nameTextBox.Bind(t =&amp;gt; t.Text, aBindingSource, (Customer c) =&amp;gt; c.FirstName);&#xD;
// Binds the Text property on nameTextBox to the FirstName property&#xD;
// of the current Customer in aBindingSource, no string literals required.&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
And the following code to implement support for it:&#xD;
&lt;/p&gt;&#xD;
        &lt;pre class="c#" name="code"&gt;public static class ControlExtensions&#xD;
{&#xD;
    public static Binding Bind&amp;lt;TControl, TDataSourceItem&amp;gt;(this TControl control, Expression&amp;lt;Func&amp;lt;TControl, object&amp;gt;&amp;gt; controlProperty, object dataSource, Expression&amp;lt;Func&amp;lt;TDataSourceItem, object&amp;gt;&amp;gt; dataSourceProperty) where TControl: Control&#xD;
    {&#xD;
        return control.DataBindings.Add(PropertyName.For(controlProperty), dataSource, PropertyName.For(dataSourceProperty));&#xD;
    }&#xD;
}&#xD;
&#xD;
public static class PropertyName&#xD;
{&#xD;
    public static string For&amp;lt;T&amp;gt;(Expression&amp;lt;Func&amp;lt;T, object&amp;gt;&amp;gt; property)&#xD;
    {&#xD;
        var member = property.Body as MemberExpression;&#xD;
        if (null == member)&#xD;
        {&#xD;
            var unary = property.Body as UnaryExpression;&#xD;
            if (null != unary) member = unary.Operand as MemberExpression;&#xD;
        }&#xD;
        return null != member ? member.Member.Name : string.Empty;&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
Thoughts? Overkill?&#xD;
&lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.codeassassin.com/blog/aggbug.ashx?id=41a7b075-4ae8-4742-a3b1-0df55577fb00"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=OmFFIjNVbfE:Knz7Lj3HpUc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=OmFFIjNVbfE:Knz7Lj3HpUc:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=OmFFIjNVbfE:Knz7Lj3HpUc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=OmFFIjNVbfE:Knz7Lj3HpUc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=OmFFIjNVbfE:Knz7Lj3HpUc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=OmFFIjNVbfE:Knz7Lj3HpUc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=OmFFIjNVbfE:Knz7Lj3HpUc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeAssassin/~4/OmFFIjNVbfE" height="1" width="1"/&gt;</description>
      <comments>http://www.codeassassin.com/blog/CommentView,guid,41a7b075-4ae8-4742-a3b1-0df55577fb00.aspx</comments>
      <category>.NET Framework</category>
    </item>
    <item>
      <trackback:ping>http://www.codeassassin.com/blog/Trackback.aspx?guid=3752f97b-bcc6-463c-9cbb-00f387d76c19</trackback:ping>
      <pingback:server>http://www.codeassassin.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.codeassassin.com/blog/PermaLink,guid,3752f97b-bcc6-463c-9cbb-00f387d76c19.aspx</pingback:target>
      <dc:creator>Jason</dc:creator>
      <wfw:comment>http://www.codeassassin.com/blog/CommentView,guid,3752f97b-bcc6-463c-9cbb-00f387d76c19.aspx</wfw:comment>
      <wfw:commentRss>http://www.codeassassin.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=3752f97b-bcc6-463c-9cbb-00f387d76c19</wfw:commentRss>
      
      <title>Binding... and IList&amp;lt;T&amp;gt; does not inherit from IList.</title>
      <guid isPermaLink="false">http://www.codeassassin.com/blog/PermaLink,guid,3752f97b-bcc6-463c-9cbb-00f387d76c19.aspx</guid>
      <link>http://www.codeassassin.com/blog/PermaLink,guid,3752f97b-bcc6-463c-9cbb-00f387d76c19.aspx</link>
      <pubDate>Mon, 04 Aug 2008 07:05:34 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
A note to myself, and to others who may find it useful:&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Use &lt;a href="http://msdn.microsoft.com/en-us/library/ms132397.aspx" target="_blank"&gt;System.Collections.ObjectModel.Collection&amp;lt;T&amp;gt;&lt;/a&gt; (or&#xD;
a subclass) as the return type for properties exposing collections of related items&#xD;
on your presentation model classes if you intend to bind to the relationships with&#xD;
Windows Forms &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.aspx" target="_blank"&gt;BindingSources&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Collection&amp;lt;T&amp;gt; appears to be the lowest-level type in Framework 3.5 that provides&#xD;
both the non-generic IList implementation as required by the binding system and also&#xD;
provides strongly-typed programmatic access to the elements of the collection. It&#xD;
is used as the base for BindingList&amp;lt;T&amp;gt;, ObservableCollection&amp;lt;T&amp;gt; and many&#xD;
others and you can easily inherit from it yourself.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Using a return type of IList&amp;lt;T&amp;gt; or ICollection&amp;lt;T&amp;gt; instead, which may be&#xD;
preferred for being less concrete, is &lt;strong&gt;not &lt;/strong&gt;sufficient as neither of&#xD;
these inherit from the non-generic IList and will fail to bind correctly (sometimes&#xD;
throwing exceptions) at run-time when the parent list of the bound relationship is&#xD;
empty.&#xD;
&lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.codeassassin.com/blog/aggbug.ashx?id=3752f97b-bcc6-463c-9cbb-00f387d76c19"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=CDokuRKMJ5c:mEgp9C9qbVg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=CDokuRKMJ5c:mEgp9C9qbVg:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=CDokuRKMJ5c:mEgp9C9qbVg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=CDokuRKMJ5c:mEgp9C9qbVg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=CDokuRKMJ5c:mEgp9C9qbVg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=CDokuRKMJ5c:mEgp9C9qbVg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=CDokuRKMJ5c:mEgp9C9qbVg:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeAssassin/~4/CDokuRKMJ5c" height="1" width="1"/&gt;</description>
      <comments>http://www.codeassassin.com/blog/CommentView,guid,3752f97b-bcc6-463c-9cbb-00f387d76c19.aspx</comments>
      <category>.NET Framework</category>
    </item>
    <item>
      <trackback:ping>http://www.codeassassin.com/blog/Trackback.aspx?guid=d2cd786d-4233-4fd1-ba15-250fa33c8148</trackback:ping>
      <pingback:server>http://www.codeassassin.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.codeassassin.com/blog/PermaLink,guid,d2cd786d-4233-4fd1-ba15-250fa33c8148.aspx</pingback:target>
      <dc:creator>Jason</dc:creator>
      <wfw:comment>http://www.codeassassin.com/blog/CommentView,guid,d2cd786d-4233-4fd1-ba15-250fa33c8148.aspx</wfw:comment>
      <wfw:commentRss>http://www.codeassassin.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=d2cd786d-4233-4fd1-ba15-250fa33c8148</wfw:commentRss>
      
      <title>Adelaide Geek Dinner August 2008 Announcement</title>
      <guid isPermaLink="false">http://www.codeassassin.com/blog/PermaLink,guid,d2cd786d-4233-4fd1-ba15-250fa33c8148.aspx</guid>
      <link>http://www.codeassassin.com/blog/PermaLink,guid,d2cd786d-4233-4fd1-ba15-250fa33c8148.aspx</link>
      <pubDate>Fri, 01 Aug 2008 12:07:48 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
As &lt;a href="http://www.codeassassin.com/blog/PermaLink,guid,ac5db07c-f73c-40a2-9077-474025f3f953.aspx" target="_blank"&gt;promised&#xD;
in May&lt;/a&gt;, it is time for the August Geek Dinner, specifically the time will be 6:30pm&#xD;
on Saturday 16th August. Everyone seemed to enjoy the food and atmosphere of &lt;a href="http://www.cafeamore.com.au/" target="_blank"&gt;Caffe&#xD;
Amore&lt;/a&gt; on the corner of Pulteney and Pirie Streets last time so we'll be going&#xD;
there again this time.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
If you're already on the geek dinner mailing list from previous times expect an invitation&#xD;
shortly. If you've never been invited before or you think your invite may be lost&#xD;
in the mail, just contact me and I'll make sure you get included.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Please RSVP before Wednesday 13th August so I can finalise the booking with the restaurant.&#xD;
Hope to see you all there!&#xD;
&lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.codeassassin.com/blog/aggbug.ashx?id=d2cd786d-4233-4fd1-ba15-250fa33c8148"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=LON_QfwtPy4:UyMJcjheFS4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=LON_QfwtPy4:UyMJcjheFS4:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=LON_QfwtPy4:UyMJcjheFS4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=LON_QfwtPy4:UyMJcjheFS4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=LON_QfwtPy4:UyMJcjheFS4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=LON_QfwtPy4:UyMJcjheFS4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=LON_QfwtPy4:UyMJcjheFS4:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeAssassin/~4/LON_QfwtPy4" height="1" width="1"/&gt;</description>
      <comments>http://www.codeassassin.com/blog/CommentView,guid,d2cd786d-4233-4fd1-ba15-250fa33c8148.aspx</comments>
      <category>Geek Dinner</category>
    </item>
    <item>
      <trackback:ping>http://www.codeassassin.com/blog/Trackback.aspx?guid=45aa2cca-09b4-4955-b573-5b8a915d4c25</trackback:ping>
      <pingback:server>http://www.codeassassin.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.codeassassin.com/blog/PermaLink,guid,45aa2cca-09b4-4955-b573-5b8a915d4c25.aspx</pingback:target>
      <dc:creator>Jason</dc:creator>
      <wfw:comment>http://www.codeassassin.com/blog/CommentView,guid,45aa2cca-09b4-4955-b573-5b8a915d4c25.aspx</wfw:comment>
      <wfw:commentRss>http://www.codeassassin.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=45aa2cca-09b4-4955-b573-5b8a915d4c25</wfw:commentRss>
      <slash:comments>1</slash:comments>
      
      <title>TFS Deployer Least Privilege</title>
      <guid isPermaLink="false">http://www.codeassassin.com/blog/PermaLink,guid,45aa2cca-09b4-4955-b573-5b8a915d4c25.aspx</guid>
      <link>http://www.codeassassin.com/blog/PermaLink,guid,45aa2cca-09b4-4955-b573-5b8a915d4c25.aspx</link>
      <pubDate>Sat, 05 Jul 2008 00:54:16 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
The original &lt;a href="http://www.codeplex.com/tfsdeployer" target="_blank"&gt;TFS Deployer&lt;/a&gt; attempted&#xD;
to access various restricted resources than effectively required it to run as an administrator&#xD;
user. Since some changes were made in February, Deployer can now be executed under&#xD;
a standard user account with some additional considerations which follow.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;strong&gt;Team Foundation Server Permissions&lt;/strong&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The TFS Deployer service account must be a member of the Team Foundation Valid Users&#xD;
server-level group on the server specified by the TeamFoundationServerUrl config setting&#xD;
and also a member of the Readers project-level group for the Team Projects that Deployer&#xD;
will be monitoring.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
If you intend to make use of the &lt;a href="http://www.codeassassin.com/blog/PermaLink,guid,9121ee83-17b9-4b02-872c-d0a9e182aad8.aspx" target="_blank"&gt;Retain&#xD;
Build feature&lt;/a&gt;, the Deployer service account will also need the Write To Operational&#xD;
Build Store project-level permission on applicable Team Projects.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;strong&gt;PowerShell Execution Policy&lt;/strong&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
TFS Deployer can execute Windows Command Scripts if you really need it to but PowerShell&#xD;
scripts are the preferred option. However, PowerShell is built to be secure-by-default&#xD;
and installs with script-running capabilities disabled. It is left for the user to&#xD;
enable scripts after PowerShell has been installed and can be performed by opening&#xD;
the PowerShell console as an administrator and executing either:&#xD;
&lt;/p&gt;&#xD;
        &lt;pre&gt;Set-ExecutionPolicy AllSigned ; # or&lt;br&gt;&#xD;
Set-ExecutionPolicy RemoteSigned&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
The former choice will require you to sign all your deployment scripts in source control&#xD;
with a certificate trusted by the Deployer. &lt;a href="http://www.hanselman.com/blog/" target="_blank"&gt;Scott&#xD;
Hanselman&lt;/a&gt; has a comprehensive post on his blog describing the &lt;a href="http://www.hanselman.com/blog/SigningPowerShellScripts.aspx" target="_blank"&gt;signing&#xD;
process&lt;/a&gt;. The latter choice &lt;a href="http://blogs.msdn.com/powershell/archive/2007/03/07/how-does-the-remotesigned-execution-policy-work.aspx" target="_blank"&gt;will&#xD;
not impose this requirement&lt;/a&gt; because files retrieved from source control by Deployer&#xD;
are not marked with a zone identifier.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;strong&gt;HTTP Namespace Reservation&lt;/strong&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
TFS Deployer utilises self-hosted WCF over HTTP to subscribe to Build Quality Change&#xD;
events from TFS. This technique relies on the Windows HTTP Server API which requires&#xD;
the Deployer service account to have been granted rights to listen on the portion&#xD;
of the HTTP URL namespace it uses for event notification. By default only local administrators&#xD;
have access to the entire namespace and permissions must be granted using the httpcfg&#xD;
tool (on Windows XP and Server 2003) or the netsh tool (on Vista and Server 2008).&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Using the netsh tool, from an administrator command prompt, the following command&#xD;
(as a single line) will grant rights to the appropriate URL for TFS Deployer (assuming&#xD;
you are using the default port number):&#xD;
&lt;/p&gt;&#xD;
        &lt;pre&gt;netsh http add urlacl url=http://+:8881/BuildStatusChangeEvent user=DOMAIN\TfsDeployerUser&lt;/pre&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://msdn.microsoft.com/en-us/library/ms733768.aspx" target="_blank"&gt;Using&#xD;
the httpcfg tool&lt;/a&gt; is more difficult as it requires an ACL string in Security Descriptor&#xD;
Definition Language (SDDL). However, &lt;a href="http://www.leastprivilege.com/" target="_blank"&gt;Dominick&#xD;
Baier&lt;/a&gt; has &lt;a href="http://www.leastprivilege.com/URIACLsAndWCFRevisited.aspx" target="_blank"&gt;created&#xD;
a tool&lt;/a&gt; to simplify this process and I can recommend it. &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;strong&gt;Additional Permissions&lt;/strong&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
All deployment scripts executed by TFS Deployer will be executed under the context&#xD;
of the service account unless the scripts explicitly contain alternate credentials.&#xD;
If the scripts copy files to a network share, configure a web site in IIS, or even&#xD;
upgrade the schema of a SQL database, ensure that the service account also has the&#xD;
minimum privileges to perform those actions too.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Any problems, questions, or suggestions... let me know.&#xD;
&lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.codeassassin.com/blog/aggbug.ashx?id=45aa2cca-09b4-4955-b573-5b8a915d4c25"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=Y3pOWJNT8I0:H10Q3mhYqgo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=Y3pOWJNT8I0:H10Q3mhYqgo:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=Y3pOWJNT8I0:H10Q3mhYqgo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=Y3pOWJNT8I0:H10Q3mhYqgo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=Y3pOWJNT8I0:H10Q3mhYqgo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?i=Y3pOWJNT8I0:H10Q3mhYqgo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/CodeAssassin?a=Y3pOWJNT8I0:H10Q3mhYqgo:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/CodeAssassin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeAssassin/~4/Y3pOWJNT8I0" height="1" width="1"/&gt;</description>
      <comments>http://www.codeassassin.com/blog/CommentView,guid,45aa2cca-09b4-4955-b573-5b8a915d4c25.aspx</comments>
      <category>Least Privilege;PowerShell;Team Foundation Server</category>
    </item>
  </channel>
</rss>
