Analyzing Visual C# Project Files

PowerShell provides some nice shortcuts for dealing with XML files.  As it turns out, Visual C# 2005 project files are MSBuild based which means that ultimately they are just XML files.  Here’s a way to find all C# source code containing classes that are components using PS:
PS> $projects = @()
PS> gci . -rec "*.csproj" -Name |
>>  foreach {$projects += [xml](get-content $_)}
PS> $projects | foreach {$_.GetElementsByTagName("Compile")} |
>>  where {$_.SubType -eq "Component"} | ft Include
A slightly more interesting example is to find out what the Optimze setting is for the Release build configuration in all C# projects:
$projects = gci . -rec "*.csproj" -Name |
  select Fullname,@{e={[xml](get-content _)};n="XmlDoc"}
$projects |`
  foreach {$pgs = $_.XmlDoc.Project.PropertyGroup;
    foreach ($pg in $pgs) {
      if ($pg.GetAttribute("Condition") -match "Release") {
        $pg=add-member -i $pg -type noteproperty -name "proj" $_ -for
  } | ft @{e={$_.proj.fullname};l="ProjFile"},
         @{e={$_.Optimize};l="Optimize"} -auto
This task can also be accomplished using XPath but the PS support for that isn’t as direct.  Here’s an example of how you would do it with XPath in PS:
$projects = gci . -rec "*.csproj" -Name |
   select Fullname,@{e={[xml](get-content $_)};n="XmlDoc"}
$query = "//dns:PropertyGroup[contains(@Condition, ‘Release’)]"
$projects |
  foreach {
    $doc  = $_.XmlDoc

    $nsmgr = new-object Xml.XmlNamespaceManager($doc.PSBase.NameTable)
    $nsmgr.AddNamespace("dns", $msbuildNS)
    $nodes = $doc.SelectNodes($query, $nsmgr)
    if ($nodes.count -gt 0) {
Note that since PowerShell provides access to XML child elements via the "property accessor" syntax, if you really want to access a property of XmlDocument or XmlNode you need to either access those via the PSBase property or use the get_<property> method.
This entry was posted in PowerShell. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s