MSBuild Item Management Patterns
Canonical patterns for working with item groups, from Microsoft.Common.CurrentVersion.targets.
Include / Remove / Update — Three Operations
Include — Add Items
Remove — Subtract Items
Update — Modify Existing Items
Update does not add items — it only modifies items already in the group.
Item Batching — %(Metadata)
When %(Metadata) appears in target attributes or task parameters, MSBuild batches execution per unique metadata value.
Target-level batching (Outputs)
Task-level batching
Per-item filtering with Condition
Batching rules
%(Metadata)inConditionorOutputs→ target batches per unique value.%(Metadata)in task parameters → task batches per unique value.- Do not mix
%()from different item groups in the same expression — this causes a cross-product (see Common Pitfalls).
Item Transforms — @(Item->'expression')
Transforms create new item lists by applying an expression to each item:
Exclude Pattern — Set Subtraction on Include
Exclude only works on Include — it cannot be used with Update or Remove.
Conditional Item Inclusion
PrivateAssets on Tool/Analyzer Packages
Common Pitfalls
Cross-product batching
Referencing %(Metadata) from two different item groups creates O(N×M) executions:
Generated files in source tree
Write to $(IntermediateOutputPath) (obj/), not the source directory. Source-tree generation pollutes version control and can cause duplicate compilation via globs.
Missing FileWrites
Every file created during a target must be added to @(FileWrites) for dotnet clean support.


