I’m currently working at a client that requires some source code to compile in Unix - as their major systems are Unix based with new development being done in .NET. The great thing about the project is that they have are trying to consolidate everything into TFS as the single source of truth (it’s mostly there).

To get the unix stuff going I’ve customized the DefaultTemplate.xaml and added an extra InvokeProcess that calls a PowerShell script to copy files to Unix using Pscp (for secure remote copy), compile code using Plink (allows remote command execution over SSH) and finally copy the Unix binaries back to the build server.


The PowerShell script takes in a number of arguments like remote server details, remote paths, usernames etc. So obviously we don’t want these being set via the arguments property for the InvokeProcess activity because:

  • Need to check out and modify the build template and checkin
  • The build workflow isn’t exactly the nicest thing to modify 
  • Can’t reuse the template for other environments (UAT and Production)
  • Can’t quickly make changes and queue a new build

What you should do instead is to define new Arguments for your template.


These argument can then be used in your workflow activities such as the InvokeProcess activity I used for PowerShell


You can also expose them in the Build Definition editor by configuring the Metadata argument from above.


Now these variables are easily configured in the Build Definition Editor.


One really cool feature of this is that the build fails when the Unix compile fails!


The other cool features is we can then then enable gated checkins !!! Not only do we get no more broken builds for .NET code, but no more breaking builds for Unix code either!