﻿<?xml version="1.0" encoding="utf-8"?>
<configuration id="e2e630d8-c0dc-4b6c-a2a8-8f02cfb4868e">
  <container id="9cf6a2b5-dd7d-4287-bcf4-1a804c3120ed" name="SnapinInfo">
    <items>
      <container id="2a7a09ae-54f3-468b-a188-7c3b7c5eb6e3" name="welcome">
        <items />
      </container>
      <container id="2c4e1b31-79c0-46ad-aa27-eaacf1c10b59" name="Required Snapins">
        <items />
      </container>
      <container id="7b082250-5a98-48f5-8a3f-6ab5f1e4d90e" name="PowerGUI Version">
        <value>1.0.15.361</value>
        <items />
      </container>
    </items>
  </container>
  <items>
    <container id="b3b2283e-6f58-40c6-86b6-f01cd7f060fa" name="Navigation Tree">
      <items>
        <container id="9ebf0f0a-6981-4b1d-891c-d6242d552a87" parent="b3b2283e-6f58-40c6-86b6-f01cd7f060fa" name="Team Foundation Server" type="Folder">
          <items>
            <container id="ec68a806-f6f9-4f4e-be72-3f7485ed4db0" parent="9ebf0f0a-6981-4b1d-891c-d6242d552a87" name="Browse projects by Area" type="Script@Microsoft.TeamFoundation.WorkItemTracking.Client.Project" returntype="Microsoft.TeamFoundation.WorkItemTracking.Client.Project">
              <script><![CDATA[Function LoadTFSAssemblies()
{
	$assembly1 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation")
	$assembly2 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
	$assembly3 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.WorkItemTracking.Client")
}

Function global:GetServerPath()
{
	$pathRoot = "HKCU:\Software\PowerGui"
	
	# Check to see if the key already exists
	if( Test-Path ($pathRoot + "\TfsBrowser") )
	{
		$reg = Get-ItemProperty ($pathRoot + "\TfsBrowser")
		$serverName = $reg.Server
		
		# If the reg key exists but it contains an empty string prompt the user to provide an address
		if( [String]::IsNullOrEmpty( $serverName ) )
		{
			$serverName = Read-Host "Team Foundation Server"
			$result = Set-ItemProperty -path ($pathRoot + "\TfsBrowser") -name "Server" -Value $serverName
		}
		
		$serverName
	}
	else
	{
		# Prompt the user for the address of the TFS server to connect to
		$serverName = Read-Host "Team Foundation Server"
		
		# Make sure the registry key exists before we try and set the value.
		if( (Test-Path $pathRoot) -ne $TRUE ) {$a = New-Item -path $pathRoot}
		if( (Test-Path ($pathRoot + "\TfsBrowser")) -ne $TRUE ) {$a = New-Item -path ($pathRoot + "\TfsBrowser")}
		
		# Set the TFS server address in the registry
		$result = Set-ItemProperty -path ($pathRoot + "\TfsBrowser") -name "Server" -Value $serverName
		$serverName
	}
}

Function global:GetServerConnection()
{
	$serverPath = GetServerPath
	[psobject] $tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($serverPath)
	$workItemStore = [Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore]
	$tfs.GetService($workItemStore)
}

Function global:GetTFSCSS()
{
	$serverPath = GetServerPath
	[psobject] $tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($serverPath)
	$cssType = [Microsoft.TeamFoundation.Server.ICommonStructureService]
	$tfs.GetService($cssType)
}

Function global:GetCurrentNode()
{
	[Quest.PowerGUI.HostFactory]::Current.Application.Navigation.CurrentItem;
}

##
# This function takes a project name and a full area path and queries the TFS server
# for all WorkItems in that project/area, pumping all results out to the console
#
Function global:GetTFSWorkItemsForArea($projectName, $areaName)
{
	[Microsoft.TeamFoundation.WorkItemTracking.Client.Project] $project = GetTFSProjectByName $projectName
	[Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore] $store = $project.Store
	
	if( $areaName -eq $NULL )
	{
		$areaName = $projectName
	}
	else
	{
		$trimLength = $projectName.Length + 6
	
		$areaName = $areaName.substring($trimLength) 
		$areaName = $projectName + $areaName
	}
	
	$queryString = 
		[String]::Format("SELECT [System.Id], [System.WorkItemType], [System.AssignedTo],[System.CreatedBy], [System.Title] FROM WorkItems WHERE [System.TeamProject] = '{0}' AND [System.AreaPath] = '{1}'",
							$project.Name,
							$areaName)
	
	[Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemCollection] $workItemCollection = $store.Query( $queryString )
	Write-Output $workItemCollection
}

##
# This function queries the TFS server for all area nodes for the indicated project
# and starts the recursive process of walking the area nodes and creating PowerGUI
# tree nodes
#
Function global:AddAreaRootNodes($projectName, $fullAreaName) 
{
	$selectedNode = GetCurrentNode
	
	$css = GetTFSCSS

    [Microsoft.TeamFoundation.Server.ProjectInfo] $projectInfo = $css.GetProjectFromName($projectName)
	$nodes = $css.ListStructures($projectInfo.Uri);
	
	$nodes | %{ 
	
		if( $_.StructureType -eq "ProjectModelHierarchy" )
		{
			[System.Xml.XmlElement] $nodesElement = $css.GetNodesXml($_.Uri, $TRUE)
			$nav = $nodesElement.CreateNavigator()
			[xml] $xml = $nav.InnerXml
					
			if( $xml.Node.Children -ne $NULL )
			{
				$xml.Node.Children.Node | %{
				
					$node = $_
					AddAreaNode $projectName $node $selectedNode
				}
			}
		}
	}			
}

##
# This recursive function walks down the area nodes tree creating
# a new PowerGui node for each item it finds.
#
Function global:AddAreaNode {
	param($projectName, $node, $parentTreeNode) 

	$areaName = $node.GetAttribute("Name")
	$areaPath = $node.GetAttribute("Path")
		
	$childTreeNode = $parentTreeNode.AddChild(); 
	$childTreeNode.Name = $areaName;
	$childTreeNode.Script = "GetTFSWorkItemsForArea '$projectName' '$areaPath'"
	
	if( $node.Children -ne $NULL )
	{
		$node.Children.Node | %{
				
			$childNode = $_	
				
			AddAreaNode $projectName $childNode $childTreeNode
		}
	}
}

Function AddProjectNode ($project) 
{
	$projectName = $project.Name
	$selectedNode = GetCurrentNode
		
	$childNode = $selectedNode.AddChild(); 
	$childNode.Name = $projectName;
	$childNode.Script = "AddAreaRootNodes '$projectName' | GetTFSWorkItemsForArea '$projectName'"
}

Function global:GetTFSProjectByName($projectName)
{
	$store = GetServerConnection
	[Microsoft.TeamFoundation.WorkItemTracking.Client.ProjectCollection] $projects = $store.Projects 
	$projects[$projectName]
}


#############################
## Main execution begins here

LoadTFSAssemblies

# Connect to the TFS server
$store = GetServerConnection

# Grab all projects and create a PowerGUI tree node for each one
[Microsoft.TeamFoundation.WorkItemTracking.Client.ProjectCollection] $projects = $store.Projects 

for( $i = 0; $i -le $projects.Count; $i++ )
{
	[Microsoft.TeamFoundation.WorkItemTracking.Client.Project] $project = $projects[$i]
	
	AddProjectNode $project
	Write-Output $project
}]]></script>
              <items />
            </container>
            <container id="575439c9-0046-42ee-b07c-a71f0379007d" parent="9ebf0f0a-6981-4b1d-891c-d6242d552a87" name="Browse projects by Iteration" type="Script@Microsoft.TeamFoundation.WorkItemTracking.Client.Project" returntype="Microsoft.TeamFoundation.WorkItemTracking.Client.Project">
              <script><![CDATA[Function LoadTFSAssemblies()
{
	$assembly1 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation")
	$assembly2 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
	$assembly3 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.WorkItemTracking.Client")
}

Function global:GetServerPath()
{
	$pathRoot = "HKCU:\Software\PowerGui"
	
	# Check to see if the key already exists
	if( Test-Path ($pathRoot + "\TfsBrowser") )
	{
		$reg = Get-ItemProperty ($pathRoot + "\TfsBrowser")
		$serverName = $reg.Server
		
		# If the reg key exists but it contains an empty string prompt the user to provide an address
		if( [String]::IsNullOrEmpty( $serverName ) )
		{
			$serverName = Read-Host "Team Foundation Server"
			$result = Set-ItemProperty -path ($pathRoot + "\TfsBrowser") -name "Server" -Value $serverName
		}
		
		$serverName
	}
	else
	{
		# Prompt the user for the address of the TFS server to connect to
		$serverName = Read-Host "Team Foundation Server"
		
		# Make sure the registry key exists before we try and set the value.
		if( (Test-Path $pathRoot) -ne $TRUE ) {$a = New-Item -path $pathRoot}
		if( (Test-Path ($pathRoot + "\TfsBrowser")) -ne $TRUE ) {$a = New-Item -path ($pathRoot + "\TfsBrowser")}
		
		# Set the TFS server address in the registry
		$result = Set-ItemProperty -path ($pathRoot + "\TfsBrowser") -name "Server" -Value $serverName
		$serverName
	}
}

Function global:GetServerConnection()
{
	$serverPath = GetServerPath
	[psobject] $tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($serverPath)
	$workItemStore = [Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore]
	$tfs.GetService($workItemStore)
}

Function global:GetTFSCSS()
{
	$serverPath = GetServerPath
	[psobject] $tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($serverPath)
	$cssType = [Microsoft.TeamFoundation.Server.ICommonStructureService]
	$tfs.GetService($cssType)
}

Function global:GetCurrentNode()
{
	[Quest.PowerGUI.HostFactory]::Current.Application.Navigation.CurrentItem;
}

##
# This function takes a project name and a full iteration path and queries the TFS server
# for all WorkItems in that project/iteration, pumping all results out to the console
#
Function global:GetTFSWorkItemsForIteration($projectName, $iterationPath)
{
	[Microsoft.TeamFoundation.WorkItemTracking.Client.Project] $project = GetTFSProjectByName $projectName
	[Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore] $store = $project.Store
	
	if( $iterationPath -eq $NULL )
	{
		$iterationPath = $projectName
	}
	else
	{
		$trimLength = $projectName.Length + 11
	
		$iterationPath = $iterationPath.substring($trimLength) 
		$iterationPath = $projectName + $iterationPath
	}
	
	$queryString = 
		[String]::Format("SELECT [System.Id], [System.WorkItemType], [System.AssignedTo],[System.CreatedBy], [System.Title] FROM WorkItems WHERE [System.TeamProject] = '{0}' AND [System.IterationPath] = '{1}'",
							$project.Name,
							$iterationPath)
	
	[Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemCollection] $workItemCollection = $store.Query( $queryString )
	Write-Output $workItemCollection
}

##
# This function queries the TFS server for all iteration nodes for the indicated project
# and starts the recursive process of walking the iteration nodes and creating PowerGUI
# tree nodes
#
Function global:AddIterationRootNodes($projectName) 
{
	$selectedNode = GetCurrentNode
	
	$css = GetTFSCSS

    [Microsoft.TeamFoundation.Server.ProjectInfo] $projectInfo = $css.GetProjectFromName($projectName)
	$nodes = $css.ListStructures($projectInfo.Uri);
	
	$nodes | %{ 
	
		if( $_.StructureType -eq "ProjectLifecycle" )
		{
			[System.Xml.XmlElement] $nodesElement = $css.GetNodesXml($_.Uri, $TRUE)
			$nav = $nodesElement.CreateNavigator()
			[xml] $xml = $nav.InnerXml
					
			if( $xml.Node.Children -ne $NULL )
			{
				$xml.Node.Children.Node | %{
				
					$node = $_
					AddIterationNode $projectName $node $selectedNode
				}
			}
		}
	}			
}

##
# This recursive function walk down the iteration nodes tree creating
# a new PowerGui node for each item it finds.
#
Function global:AddIterationNode {
	param($projectName, $node, $parentTreeNode) 

	$areaName = $node.GetAttribute("Name")
	$iterationPath = $node.GetAttribute("Path")
		
	$childTreeNode = $parentTreeNode.AddChild(); 
	$childTreeNode.Name = $areaName;
	$childTreeNode.Script = "GetTFSWorkItemsForIteration '$projectName' '$iterationPath'"
	
	if( $node.Children -ne $NULL )
	{
		$node.Children.Node | %{
				
			$childNode = $_	
				
			AddIterationNode $projectName $childNode $childTreeNode
		}
	}
}

Function AddProjectNode ($project) 
{
	$projectName = $project.Name
	$selectedNode = GetCurrentNode
		
	$childNode = $selectedNode.AddChild(); 
	$childNode.Name = $projectName;
	$childNode.Script = "AddIterationRootNodes '$projectName' | GetTFSWorkItemsForIteration '$projectName'"
}

Function global:GetTFSProjectByName($projectName)
{
	$store = GetServerConnection
	[Microsoft.TeamFoundation.WorkItemTracking.Client.ProjectCollection] $projects = $store.Projects 
	$projects[$projectName]
}


#############################
## Main execution begins here

LoadTFSAssemblies

# Connect to the TFS server
$store = GetServerConnection

# Grab all projects and create a PowerGUI tree node for each one
[Microsoft.TeamFoundation.WorkItemTracking.Client.ProjectCollection] $projects = $store.Projects 

for( $i = 0; $i -le $projects.Count; $i++ )
{
	[Microsoft.TeamFoundation.WorkItemTracking.Client.Project] $project = $projects[$i]
	
	AddProjectNode $project
	Write-Output $project
}]]></script>
              <items />
            </container>
            <container id="2ad35bed-8390-436b-ae06-1757e36c7000" parent="9ebf0f0a-6981-4b1d-891c-d6242d552a87" name="My open work items" type="Script@Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem" returntype="Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem">
              <script><![CDATA[Function LoadTFSAssemblies()
{
	$assembly1 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation")
	$assembly2 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
	$assembly3 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.WorkItemTracking.Client")
}

Function global:GetServerPath()
{
	$pathRoot = "HKCU:\Software\PowerGui"
	
	# Check to see if the key already exists
	if( Test-Path ($pathRoot + "\TfsBrowser") )
	{
		$reg = Get-ItemProperty ($pathRoot + "\TfsBrowser")
		$serverName = $reg.Server
		
		# If the reg key exists but it contains an empty string prompt the user to provide an address
		if( [String]::IsNullOrEmpty( $serverName ) )
		{
			$serverName = Read-Host "Team Foundation Server"
			$result = Set-ItemProperty -path ($pathRoot + "\TfsBrowser") -name "Server" -Value $serverName
		}
		
		$serverName
	}
	else
	{
		# Prompt the user for the address of the TFS server to connect to
		$serverName = Read-Host "Team Foundation Server"
		
		# Make sure the registry key exists before we try and set the value.
		if( (Test-Path $pathRoot) -ne $TRUE ) {$a = New-Item -path $pathRoot}
		if( (Test-Path ($pathRoot + "\TfsBrowser")) -ne $TRUE ) {$a = New-Item -path ($pathRoot + "\TfsBrowser")}
		
		# Set the TFS server address in the registry
		$result = Set-ItemProperty -path ($pathRoot + "\TfsBrowser") -name "Server" -Value $serverName
		$serverName
	}
}

Function GetWorkItemStoreFromServer()
{
	$serverPath = GetServerPath
	[psobject] $tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($serverPath)
	$workItemStore = [Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore]
	$tfs.GetService($workItemStore)
}

##---------------------------
## Main execution begins here

LoadTFSAssemblies

[Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore] $store = GetWorkItemStoreFromServer
	
$queryString = 
	"SELECT [System.Id], [System.WorkItemType], [System.AssignedTo],[System.CreatedBy], [System.Title] 
	FROM WorkItems WHERE [System.AssignedTo] = @me AND [System.State] = 'Active'"
	
[Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemCollection] $workItemCollection = $store.Query( $queryString )
Write-Output $workItemCollection]]></script>
              <items />
            </container>
            <container id="b1c2e2a7-b46b-450c-ab42-bc87b7f8ee48" parent="9ebf0f0a-6981-4b1d-891c-d6242d552a87" name="Change server connection" type="Script@System.String" returntype="System.String">
              <script><![CDATA[##################################
#
# Selecting this node will prompt the user to enter the address of 
# the TFS server that this PowerPack will connect to
#

Function HandleScriptTextChanged()
{
	if( $addressText.Text.Trim().Length -gt 0 )
	{
		$okBtn.Enabled = $True
	}
	else
	{
		$okBtn.Enabled = $False
	}
}

$serverName = ""
$pathRoot = "HKCU:\Software\PowerGui"

if( Test-Path ($pathRoot + "\TfsBrowser") )
{
	$reg = Get-ItemProperty ($pathRoot + "\TfsBrowser")
	$serverName = $reg.Server
}

# Create a iteration picker form
$form = New-Object Windows.Forms.Form
$form.Text = "Team Foundation Server Address"
$form.ShowIcon = $FALSE
$form.Width = 330
$form.Height = 165

# Create Label control
$label = New-Object System.Windows.Forms.Label
$label.Location = new-object System.Drawing.Point(8,33)
$label.Text = "Team Foundation Server Address:"
$label.AutoSize = $TRUE
$form.Controls.Add($label)

# Create a TextArea control
$addressText = new-object System.Windows.Forms.TextBox
$addressText.Location = new-object System.Drawing.Point(10,50)
$addressText.Size = new-object System.Drawing.Size(300, 20)
$addressText.Text = $serverName
$addressText.Add_TextChanged({HandleScriptTextChanged})
$form.Controls.Add($addressText)

# Add Ok button
$okBtn = new-object System.Windows.Forms.Button
$okBtn.Location = new-object System.Drawing.Point(185, 95)
$okBtn.Size = new-object System.Drawing.Size(50,23)
$okBtn.Text = "&OK"
$okBtn.visible = $True
$okBtn.DialogResult = "OK"
$form.Controls.Add($okBtn)
$form.AcceptButton = $okBtn

# Add Cancel button
$cancelBtn = new-object System.Windows.Forms.Button
$cancelBtn.Location = new-object System.Drawing.Size(250,95)
$cancelBtn.Size = new-object System.Drawing.Size(60,23)
$cancelBtn.Text = "&Cancel"
$cancelBtn.visible = $True
$cancelBtn.DialogResult = "Cancel"
$form.Controls.Add($cancelBtn)
$form.Add_Shown({$form.Activate()}) 

# Display the form
if( $form.ShowDialog() -eq "OK" )
{
	$serverName = $addressText.Text
		
	# Make sure the registry key exists before we try and set the value.
	if( (Test-Path $pathRoot) -ne $TRUE ) {$a = New-Item -path $pathRoot}
	if( (Test-Path ($pathRoot + "\TfsBrowser")) -ne $TRUE ) {$a = New-Item -path ($pathRoot + "\TfsBrowser")}
		
	# Set the TFS server address in the registry
	$result = Set-ItemProperty -path ($pathRoot + "\TfsBrowser") -name "Server" -Value $serverName
	
	# Let the user know what the address has been set to
	Write-Output ("Server connection set to : " + $serverName)
}
else
{
	Write-Output ("Server connection not changed. Remains as : " + $serverName)
}]]></script>
              <items />
            </container>
          </items>
        </container>
      </items>
    </container>
    <container id="1ef02fe0-c6fc-4cdc-88bc-a9e4313bee18" name="Actions">
      <items>
        <container id="7826b2ed-8ae4-4ad0-bf29-1ff0a25e0ece" name="Actions" type="NonGet">
          <items>
            <container id="11afa439-f40f-4ebd-b8b8-7cd30a1d6cb3" parent="7826b2ed-8ae4-4ad0-bf29-1ff0a25e0ece" name="Edit Work Item" type="Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem">
              <script><![CDATA[########################
#
# This script will load the WorkItemFormControl from the TFS assemblies
# and load the selected WorkItem for editing. Unfortunately there is an
# issue with loading the WorkItemFormControl from a MTA (Multi-threaded Apartment)
# context. PowerShell happens to run in MTA mode and currently there is no
# good way to get a thread started up from within PowerShell in STA mode.
#
# If anyone has any ideas about how to get around this I'd love to hear them
#

Function LoadTFSAssemblies()
{
	$assembly2 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation")
	$assembly2 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Common")
	$assembly2 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
	$assembly2 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.WorkItemTracking.Client")
	$assembly3 = [System.Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.WorkItemTracking.Controls.dll")
}

Function LaunchWorkItemEditForm( $workItem )
{
	LoadTFSAssemblies

	# Create a form to contain the WorkItem edit control
	$form = New-Object Windows.Forms.Form
	$form.Width = 650
	$form.Height = 600
	
	# Create a WorkItemFormControl 
	$workItemEditControl = New-Object Microsoft.TeamFoundation.WorkItemTracking.Controls.WorkItemFormControl
	$workItemEditControl.Dock = "Fill"
	
	# Assign the WorkItem to the editor control
	$workItemEditControl.Item = $workItem
	
	# Add the control to the form and display
	$form.Controls.Add($workItemEditControl)
	$form.Add_Shown({$form.Activate()}) 
	$form.ShowDialog() 
}

$input | %{
	
	# Launch the edit control for the first input item then break. 
	# We don't want to have millions of edit dialogs popping up
	# if the user accidentally selects all work items and hits 'Edit'
	LaunchWorkItemEditForm $_
	break;
}



]]></script>
              <items />
            </container>
            <container id="41f39bcb-bcaf-4a45-a97e-d4a33c9f387f" parent="7826b2ed-8ae4-4ad0-bf29-1ff0a25e0ece" name="Move to iteration" type="Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem">
              <script><![CDATA[Function LoadTFSAssemblies()
{
	$assembly2 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation")
	$assembly2 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Common")
	$assembly2 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
	$assembly2 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.WorkItemTracking.Client")
	$assembly3 = [System.Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.WorkItemTracking.Controls.dll")
}

Function GetServerPath()
{
	$pathRoot = "HKCU:\Software\PowerGui"
	
	# Check to see if the key already exists
	if( Test-Path ($pathRoot + "\TfsBrowser") )
	{
		$reg = Get-ItemProperty ($pathRoot + "\TfsBrowser")
		$serverName = $reg.Server
		
		# If the reg key exists but it contains an empty string prompt the user to provide an address
		if( [String]::IsNullOrEmpty( $serverName ) )
		{
			$serverName = Read-Host "Team Foundation Server"
			$result = Set-ItemProperty -path ($pathRoot + "\TfsBrowser") -name "Server" -Value $serverName
		}
		
		$serverName
	}
	else
	{
		# Prompt the user for the address of the TFS server to connect to
		$serverName = Read-Host "Team Foundation Server"
		
		# Make sure the registry key exists before we try and set the value.
		if( (Test-Path $pathRoot) -ne $TRUE ) {$a = New-Item -path $pathRoot}
		if( (Test-Path ($pathRoot + "\TfsBrowser")) -ne $TRUE ) {$a = New-Item -path ($pathRoot + "\TfsBrowser")}
		
		# Set the TFS server address in the registry
		$result = Set-ItemProperty -path ($pathRoot + "\TfsBrowser") -name "Server" -Value $serverName
		$serverName
	}
}

Function GetTFSCSS()
{
	LoadTFSAssemblies
	
	$serverPath = GetServerPath
	[psobject] $tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($serverPath)
	$cssType = [Microsoft.TeamFoundation.Server.ICommonStructureService]
	$tfs.GetService($cssType)
}

Function AddIterationRootNodes() 
{
	$css = GetTFSCSS

    [Microsoft.TeamFoundation.Server.ProjectInfo] $projectInfo = $css.GetProjectFromName($projectName)
	$nodes = $css.ListStructures($projectInfo.Uri);
	
	#add the root iteration node
	[void]$arrayList.Add($projectName)
	
	$nodes | %{ 
	
		if( $_.StructureType -eq "ProjectLifecycle" )
		{
			[System.Xml.XmlElement] $nodesElement = $css.GetNodesXml($_.Uri, $TRUE)
			$nav = $nodesElement.CreateNavigator()
			[xml] $xml = $nav.InnerXml
					
			if( $xml.Node.Children -ne $NULL )
			{
				$xml.Node.Children.Node | %{
				
					$node = $_
					AddIterationNode $node
				}
			}
		}
	}			
}

##
# This recursive function walk down the iteration nodes tree creating
# a new PowerGui node for each item it finds.
#
Function AddIterationNode($node) 
{
	$iterationPath = $node.GetAttribute("Path")

	# Iterations start with \<Project Name>\Iteration\
	if( $iterationPath.Length -gt ($projectName.Length + 11))	
	{
		$iterationShortPath = ($projectName + $iterationPath.Substring($projectName.Length + 11))
		[void]$arrayList.Add($iterationShortPath)
		
		if( $node.Children -ne $NULL )
		{
			$node.Children.Node | %{
					
				$childNode = $_	
					
				AddIterationNode $childNode
			}
		}
	}
}

Function HandleOkBtnClick()
{
	if( $iterationsCombo.SelectedItem -ne $NULL )
	{
		$iterationPath = $iterationsCombo.Items[ $iterationsCombo.SelectedIndex ].ToString()
		
		
		
		$workItems | %{
		
			$_.Open()
			$_.Fields["System.IterationPath"].Value = $iterationPath
			$_.Save
			
			$_ | fl | Out-File "c:\test.txt"
		}
		
		$form.Close()
	}
}

Function HandleCancelBtnClick()
{
	$form.Close()
}

$workItems = new-Object System.Collections.ArrayList
$input | %{
	[void]$workItems.Add($_)
}

$projectName = $workItems[0].Project.Name
$arraylist = new-Object System.Collections.ArrayList
AddIterationRootNodes

# Create a iteration picker form
$form = New-Object Windows.Forms.Form
$form.Text = "Select Destination Iteration"
$form.Width = 350
$form.Height = 150

# Create a combobox control
$iterationsCombo = new-object System.Windows.Forms.ComboBox
$iterationsCombo.Location = new-object System.Drawing.Point(20,25)
$iterationsCombo.Size = new-object System.Drawing.Size(275,25)
if($arraylist -ne $NULL -AND $arraylist.Count -gt 0)
{
	$arraylist | % {
		[void]$iterationsCombo.Items.Add($_)
	}
}

# Add Ok button
$okBtn = new-object System.Windows.Forms.Button
$okBtn.Location = new-object System.Drawing.Point(125,65)
$okBtn.Size = new-object System.Drawing.Size(50,23)
$okBtn.Text = "&Ok"
$okBtn.visible = $True
$okBtn.Add_Click({HandleOkBtnClick})
$form.Controls.Add($okBtn)

# Add Cancel button
$cancelBtn = new-object System.Windows.Forms.Button
$cancelBtn.Location = new-object System.Drawing.Size(190,65)
$cancelBtn.Size = new-object System.Drawing.Size(50,23)
$cancelBtn.Text = "&Cancel"
$cancelBtn.visible = $True
$cancelBtn.Add_Click({HandleCancelBtnClick})
$form.Controls.Add($cancelBtn)

# Add the control to the form and display
$form.Controls.Add($iterationsCombo)
$form.Add_Shown({$form.Activate()}) 
[void]$form.ShowDialog() ]]></script>
              <items />
            </container>
            <container id="21533ea3-dc3c-44d2-9b0a-f33b29eed6bc" parent="7826b2ed-8ae4-4ad0-bf29-1ff0a25e0ece" name="Attachments" type="Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem">
              <script><![CDATA[$input | %{

	$_.Attachments | %{
		
		$internetExplorer = New-object -COM InternetExplorer.Application
	
		$internetExplorer.navigate2($_.Uri.AbsoluteUri)
		$internetExplorer.width=400
		$internetExplorer.height=600
		$internetExplorer.visible = $TRUE
	}
}]]></script>
              <items />
            </container>
            <container id="c9b75170-2681-47a0-97e5-b6b86856b155" parent="7826b2ed-8ae4-4ad0-bf29-1ff0a25e0ece" name="Open vs. closed chart" type="Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem">
              <script><![CDATA[$openCounter = 0
$closedCounter = 0

$input | %{

	if( ($_.State.ToString() -eq "Closed") -or
		($_.State.ToString() -eq "Deleted") -or
		($_.State.ToString() -eq "Resolved"))
	{
		$closedCounter++
	}
	else
	{
		$openCounter++
	}
}

$internetExplorer = New-object -COM InternetExplorer.Application
	
$internetExplorer.navigate2([String]::Format("http://chart.apis.google.com/chart?cht=p&chd=t:{0},{1}&chl=Open|Closed&chs=425x325", $openCounter, $closedCounter))
$internetExplorer.width=400
$internetExplorer.height=400
$internetExplorer.visible = $TRUE]]></script>
              <items />
            </container>
          </items>
        </container>
        <container id="481eccc0-43f8-47b8-9660-f100dff38e14" name="Links" type="Get">
          <items>
            <container id="3175c3e9-b90e-4fd4-9ce3-a21564a7a53a" parent="481eccc0-43f8-47b8-9660-f100dff38e14" name="Stored queries" type="Microsoft.TeamFoundation.WorkItemTracking.Client.Project" returntype="Microsoft.TeamFoundation.WorkItemTracking.Client.StoredQuery">
              <script><![CDATA[$input | ForEach-Object {

	[Microsoft.TeamFoundation.WorkItemTracking.Client.Project] $project = $_
	[Microsoft.TeamFoundation.WorkItemTracking.Client.StoredQueryCollection] $queryCollection = $project.StoredQueries 
	
	For($i = 0; $i -le $queryCollection.Count; $i++ )
	{
		[Microsoft.TeamFoundation.WorkItemTracking.Client.StoredQuery] $query = $queryCollection[$i]
		Write-Output $query
	}
	
	break;
}]]></script>
              <items />
            </container>
            <container id="473d0a8f-35fc-434e-a766-50492aacad22" parent="481eccc0-43f8-47b8-9660-f100dff38e14" name="Work item types" type="Microsoft.TeamFoundation.WorkItemTracking.Client.Project" returntype="Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemType">
              <script><![CDATA[$input | ForEach-Object {

	[Microsoft.TeamFoundation.WorkItemTracking.Client.Project] $project = $_
	[Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemTypeCollection] $workItemTypeCollection = $project.WorkItemTypes
	
	Write-Output $workItemTypeCollection
	
	break;
}]]></script>
              <items />
            </container>
            <container id="2aade1cf-3a4b-4b62-a256-5cee62a303c9" parent="481eccc0-43f8-47b8-9660-f100dff38e14" name="Work items" type="Microsoft.TeamFoundation.WorkItemTracking.Client.Project" returntype="Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem">
              <script><![CDATA[$input | ForEach-Object {

	[Microsoft.TeamFoundation.WorkItemTracking.Client.Project] $project = $_
	[Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore] $store = $project.Store
	
	$queryString = [String]::Format("SELECT [System.Id], [System.WorkItemType], [System.AssignedTo],[System.CreatedBy], [Microsoft.VSTS.Common.Priority], [System.Title] FROM WorkItems WHERE [System.TeamProject] = '{0}'", $project.Name)
	
	[Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemCollection] $workItemCollection = $store.Query( $queryString )
	
	Write-Output $workItemCollection
	
	break;
}]]></script>
              <items />
            </container>
          </items>
        </container>
      </items>
    </container>
  </items>
</configuration>