Scripting in the Cross-Platform Command-Line Client for Team Foundation Server

Would you like to automate tasks, such as checking in and checking out source code? You can use either external or internal automation to get the job done. First, let’s review these two modes of automation. Or, you can skip directly to the pros and cons.

External automation

External automation configures another process to invoke the tf command-line tool repeatedly with fully contextual arguments each time. You don’t need any special syntax to enable this mode. You can use one of the following external processes to implement this method:

  • A Unix shell, such as sh, ksh, bash, or csh

  • Perl or another programming language that is used for scripting

  • Apache Ant or another build-oriented tool

  • Any other tool that can start the tf program and supply arguments

Internal automation

Internal automation configures the tf command-line tool to drive the automation process and interpret a command file that is passed as an argument. You can invoke internal automation by supplying the @ symbol immediately followed by a local path to a command file. Any additional arguments that you supply in this command line are available to commands in the command file as positional arguments.


To process standard input as your command file, supply the @ symbol with no file name following it (tf@). The input stream is interpreted as text according to your platform's default encoding and character set.

The following command file gets the specified version of a file and prints detailed historical information about that version.

# This line is ignored because it is a comment.
get "-version:%2" -force "%1"
history -format:detailed "-version:%2" "%1"

The command file, which is named /home/john/get-and-history.tfc, expects two positional arguments, so you can run it like the following example shows:

tf @/home/john/get-and-history.tfc README.doc C5087

The first argument, README.doc, is substituted for %1 when each line is interpreted. C5087 is substituted for %2.


In the command file, both positional arguments are surrounded by double quotation marks because their substituted values may contain spaces (for example, a file name or a date version specification).

The format of the command file can be described by the Extended Backus-Naur Form (EBNF):

command file ::= { line } ;
line ::= comment line | blank line | action line , EOL ;
comment-line ::= "#" | "rem" , { ? any non-EOL character ? } ;
blank line ::= { ? any whitespace character ? };
action line ::= tf command , [ { white space , tf option } ] , [ { white space , tf free argument } ] ;
tf command ::= ? any tf command ?
tf option ::= ? any tf option ? | positional argument ;
tf free argument::= ? any tf free argument ? | positional argument ;
positional argument::= "%" , non-zero digit , [ { digit } ] ;
EOL ::= ? your platform's EOL character or sequence ?
white space ::= { ? any non-EOL whitespace character ? }
digit ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
non-zero digit ::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
  • tf command can be any valid tf command, such as get, workfold, and workspace.

  • tf option can be any valid tf option, such as -login, -profile, and -format.

  • tf free argument can be any string that is intended as a free argument to tf, such as a server path and a local path.

  • positional argument is a placeholder for text that is substituted from the outer tf command-line arguments. The number is a positive integer that corresponds to the index of the command-line argument that you want to substitute, such as "%1" and "%2". %1 refers to the first argument. You can use positional arguments as options or free arguments and in any order after the command.


Use double quotation marks to surround options and arguments that contain spaces. For example, use “-version:LRelease 2.1” for a label specifier, “$/Inventory/Client Project/main.c” for a free argument, and "%1" for a positional argument that may contain spaces. Only double quotations denote option boundaries in command files. Single quotations are interpreted literally. To specify a literal double quotation in your action line, you must use two double quotations together (""). Quoting rules inside command files may differ from the rules that your shell uses because your shell does not parse the lines in the command file.

Pros and cons of the two methods

So which method should you use—the external or internal automation? Let’s look at the pros and cons of each method:

External automation

Internal automation


  • It’s more flexible because it can run not only tf commands, but other commands.

  • It’s simple. If you’re familiar with the external process or language, you invoke the tf command-line tool the same way as any other command-line process.

  • It’s easy to debug. If some commands don’t run as you expect, you don’t have to change the commands at the command-line for diagnosing problems.

  • It’s faster than the external method. Because the Java virtual machine is loaded only once and the command-line tool can re-use its connections to the server, you can execute multiple commands in a command file more quickly than if you run each command separately.


  • It’s slower than internal automation. For each command that you run, the CPU must spend time starting the Java virtual machine and preparing to run the client.

  • The external process must detect errors. If the external process doesn’t test the exit code of each execution, the process might miss an error.

  • It can be more cumbersome to program. The external process must supply all relevant options each time that it runs the tf command-line tool, and the arguments might require special quoting or escaping.

It’s less flexible than external automation. Here’s why:

  • You can specify only tf commands in the command file, so you might have to write multiple command files and run each of them if you want to perform other tasks between tf commands.

  • Execution stops at the first error condition that you encounter. You cannot force the tool to skip or ignore any error condition.

  • You might find that dealing with normal or error output is more complicated. A process that is running the tool with internal automation might not be able to determine which line in the command file produced which part of the normal output.

See Also

Other Resources

Command-line Reference (Team Explorer Everywhere)