A question came up recently about a common problem in organizations that utilize Team Build. The problem was that there are some common Properties or Targets that must be added to every build. They want to make it as easy as possible to ensure that these Properties/Targets are added. As is usual, there were some constraints. The first is that the Microsoft.TeamFoundation.Build.targets is off-limits to modification. This is a generally accepted "best practice" as Microsoft does not guarantee that this file will remain the same between versions, and in fact has changed between TeamBuild 2005 and TeamBuild 2008. The second constraint was that they wanted a way to add these "common elements" without having to go and manually check-out and modify each and every TFSBuild.proj file.
A solution that meets these constraints and solves the problem is to modify the Visual Studio template that is used to create the TFSBuild.proj files when you create a new team build type.
IMPORTANT: This template is in the PrivateAssemblies folder for Visual Studio. As such, it can and likely will be overwritten during Visual Studio maintenance (e.g. Service Packs or KB updates). As such, any changes you make here may be lost so it is important to check the resulting TFSBuild.proj file after the wizard ends. Just like the Microsoft.TeamFoundation.Build.targets file, it is not a best practice to modify these files.
The template can be found in:
[VS2005] C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\1033\tfsbuild.proj
[VS2008] C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\1033\tfsbuild.proj
Below are the (heavily edited) contents of the VS 2005 template. As you can see, some of the values are static and some contain replaceable parameters (like Description) which are updated after the New Team Build Type wizard closes.
To add your common Targets and Properties all you have to do is edit this file and then install it on each machine that will be creating Team Build Types. So if you always need to override the BeforeGet target, all you have to do is put your override target into a custom target file (say MyCustomBuild.targets) and then Import it after the Microsoft.TeamFoundation.Build.targets Import (like below). To add custom Properties or ItemGroups, just add them right into the Template file at the appropriate location.
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!-- COMMENTS REMOVED -->
<!-- Do not edit this -->
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v8.0
\TeamBuild\Microsoft.TeamFoundation.Build.targets" />
<!-- My Corporate Customizations -->
<Import Project="$(MSBuildExtensionsPath)\MyCompany\MyCustomBuild.targets" />
<PropertyGroup>
<!-- PUT CUSTOM PROPERTIES HERE -->
<MyCustomProperty>ACustomPropertyValue</MyCustomProperty>
</PropertyGroup>
<ProjectExtensions>
<!-- DESCRIPTION
The description is associated with a build type. Edit the value for making changes.
-->
<Description>$description$</Description>
<!-- BUILD MACHINE
Name of the machine which will be used to build the solutions selected.
-->
<BuildMachine>$build machine name$</BuildMachine>
</ProjectExtensions>
<PropertyGroup>
<!-- TEAM PROJECT
The team project which will be built using this build type.
-->
<TeamProject>$Team Project name$</TeamProject>
<!-- BUILD DIRECTORY
The directory on the build machine that will be used to build the
selected solutions. The directory must be a local path on the build
machine (e.g. c:\build).
-->
<BuildDirectoryPath>$Build Directory (c:\build)$</BuildDirectoryPath>
<!-- DROP LOCATION
The location to drop (copy) the built binaries and the log files after
the build is complete. This location has to be a valid UNC path of the
form \\Server\Share. The build machine service account and application
tier account need to have read write permission on this share.
-->
<DropLocation>$drop location (e.g. \\Server\share)$</DropLocation>
<!-- TESTING
Set this flag to enable/disable running tests as a post build step.
-->
<RunTest>$true/false$</RunTest>
<!-- WorkItemFieldValues
Add/edit key value pairs to set values for fields in the work item created
during the build process. Please make sure the field names are valid
for the work item type being used.
-->
<WorkItemFieldValues>Symptom=build break;Steps To Reproduce=Start the build using Team Build</WorkItemFieldValues>
<!-- REMAINING PROPERTIES REMOVED -->
</PropertyGroup> <!-- REMAINING ITEMGROUPS REMOVED -->
</Project>
Just remeber that you have to install the updated Template tfsbuild.proj file to each machine that will create new Team Build types. Also note that this will not do anything for Team Build types that have already been created, just new ones.
Many thanks to Team System MVPs Neno Loje and Marcel De Vries for the question and the answer, respectively.
Edited: Added Caveat section warning about use of this technique.