title: In MSBuild, how do I aggregate an ItemGroup (specifically, find the largest number in the metadata of a group?)
body: <p>I have tried using a batch target to batch by the metadata field that contains the number:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  
  &lt;Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
  
    &lt;PropertyGroup&gt;
      &lt;HighestNumber&gt;0&lt;/HighestNumber&gt;
    &lt;/PropertyGroup&gt;
  
    &lt;ItemGroup&gt;
      &lt;TextFiles Include="*.txt" /&gt;
      &lt;TextFiles Update="*.txt"&gt;
        &lt;Number&gt;%(TextFiles.Filename)&lt;/Number&gt;
      &lt;/TextFiles&gt;
    &lt;/ItemGroup&gt;
  
    &lt;Target Name="SetUpMyStuff"&gt;
      &lt;Message Importance="High" Text="HighestNumber: $(HighestNumber)"/&gt;
      &lt;CallTarget Targets="FindLargerNumber" /&gt;
      &lt;Message Importance="High" Text="HighestNumber: $(HighestNumber)"/&gt;
    &lt;/Target&gt;
  
    &lt;Target Name="FindLargerNumber"&gt;
      &lt;CreateProperty Value="$([System.Math]::Max($(HighestNumber), %(TextFiles.Number)))"&gt;
        &lt;Output PropertyName="HighestNumber" TaskParameter="ValueSetByTask" /&gt;
      &lt;/CreateProperty&gt;
      &lt;Message Importance="High" Text="HighestNumber: $(HighestNumber)"/&gt;
    &lt;/Target&gt;
  
  &lt;/Project&gt;
  </code></pre>
  
  <p>Here's the diagnostic output:</p>
  
  <pre><code>1&gt;  Using "Message" task from assembly "Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
  1&gt;  Task "Message"
  1&gt;    Task Parameter:Importance=High
  1&gt;    Task Parameter:Text=HighestNumber: 0
  1&gt;    HighestNumber: 0
  1&gt;  Done executing task "Message".
  1&gt;  Using "CallTarget" task from assembly "Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
  1&gt;  Task "CallTarget"
  1&gt;    Task Parameter:Targets=FindLargerNumber
  1&gt;    Target "FindLargerNumber" in file "e:\Projects\BaseLibrary\Test.targets":
  1&gt;      Using "CreateProperty" task from assembly "Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
  1&gt;      Task "CreateProperty"
  1&gt;        Task Parameter:Value=0
  1&gt;        Output Property: HighestNumber=0
  1&gt;      Done executing task "CreateProperty".
  1&gt;      Task "CreateProperty"
  1&gt;        Task Parameter:Value=1
  1&gt;        Output Property: HighestNumber=1
  1&gt;        The property "HighestNumber" with value "0" is being overridden by another batch. The property is now: "1"
  1&gt;      Done executing task "CreateProperty".
  1&gt;      Task "CreateProperty"
  1&gt;        Task Parameter:Value=10
  1&gt;        Output Property: HighestNumber=10
  1&gt;        The property "HighestNumber" with value "1" is being overridden by another batch. The property is now: "10"
  1&gt;      Done executing task "CreateProperty".
  1&gt;      Task "CreateProperty"
  1&gt;        Task Parameter:Value=2
  1&gt;        Output Property: HighestNumber=2
  1&gt;        The property "HighestNumber" with value "10" is being overridden by another batch. The property is now: "2"
  1&gt;      Done executing task "CreateProperty".
  1&gt;      Task "CreateProperty"
  1&gt;        Task Parameter:Value=3
  1&gt;        Output Property: HighestNumber=3
  1&gt;        The property "HighestNumber" with value "2" is being overridden by another batch. The property is now: "3"
  1&gt;      Done executing task "CreateProperty".
  1&gt;      Task "CreateProperty"
  1&gt;        Task Parameter:Value=4
  1&gt;        Output Property: HighestNumber=4
  1&gt;        The property "HighestNumber" with value "3" is being overridden by another batch. The property is now: "4"
  1&gt;      Done executing task "CreateProperty".
  1&gt;      Task "CreateProperty"
  1&gt;        Task Parameter:Value=5
  1&gt;        Output Property: HighestNumber=5
  1&gt;        The property "HighestNumber" with value "4" is being overridden by another batch. The property is now: "5"
  1&gt;      Done executing task "CreateProperty".
  1&gt;      Task "CreateProperty"
  1&gt;        Task Parameter:Value=6
  1&gt;        Output Property: HighestNumber=6
  1&gt;        The property "HighestNumber" with value "5" is being overridden by another batch. The property is now: "6"
  1&gt;      Done executing task "CreateProperty".
  1&gt;      Task "CreateProperty"
  1&gt;        Task Parameter:Value=7
  1&gt;        Output Property: HighestNumber=7
  1&gt;        The property "HighestNumber" with value "6" is being overridden by another batch. The property is now: "7"
  1&gt;      Done executing task "CreateProperty".
  1&gt;      Task "CreateProperty"
  1&gt;        Task Parameter:Value=8
  1&gt;        Output Property: HighestNumber=8
  1&gt;        The property "HighestNumber" with value "7" is being overridden by another batch. The property is now: "8"
  1&gt;      Done executing task "CreateProperty".
  1&gt;      Task "CreateProperty"
  1&gt;        Task Parameter:Value=9
  1&gt;        Output Property: HighestNumber=9
  1&gt;        The property "HighestNumber" with value "8" is being overridden by another batch. The property is now: "9"
  1&gt;      Done executing task "CreateProperty".
  1&gt;      Task "Message"
  1&gt;        Task Parameter:Importance=High
  1&gt;        Task Parameter:Text=HighestNumber: 9
  1&gt;        HighestNumber: 9
  1&gt;      Done executing task "Message".
  1&gt;    Done building target "FindLargerNumber" in project "BaseLibrary.csproj".
  1&gt;  Done executing task "CallTarget".
  1&gt;  Task "Message"
  1&gt;    Task Parameter:Importance=High
  1&gt;    Task Parameter:Text=HighestNumber: 0
  1&gt;    HighestNumber: 0
  1&gt;  Done executing task "Message".
  </code></pre>
  
  <p>HighestNumber isn't getting the accumulated highest number, it's getting stomped by each batched target and then it is back to 0 after all the batched targets are called.</p>
  
  <p>How can I get the highest number into a property?</p>