Он должен вызываться один раз для экземпляра MSBuild, для каждого набора параметров. Team Build в некоторых случаях выделяет отдельные экземпляры MSBuild (например, если вы предоставляете более одной конфигурации решения). Но это, вероятно, не поможет вам.
Более применимый к вашему сценарию, MSBuild перезапустит задачу, если вы вызовете ее с другим набором параметров. Если вы копируете два разных набора файлов, это звучит как функция, которую вы ищете.
<MSBuild Project=".\CommonStuff.targets" Targets="CopyFiles" Properties="Location=1" />
<!-- .... -->
<MSBuild Project=".\CommonStuff.targets" Targets="CopyFiles" Properties="Location=2" />
Другое решение состоит в том, чтобы преобразовать функциональность в задачу вместо цели. Несмотря на то, что все еще существуют декларативные и процедурные особенности, Задачи ведут себя гораздо ближе к тому, что вы считаете «функцией» из более знакомых языков.