Team Foundation Server (TFS) from Microsoft is an application lifecycle management (ALM) solution that is deployed across many development teams and organizations. After working with TFS for 3+ years, I have come to the conclusion that organizations are better off without it and should look to adopting best of breed tools (of which, I claim, TFS is not part).
This post addresses three topics: the technical flaws of TFS and its subsystems, the culture TFS encourages and strategies on how to get out.
For developers, tooling can inspire almost religious dogmatism and fanaticism. This is understandable. We work with these tools for a significant portion of our lives. Choosing the right tool for the job can decrease stress, increase productivity and make legitimate impacts on us.
Dogmatism can cut both ways and TFS is one of those topics that seems to inspire factionization. There are many people that dislike TFS. There are many people that like TFS. We'll get to the why it is so divisive in the second section, but I'm going to try to explain why TFS is not a best of breed tool. I'll start by breaking down the subsystems of TFS. However, any review of TFS would be a disservice if it did not talk about the vertical integration that TFS provides and I'll end there.
TFS Version Control
In a nutshell, this could be the worst part of TFS 2010. It is certainly the most impactful subsystem to the developer. Combine a below-par version control system with the amount of time that a developer is working with it and you have a very frustrated developer (that posts their frustations on amplicate.com!).
Frustrations with the version control system are well documented. In order to be comprehensive, though, I'll give you the digest.
TFVC is a centralized-server model that requires constant and active communication between a client (read: developer) machine and the server. If, for example, the network goes down for 1 hour, development grinds to a halt. The reason here is that TFS will mark all files as read-only on the filesystem until you have asked the server to check them out for you. If you cannot communicate to the server, you cannot checkout the files and you cannot edit them .
TFVC wants you to do everything inside of Visual Studio . When you add a file, it is best to add the file through Visual Studio's contextual menus in your solution explorer. TFS will recognize that you are adding a file and track that file for you. This is great until you need to start adding some files outside of Visual Studio. In my experience, this is usually peripheral code like batch automation scripts, build tools, XML configuration files, etc. Sometimes you use Notepad++ because its more convenient--but then you get yourself into trouble because you try to check in but TFS does not recognize the new file or that the file is edited. In that case, you need to navigate to the Source Control Explorer, add or check out the file using its contextual menus.
TFVC uses a merging solution that is heavy handed and ineffective. It can, sometimes, do automerging for a file that was edited twice. However, it prompts the developer for each file and makes them click an "Automerge" button. The default merge tool doesn't support a rather standard 4 window, 3 way merge view .
There are many other documented problems and errors with TFS. Some of those are very scary (e.g. losing check ins) but I have not personally run into them. Many of those are small but annoying things that should be fixed but does not seem likely to change in the near future. There can be, and has been, whole posts dedicated to just the issues surrounding the version control system.
TFS as Bug Tracking
TFS, as an ALM, has to handle bugs on software that has been released. Using a bug work item, someone will log a bug into the system. She will be required to fill in some details like Title, Description, "Classification", Assignee, etc.
In order to create this bug work item, you need to use either Team Explorer (through Visual Studio, most likely) or the TFS 2010 Web Interface. The obvious problem for the first scenario is that developers are the only ones likely to have Visual Studio and are only one of several groups of people that could log a bug.
The second option, TFS Web Access, is really a second class citizen. It is slow, painful and cluttered. Unless you work with it every day, you could easily become overwhelmed by the options when you just need to log a bug!
Who logs bugs? For the most part, bugs are discovered by customers and then distilled into actionable items by customer service representatives. Instead of creating bugs through an email, or through a simple web interface, the CSRs are asked to either open up Visual Studio (if they have it; a development tool!) or to use Web Access. On top of that, they are asked to fill in information that they do not know or care about. Both of these processes discourage bugs from being logged due to the pain that the CSRs experience.
TFS as Agile Project Management
Unfortunately, I cannot speak to TFS from the perspective of a waterfall or clean-room type of project management. I just do not have any experience in those areas (though, some of my "Agile" projects have definitely had some Waterfall-ish aspects to them!). I can speak, though, to its use in Agile.
From my experience, TFS is ignored by Agile teams. Instead, I have used a combination of Story Wall, Pivotal Tracker, Jira and Excel. Yes, Excel. In fact, my current project manager uses Excel instead of TFS. I do not know how she deals with the pain of Excel on a day to day basis but she finds it a better experience than to use TFS! She would much rather use a tool like Jira or Mingle  to manage the project.
This largely stems from the inflexibility of TFS as a project management tool. Agile TFS work items, by default, have only five states . Agile is about self-organizing, constantly improving teams that will change in order to make themselves better. This includes process changes as a project goes on. Even if the team went to the trouble of creating custom templates, those templates are going to have to change. TFS makes changing painful and, thus, discourages instead of enables Agile teams.
Project reporting in TFS is rather primitive. It operates on high level, structured data like Work Items. One of the more sophisticated views is the "Build Quality Indicators Report". This report is a decent start to a build quality metrics report but to get additional information you're going to have to branch out and create a custom build template.
TFS as Build System
Probably one of the under-utilized features of TFS is the build system. TFS will build every checkin akin to other build systems like Jenkins or TeamCity.
You can switch this on and TFS will run your software through a default template associated with your build type. In order to do anything different that the default template (and, believe me, you will), you'll have to go through a 15 step process to create a custom build type .
Once you have your custom build, it will now be time to create new tasks. This means that in your new build type (which is actually a C# project) you'll need to do some PrivateAssembly referencing, some obscure subclassing and some drag and drop workflow editing (in a very slow and cumbersome drap and drop interface, I might add). All of this will need to be done against a rather odd API .
I once had to write a custom build pipeline for a product I was developing. The functional tests were using a Java-based test runner (proprietary) that needed to be executed on every build. We wanted a HTML dashboard of the metrics we were running and the build times. I spent a few days getting this to work. It was extremely brittle and development was a pain. In order to test the system, I would have to write code and check it in for the build to attempt to run it. There really was no local development process for build development.
On top of that, continuous deployment (which is all the rage) requires a strong pipeline that TFS just cannot provide. While TFS has agents that can execute many builds or parts of a build in parallel, I see no worthwhile way of developing a pipeline on top of TF Build.
The elephant in the room is the vertical integration that TFS provides. It is, by far, the biggest thing that proponents will use as defense. It has been, in my experience, a big selling point for developers and organizations to use TFS.
TFS has the promise of being a drop in, all in one box solution to ALM within an organization. On top of that, it provides additional features such as a source control system and a build system that have some additional integration points into the ALM, as well.
The problem is that the TFS ALM is only compatible with one source control system and one build system. And that the TFS Build System is only compatible with one source control system. TFS is actually a package of highly incompatible software that happens to work together but with nothing else.
This is a problem because it prevents organizations from adopting best of breed tools. For sake of argument, let us assume that the TFS ALM and TF Build subsystems are first class. The TFS source control, however, needed to be replaced. With most tools, you're given the flexibility to make that decision and switch to a better tool. With TFS, you're locked in because the ALM and the TF Build subsystems require that you use TFS and only TFS.
The Microsoft Way
As an organization, you're probably going to use some bad tools at one point or another. There will always be a new hotness that makes one of the tools you use look like dinosaurs. That's okay. The main point is to Get Things Done. As long as you can do that, you'll be sitting pretty.
Some day, you plan to move on to better tools than TFS and are even in the process of doing so now. You're evaluating other ALMs and have installed TeamCity and have a few builds going. Great stuff.
TFS may be hurting you more than just technically. TFS may be a symptom of a more endemic problem. TFS, as a tool, wholehearted embraces the culture of cradle-to-grave hand holding and dispassionate development. Good developers and organizations all have one thing in common: they are hungry. They thirst for knowledge and delight in trying new things. While at work, they are never satisfied with "okay" but always strive for "better".
TFS promises several things for your organization. It will handle source control for you, it will handle project management (even giving you strict templates that you have to follow!) and strictly enforces development policies (you must associate a work item with your check in). TFS will be an install once, forget about it forever solution. It is easy and you do not have to think about it.
The problem with that promise is that these are the sorts of things that an organization should be questioning. Project Management is more of an art than a science and good project management evolves along with the project. Your source control set up should enable multiple teams to work simultaneously and less painfully (try working on TFS from India via VPN). Your bug tracking system should be so dead simple that CSRs are creating bugs for every tiny UI hiccup that customers experience. Your deployment pipeline should take under an hour from developer check in to production-like environment.
Instead, the teams that work with TFS will use the default templates, default build pipeline and ignore the pain of a centralized source control model. I have also seen the lack of good configuration management in an organization because someone was able to one-click install TFS on a server and then the organization can trick itself into thinking that configuration management is a solved problem. The teams gladly ignore the "not programming" part of delivering software and put their heads in the sand.
This is not only TFS's fault, though. There is a whole approach to software development that embraces the set-it-and-forget-it or cradle-to-grave software development setup. The approach discourages the use of products that are not given to development teams. Organizations with symptoms of this can be found using tools and frameworks like Entity Framework and DevExpress. Your code is likely very weakly tested. You may not have a clear path to production. Deployment can consist of manually copying DLLs or hand crafting an MSI. This is a bad state to be in and the only way to get yourself out of this hole is to start thinking wholistically about software development.
In order to get yourself out of the TFS hole, you're going to have to endure a bit of pain. However, instead of doing one big switchover, there may be better ways of incrementally moving away from TFS.
The first thing that is helpful is to establish a team that can make decisions on configuration management across the organization. In ThoughtWorks, we call these kinds of roles "DevOps" because it often involves both the development part of the IT organization as well as the operations side. Appoint someone to be the leader for these kinds of decisions and as someone that can enforce a decision for the organization as a whole.
Then, set up a Jenkins  server and start piloting a new continuous integration approach. Jenkins has a TFS plugin that seems to work fairly well. It is likely that, if using TFS only, you are not using the build system anyway and that a switch to Jenkins will be a painless exercise.
Use Jenkins to start thinking critically about how to deliver software. You'll find that it is a non-trivial task. You'll need performance, UAT and staging environments. You'll need to be able to deploy your software automatically. You will need to understand how to get your software from the source code checked in to TFS to a deployed, usable application for your users.
After you've got the ball rolling on Jenkins, it is time to move away from TFS version control. I would highly recommend to switch to a distributed version control system like Mercurial or Git . This is a non-trivial task and will be painful. However, you can mitigate that pain.
You will save yourself a ton of pain by using a Linux server for either Git or Mercurial. While both work on Windows, they both perform better on Linux. VMWare has appliances that you can drop in which are already set up. There is also a turn key linux distribution for these systems . If you can swing it, though, the best DVCS hosting solutions are actually in the cloud .
Start by creating a pilot program that uses your new version control system and creating a small group of your developers that can be the evangelists within your organization. If you have people that are particularly passionate about the new source control system (they aren't hard to find!), use them as your experts. Train them on the new pilot program and allow them to discover the positives and negatives about the system.
After version control, TFS is now left as a bug tracker and project management tool. It isn't particularly good at either but chances are that your organization is pretty entrenched with these tools. Everyone knows how to use it and will resist any large scale changes.
I've little experience in this area and I imagine that this will be painful, as well. The best way to get your data out of TFS seems to be to export it to Excel. From there, you may have to re-enter all data into a new system. This is a slow and painful process, I imagine.
As far as alternatives to TFS, there are many. I've used Jira, Redmine and Mingle successfully . I think this will depend largely on your organization's needs and that the transition here will need larger buy in from other departments. For example, it is likely that your CSRs are using TFS to enter in bugs.
Do not use TFS. It harms your organization and is extremely painful to leave. Vertical integration is another word for "lock in". Only through the hard work of some open source developers is there any lateral integration with TFS (e.g. Jenkins) and that is very likely to stay true.
One thing to note is that TFS plans to fix everything in their next release. Do not be tempted. TFS has historically been a bad system to work with and the Microsoft solution should not garner loyalty until it has proven itself to be a viable alternate system.
 There is a solution to temporarily remove TFS bindings, but it is an unintuitive and clunky process. It can also lose changes when re-establishing a connection to the server in some rather unpredictable ways.
 Some other IDEs are supported through Visual Studio Everywhere. This gets around some of the tool support problems. However, this still leaves things like copying files into the source tree very clunky.
 A 4-window, 3-way merge will show you 4 different files (or, rather, the same file in 4 different states). It will show you the "base" which is the common, shared file state. It will show you "mine" and "other". And, it will show you "output". There are tools that can be configured with TFS that will do this correctly.
 Full Disclosure: I work at ThoughtWorks. Mingle is a ThoughtWorks Studios product.
 Full Disclosure: Again, I work at ThoughtWorks. Mingle is a ThoughtWorks Studios product.