大きすぎてコメントとして返信できません。
空である理由は、他の質問と同じです-評価順序。コードは、ターゲットに到達する前に評価され、トークン化されます。ここで値を設定し、プロパティを設定すると思います。
タスクで何を達成しようとしているのか理解できたら、以下の例を見て、それらをプロパティとして渡し、出力として渡すだけです。
とはいえ、最初にプロパティ関数を調べて、多くの問題を回避する必要があると思います。
http://msdn.microsoft.com/en-us/library/dd633440.aspx
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="Foo" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<SourceStr Required="true" Output="true" />
<Pattern Required="true" />
<Value Required="true" />
<Macros ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true" />
</ParameterGroup>
<Task>
<Using Namespace="System.Linq" />
<Using Namespace="System.Text.RegularExpressions" />
<Code Type="Fragment" Language="cs">
<![CDATA[
var regex = new Regex(Pattern);
var matches = regex.Matches(SourceStr).Cast<Match>().Select(m => m.Value).ToList();
matches.ForEach(m => Log.LogMessage("{0} -> {1}", m, Value));
Macros = matches.Select(m => new TaskItem(m)).ToArray();
SourceStr = regex.Replace(SourceStr, Value);
]]>
</Code>
</Task>
</UsingTask>
<Target Name="Foo">
<PropertyGroup>
<SourceStr>Bar</SourceStr>
<Value>z</Value>
</PropertyGroup>
<Message Text="in $(SourceStr)" />
<Foo SourceStr="$(SourceStr)" Pattern="r$" Value="$(Value)">
<Output TaskParameter="SourceStr" PropertyName="SourceStr" />
<Output TaskParameter="Macros" ItemName="Macros" />
</Foo>
<Message Text="out $(SourceStr)" />
<Message Text="sans %(Macros.Identity)" />
</Target>
</Project>