Use local NuGet file repository to use NuGet on a Build Server that has no access to the webs.


Scott Hanselman has blogged about using your local NuGet cache as your private local NuGet server in case your connection is down. And that works great when you're working locally. When working with Team Build you have multiple options, one is to enable Package restore and use Nugetter to have Team Build download the files during build, the other is to check your packages into sourcecontrol.

We had configured Nugetter on our previous build server and on all the local workstations, but a recent change in VPN's, DMZ's and other infrastructure stuff, the Build server has ended up behind a firewall that is blocking outgoing connections... So all our builds started failing.

Since this was going to be fixed again soon, we decided to apply the same trick Scott used to work locally to our build server. One of the developers has copied the local NuGet cache over to the build server and we've added the following item to the MsBuild Commandline Arguments:


This will instruct NuGetter to look in that location for its packages during the package restore phase.

Now when the internet connection has been restored, removing this line will resume normal operation. Until then we can still build :).

Update Build Quality and Keep Indefinitely in TFS from the commandline

As you probably know, TFS keeps all kinds of data behind when it finishes an automated build. Test Results, the stuff it copied to the drop folder, symbols etc. And by default it will keep the last 10 builds of data around and then starts cleaning up.

When you deploy a build to production, you don't want TFS to delete the symbol files and you might want to retain the test results etc as well. On the Build Detail screen, you can click a link to tell TFS you want to 'Retain the build indefinitely'.

This option cannot be set from the commandline, which is a pity when you want to ensure this is set correctly once your automated deployment process picks up the build and does stuff with it.

So I've written a little utility which handles this for you.

The actual piece of code is very simple and straightforward:

  1. Connect to TFS
  2. Request the build
  3. Change the options
  4. Save the result

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using CommandLine;
using CommandLine.Text;

using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Client.CommandLine;

namespace TfsBuildUtil
    class Program
        private static CommandlineParams commandlineArgs;

        static void Main(string[] args)
            commandlineArgs = new CommandlineParams();
            bool parseresult = CommandLine.Parser.Default.ParseArgumentsStrict(
                () => Console.Write(commandlineArgs.GetUsage()));
            if (parseresult)
                var server = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(commandlineArgs.ProjectCollection));

                var buildserver = server.GetService<IBuildServer>();
                var build = buildserver.GetBuild(new Uri(commandlineArgs.BuildUri));

                bool save = false;

                if (commandlineArgs.Quality != null)
                    if (!string.Equals(build.Quality, commandlineArgs.Quality, StringComparison.CurrentCulture))
                        build.Quality = commandlineArgs.Quality;
                        save = true;

                if (commandlineArgs.KeepForever.HasValue)
                    if (build.KeepForever != commandlineArgs.KeepForever.Value)
                        build.KeepForever = commandlineArgs.KeepForever.Value;
                        save = true;

                if (save)
                    buildserver.SaveBuilds(new[] { build });

    public class CommandlineParams
        [Option("collection", HelpText = "The project collection Uri", Required = true)]
        public string ProjectCollection { get; set; }

        [Option("build", HelpText = "The build uri", Required = true)]
        public string BuildUri { get; set; }

        [Option("quality", HelpText = "Quality to set", Required = false)]
        public string Quality { get; set; }

        [Option("keep", DefaultValue=false, HelpText = "Set keep forever", Required = false)]
        public bool? KeepForever { get; set; }

        public string GetUsage()
            var help = new HelpText
                Heading = new HeadingInfo("Tfs Build Utility", "1.0"),
                Copyright = new CopyrightInfo("Jesse Houwing", 2012),
                AdditionalNewLineAfterOption = true,
                AddDashesToOption = true

            if (LastParserState.Errors.Count > 0)
                var errors = help.RenderParsingErrorsText(this, 2);

            return help;

        public IParserState LastParserState { get; set; }

The commandline will look like this:

tfsbuildutil --collection http://localhost:8080/tfs/DefaultCollection --build vsts:///Build/Build/1234 --keep true --quality "Deployed to Production"
Download the solution here.

Connecting Team Explorer Everywhere to TFS results in Certificate error


When you're trying to connect Team Explorer Everywhere (or any other Java-based application for that matter) to Team Foundation Server you might run into the following, very helpful, message:

An error occurred:
     PKIX path building failed:
     unable to find valid certification path to requested target


Most Reading