Detailed documentation of NuGroom’s analysis and management features.
The tool automatically detects and supports Central Package Management in scanned repositories.
Directory.Packages.props files<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>, CPM is active<PackageVersion Include="..." Version="..."/> entries are read into a version lookup<PackageReference> entries that omit a Version attribute have their versions populated from the CPM lookupVersionOverride, that version takes precedence over the central versionDirectory.Packages.props files commonly use MSBuild property variables ($(PropertyName)) to define package versions in a single place. NuGroom automatically resolves these variables during scanning so that the actual version number is used for analysis, warnings, and updates.
Supported patterns:
| Pattern | Example | Resolved |
|---|---|---|
| Simple variable | $(NetCoreVersion) → 10.0.0 |
10.0.0 |
| Composed variables | $(MajorVersion).$(MinorVersion).$(PatchVersion) |
13.0.3 |
| Indirect reference | $(FullVersion) where FullVersion = $(Major).$(Minor).$(Patch) |
13.0.3 |
| Partial literal | $(MajorVersion).0.3 |
13.0.3 |
Behavior details:
<PropertyGroup> elements in the Directory.Packages.props file$(UndefinedVersion) is kept literally)Directory.Build.props) are not resolved — only properties within the same Directory.Packages.props are availableExample:
<Project>
<PropertyGroup>
<NetCoreVersion>10.0.0</NetCoreVersion>
<JsonVersion>13.0.3</JsonVersion>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="$(NetCoreVersion)" />
<PackageVersion Include="Newtonsoft.Json" Version="$(JsonVersion)" />
<PackageVersion Include="Serilog" Version="3.1.1" />
</ItemGroup>
</Project>
NuGroom resolves this as:
Microsoft.Extensions.Hosting → 10.0.0Newtonsoft.Json → 13.0.3Serilog → 3.1.1 (literal, no resolution needed)No configuration is needed — variable resolution happens automatically whenever a Directory.Packages.props file is parsed.
When CPM is active, package version updates target Directory.Packages.props instead of individual project files. This means a single update to the central props file can update the version for all projects in the repository.
No configuration is needed — CPM detection is automatic.
For repositories that do not yet use Central Package Management, the --migrate-to-cpm option generates a Directory.Packages.props file and updates all project files to remove inline Version attributes.
Dry-run preview:
NuGroom --config settings.json --migrate-to-cpm --dry-run
Apply migration (creates branches and PRs):
NuGroom --config settings.json --migrate-to-cpm --update-references
<PackageReference ... Version="..."/> are collectedDirectory.Packages.propsVersionOverride attribute and a warning is emittedDirectory.Packages.props file is created at the repository root (or per project with --per-project)Version attributes from <PackageReference> elementsWhen multiple projects reference different versions of the same package, the migration resolves the conflict as follows:
Directory.Packages.propsVersionOverride attribute to preserve their current versionFor example, given two projects:
App1.csproj references Newtonsoft.Json version 13.0.3App2.csproj references Newtonsoft.Json version 12.0.0The migration produces:
Directory.Packages.props (central version: highest)
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
</Project>
App1.csproj (version removed — uses central version)
<PackageReference Include="Newtonsoft.Json" />
App2.csproj (gets VersionOverride to preserve lower version)
<PackageReference Include="Newtonsoft.Json" VersionOverride="12.0.0" />
Warning emitted:
Version conflict: package 'Newtonsoft.Json' in project 'src/App2/App2.csproj'
uses version 12.0.0 (VersionOverride) while central version is 13.0.3
By default, --migrate-to-cpm creates a single Directory.Packages.props at the repository root. Use --per-project to create a separate file alongside each project file instead:
NuGroom --config settings.json --migrate-to-cpm --per-project --dry-run
In per-project mode:
Directory.Packages.props in the same directoryImportant: When migrating a repository that already contains a
Directory.Packages.propsfile (mixed repo), the migration merges existingPackageVersionentries into the generated output so they are not lost. However, the output file is regenerated from scratch — any other XML content in the original file such as comments, conditions, extraPropertyGroupelements, or custom items is not preserved.
When the CPM migration creates pull requests and the configured target branch does not exist, the tool automatically creates it from the source branch instead of skipping the repository.
TargetBranchPattern is an exact branch name (no wildcards), it is created as a new branch from the source branchrelease/*) that match no branches cannot be auto-created and will still skipThis allows migrations to target branches that do not yet exist, for example when introducing a new branching strategy alongside the CPM migration.
For repositories that still use the legacy packages.config format (common in .NET Framework projects), the tool can optionally scan and extract package references from these files.
Legacy packages.config scanning is opt-in to avoid noise in modern codebases:
CLI:
NuGroom --config settings.json --include-packages-config
Config file:
{
"IncludePackagesConfig": true
}
packages.config files in the repository.csproj, .vbproj, or .fsproj in the same directory)<package id="..." version="..."/> entries are extracted and tagged as PackagesConfig source kind<PackageReference> in the same project are deduplicatedSpecify one or more feeds with --feed. The resolver queries each feed until a package is found, selecting the first match. The originating feed host is displayed next to each package.
Benefits:
The version warning system helps identify version inconsistencies across your repositories.
{
"VersionWarnings": {
"DefaultLevel": "Minor"
}
}
{
"VersionWarnings": {
"DefaultLevel": "Minor",
"PackageRules": [
{
"PackageName": "Newtonsoft.Json",
"Level": "Major"
},
{
"PackageName": "Microsoft.Extensions.Logging",
"Level": "None"
}
]
}
}
VERSION WARNINGS
================================================================================
Newtonsoft.Json:
⚠ Repository1/Project1.csproj
Package version 12.0.3 differs from latest available version 13.0.3 (major version difference)
Serilog:
⚠ Repository2/Project2.csproj
Package version 2.10.0 differs from latest used version 2.12.0 (minor version difference)
--------------------------------------------------------------------------------
Total warnings: 2
Packages with warnings: 2
Major version differences: 1
Minor version differences: 1
When version warnings are configured, the tool automatically generates actionable package update recommendations.
The tool recommends updates for packages where:
The recommendations section shows:
Recommendations are automatically generated whenever version warnings are configured. No additional configuration is needed. Set "DefaultLevel": "None" to disable.
Exclude specific project files from analysis using regex patterns.
Exclude Test Projects:
{
"ExcludeProjectPatterns": [
".*\\.Test[s]?\\.csproj$",
".*\\.UnitTests\\.csproj$",
".*\\.IntegrationTests\\.csproj$"
]
}
Exclude Specific Project Types:
{
"ExcludeProjectPatterns": [
".*\\.Benchmarks\\.csproj$",
".*\\.Samples\\.csproj$",
".*\\.Demo\\.csproj$"
]
}
Case-Sensitive Matching:
{
"ExcludeProjectPatterns": [".*\\.TEST\\.csproj$"],
"CaseSensitiveProjectFilters": true
}
The tool flags packages with risk indicators:
[DEPRECATED] — Package is unlisted on the feed[OUTDATED] — Your solution uses a version lower than the latest available[VULNERABLE] — Heuristic detection (keywords in description or very old publish date)Summary sections list all Deprecated, Outdated, and Vulnerable packages with details.
Use --list-vulnerabilities to scan all packages exclusively for known vulnerabilities without making any changes. This mode performs a full package scan (local or Azure DevOps), runs vulnerability checks against NuGet feed advisories and the OSV.dev database, and reports only the vulnerable packages.
# Local vulnerability scan
nugroom --paths ./src --list-vulnerabilities
# Azure DevOps vulnerability scan
nugroom --config settings.json --list-vulnerabilities
# With exported report for CI artifacts
nugroom --paths ./src --list-vulnerabilities --export-vulnerabilities vuln-report.json
See Vulnerability Scanning for full details on data sources, caching, and configuration.
Cross-references packages not found on public feeds with project sources:
Enable detailed diagnostic output for troubleshooting.
Debug logging is automatically enabled when running with a debugger attached (e.g., from Visual Studio).
NuGroom --config settings.json --debug
Debug messages are displayed in gray color with [DEBUG] prefix and timestamp.
See also: Automated Updates · Export Formats · Renovate Compatibility