TFS Delete Work Items Tool

I created a small tool to Permanently Delete TFS Work-Items from Team Foundation Server Database, I found some old tools but it doesn’t work with TFS 2013 and the source code was not available so, I decide to create a new one and share the source code.

Download the tool from Visual Studio Gallery

Visit the source code on CodePlex

This tool physically deletes work items from a Team Foundation Server, use it at your own risk



Extending the customization of TFS Process Template

We can customize TFS process template by modifying the definition for different process template items (XML files), like….Work-Items, Process Configuration, Categories, Global List, Global Workflow, etc.

The XML customization includes:

  • Adding more fields
  • Adding more rules
  • Adding more states
  • Modifying many configurations for how the displaying and the performing of  TWA (Team Web Access)

This could give us many possibilities but……. sometimes we need more than just adding  fields or rules…..sometimes we need real programming capabilities, such as getting the current value from a Work-Item and put it in another Work-Item or just calculate some Work-Items values together or changing Work-Item’s filed based on a change from a filed in another Work-Item, so how we can do that?

We have 3 options:

1.We can use a TFS server-side plugin which run within the application pool of the TFS

How to create a TFS Server Side Plugin

2.Register a web service by subscribing for TFS Service that based on SQL Server notification

How to Subscribe to TFS Event Model

3.We can also create a custom control that do that. However, this will not work for TWA (Team Web Access) or in Excel or any other client unless we will create a custom control for TWA and find a way for other clients as well.

 Custom Controls for TFS Work Item Tracking




Local and Remote Debugging for TFS Server Plugin

It’s very important to be able to debug your code, so how to use Visual Studio to debug a processHow to use Visual Studio to Remote Debug a process?

Here I will explain how to debug TFS Server Side Plugin using local and remote computer.

For how to create a TFS Server Side Plugin in the first place, click here

(Local Debugging using Visual Studio)
Local computer with TFS AT (Application Tire) and Visual Studio installed


(Remote Debugging using Visual Studio)
Remote computer with only Visual Studio installed

Subscribe to TFS Event Handler using a TFS Plugin

There are many good posts on the internet for how to create TFS Plugin, how to use TFS Event Handler and how to implement ISubscriber interface but I always prefer to have a small video with some tips

Useful links

How to subscribe for TFS Event that based on SQL Server notification service

The list of Server Side Events

Quick overview about how and why to use NLog

I needed to use a Loggin Framework, every time using loggin frameworks, it ends up with wasting some hours, because the configuration that makes me feel it’s better to create my own :-), I already started to create a small one but I found this is exactly re-enventing the wheel so I decide to give some times for different Loggin frameworks’s configurations.

Log4Net, I used that one because I found it has been used for some projects we have, it took all the day for fixing up some configurations errors that I found at the end they are bugs, I needed to make some workarounds to fix them. I don’t recommended anyone to use this framework as it not updated from long time ago (2006).

NLog, it was very simple, very nice …I decide to summarize my overview about it:

Here are the steps to use NLog:

  • Add reference to NLog framework using NUget (PM>Install-Package NLog)
  • Add config file using NUget (PM> Install-Package NLog.Config)
  • Add at least one target in the Target section in the config file
  • Add at least one rule in the Rules section that use any target from the Target section
  • Create an instance of the Logger class inside the class you want to use NLog
     private static readonly Logger Logger = LogManager.GetCurrentClassLogger() 
  • Call any method of Logger object (Log, Trace, Debug, etc..)


  • NLog tutorial
  • All Target types
  • All Layouts Renders
  • we can make combinations for target and rules for e.x,
    • We can use one target for each rule—> Error in Event Log, Info in a File
    • We can use multiple rules for the same target —> Error and Info in the same File
    • We can use multiple targets for the same rule —> Error and Info in both Event Log and in the same File or even in many Files


Here is the config file with some notes and description of some elements and attributes

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns=""

 for information on customizing logging rules and outputs.
 <target name="logfile" xsi:type="File" fileName="file.txt" />
 <target name="console" xsi:type="Console" />

 <target name="errors" xsi:type="File" fileName="ErrorLog.txt"
 layout="Caller: ${callsite:className=true:fileName=true:includeSourcePath=true
 :methodName=true} ${newline} LogDirectory: ${nlogdir}
 ${newline} Process: ${processname} ${newline} ${longdate}
 ${message} ${exception:format=tostring} "/>

 <!-- add your targets here -->

 <target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
 layout="${longdate} ${uppercase:${level}} ${message}" />

name >>>>> 
Name of the target to be used in the Rules section

xsi:type >>>>> 
There are many types e.x, File, EventLog, Database
Mail, Messagebox and many others
The list of all types:
fileName >>>>> 
If the type is a file then we need to provide a file name,
The the default is the place where the program executed but
we can put any path and it support NUC (Network) too \\machine\sharedFolder
layout >>>>> 
How and what data we want to include in the logging message,
It has many place holders that start with "$" each placeholder has 
itsown attributes E.x: ${processname}, ${newline}, {message}, we 
can include string between the placeholders e.x: $(processname} this 
is string ${message},the list of 
all layouts:




 <logger name="*" minlevel="Trace" writeTo="logfile" />
 <logger name="*" minlevel="Trace" writeTo="errors" />
 <logger name="*" minlevel="Info" writeTo="console" />

 <!-- add your logging rules here -->

 <logger name="*" minlevel="Trace" writeTo="f" />

name >>>>> 
Name of the Class that has the Logger object,
* means all classes

minlevel >>>>> 
Trace, Debug, Info, Warn, Error, Fatal
If we put the Trace this will show all of them
If we put Info, this will show (Info, Warn, Error, Fatal)

writeTo >>>>> 
Target name, pick it from the Target section