Search syntax quick reference

The same query syntax is used by Structured Log Viewer search and by BinlogMcp.

Queries are made from space-separated terms. Terms are combined with AND: every term must match unless you use a scoped expression such as under(...) or not(...).

Contents:

Basics

Find text anywhere

Unquoted words are case-insensitive substring matches.

Copying file

Matches nodes containing both Copying and file.

Find an exact phrase

Use quotes when the words must appear together.

"Copying file"

Matches the literal phrase.

Match a whole single word

Quotes around one word turn off substring matching.

"Csc"

Matches Csc exactly, not every longer string containing those letters.

Node Kind Filters

Start with a $kind token when you already know what kind of thing you want. This keeps broad text searches from drowning you in messages.

TokenUse it for
$projectProject execution nodes. The same project can appear multiple times for different target frameworks, target lists, or MSBuild task calls.
$projectevaluationEvaluation nodes. Use these to inspect evaluated properties, items, imports, and preprocessed XML.
$targetMSBuild targets.
$taskTask invocations. Combine with a task name, for example $task Csc.
$error, $warning, $messageBuild diagnostics and log messages.
$property, $item, $metadataName/value nodes from evaluation or execution.
$additem, $removeitemItem mutations that happened while targets were executing.
$import, $noimportResolved imports and imports that were skipped or failed.
$csc, $rarShortcuts for $task Csc and $task ResolveAssemblyReference.

Field Filters

Field filters are most useful for properties, items, metadata, skipped targets, and project-reference graph height.

Property by name

$property name=Configuration

The name contains Configuration.

Exact property name

$property name="Configuration"

The name equals Configuration.

Name and value

$property name=TargetFramework value=net8.0

Both filters must match.

Skipped targets

$target skipped=true

Use skipped=false to exclude skipped targets.

Hierarchical Scope

Most build questions are about context. Scope tells search where a match must be found in the tree.

FormMeaningExample
under(QUERY)Match only nodes whose ancestors include something matching QUERY.$csc under($project Core)
notunder(QUERY)Exclude nodes under a matching ancestor.$warning notunder($task Csc)
project(QUERY)Like under(), but only checks the nearest parent project.$error project(MyApp)
not(QUERY)Exclude nodes that themselves match the nested query.$task not(Csc)

Nested expressions are allowed. The parser is whitespace tolerant, so under ($project Foo) and under($project Foo) both work.

project(A) checks the nearest parent project. under($project A) can also match work done by projects that A invoked through an MSBuild task. In the viewer, right-click a project, target, or task and choose Search in subtree to generate an under(...) query for that exact subtree.

Time Filters And Sorts

There are two separate ideas: filter by a start/end timestamp, or annotate and sort by time.

Find slow tasks

$task $time

Adds duration and sorts slowest first. $duration is an alias.

Find slow targets in one project

$target $time project(MyApp.csproj)

Good first move for performance investigations.

Sort projects by start time

$project $start

Use $end for end time.

Filter by timestamp

$target start>"2026-04-30 14:30:00"

Timestamps must be quoted and parseable by .NET.

Special Indexes

These searches use analysis indexes built from the binlog instead of only scanning visible tree text.

IndexBest forExamples
$copy Why a file was copied, where it came from, or which target/task copied it. Directory searches are grouped into Incoming and Outgoing copies. $copy Foo.dll
$copy directory\path
$copy C:\full\path\Foo.dll
$nuget Package dependency chains from embedded project.assets.json files. Search by package name, version, dependency, or file from a package. $nuget project(MyApp.csproj)
$nuget project(MyApp.csproj) Package.Name
$nuget project(MyApp.csproj) File.dll
$nuget project(.csproj) 13.0.3
$projectreference Project-to-project dependency graph. Scoped to one project, it is bidirectional. Use height=0, height=1, or height=max to find projects by graph depth. $projectreference project(App.csproj)
$project height=max

$copy examples

$copy filename finds copy operations by file-name substring. $copy directory\path shows files copied into and out of a directory. $copy full\file\path focuses on one specific file. If the file came from a NuGet package, the result can show which package and dependency chain brought it in. If the copy came from a None or Content item with CopyToOutputDirectory, that is shown too.

$copy search result showing why a file was copied
$copy explains copy operations, including NuGet and CopyToOutputDirectory provenance.

$nuget examples

Use project(.) or project(.csproj) to search all projects, which is useful but can be slower on large logs. In the viewer, right-click a project and choose Search project.assets.json to inspect that project's NuGet dependencies.

$nuget project query listing dependencies
$nuget project(MyProject.csproj)
$nuget package-name query showing dependency matches
$nuget project(MyProject.csproj) Package.Name
$nuget file query showing the package a file came from
$nuget project(MyProject.csproj) File.dll
$nuget version query across projects
$nuget project(.csproj) 13.0.3

Investigation Recipes

Cold start on an unfamiliar binlog

  1. Check whether the build succeeded and note the MSBuild version.
  2. Search for $error and $warning.
  3. If it failed, open the error and look at its project, target, and task context in the tree.
  4. If it is slow, search for $task $time and $target $time.

Find which .NET SDK built it

Sdk.props

The SDK version is usually in the embedded path, such as C:\Program Files\dotnet\sdk\10.0.202\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.props. Different SDK versions explain many build differences before anything else does.

Explain why a file was copied

$copy Foo.dll

Pick the full source or destination path from the result, then search again with that full path. The expanded tree usually shows whether the file came from RAR, copy-local, NuGet content, project references, publish, or an explicit item with copy metadata.

Find where a property got its final value

  1. Find the project evaluation: $projectevaluation MyApp.
  2. Search properties and items in that evaluation for $property name=MyProperty.
  3. If import order matters, inspect the preprocessed XML for that evaluation.

If you need the full lifetime of every assignment, rebuild with MSBUILDLOGPROPERTYTRACKING=15.

Explain why a target did or did not run

First search for the target in the project:

$target CoreCompile project(MyApp.csproj)

If it ran or skipped, inspect its node and messages. If it is absent, inspect the preprocessed XML and imports to see whether the target was actually in scope.

Debug incremental build work

Capture a clean build and then an immediate no-change rebuild. The second binlog is the interesting one.

"Building target" "completely"

MSBuild logs this when a target's up-to-date check failed. Cross-check with $task $time to focus on work that actually costs time.

Pitfalls

Related Documentation

The compact source material for this page lives here: