Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
148 commits
Select commit Hold shift + click to select a range
3c89c43
feat: add Start-FinOpsMultitool cmdlet for interactive FinOps scanner…
May 19, 2026
1a63159
feat(multitool): cost access warnings, tag query fixes, MG hierarchy …
May 27, 2026
8db8eaa
perf(multitool): optimize tag cost query pacing and filter low-covera…
May 27, 2026
981e4c9
perf: parallel per-sub cost queries in Get-CostByTag
May 27, 2026
d3d7c1f
fix: filter Azure system tags in Get-CostByTag
May 27, 2026
a5fd3e3
fix: dynamic tag cap, remove Contact from system filter
May 27, 2026
54129e2
Add TUI, Hub data routing, and display fixes for FinOps Multitool
May 28, 2026
35790a6
Add TUI README
May 28, 2026
9455685
Add contextual FinOps guidance after each scan result
May 28, 2026
e65b62d
Add tenant picker to TUI for multi-tenant support
May 28, 2026
f09870d
Auto-invoke when script is run directly
May 28, 2026
c735364
Severity-colored guidance with FinOps education context
May 28, 2026
a5e4190
Enrich Hub cost data with live forecast from Cost Management API
May 28, 2026
c976654
Colorize dollar amounts green, budget rows by risk severity
May 28, 2026
1fbc9c0
Fix variable collision: forecast total was overwriting scan count
May 28, 2026
92d17d9
Fix forecast: show full-month projection (actual + remaining forecast)
May 28, 2026
caf4cb2
Fix tag coverage: query ARG for true total/untagged counts when using…
May 28, 2026
62e27b8
Remove Hub coverage caveat from tag guidance, lower resource cost thr…
May 28, 2026
e730754
Fix Cost by Tag guidance: use max untagged cost per tag instead of su…
May 28, 2026
74127a7
Add permission context and diagnostics for missing scan data
May 28, 2026
af92edf
Update TUI README with multi-tenant, guidance, permissions, and Hub e…
May 28, 2026
5215c38
Add styled HTML report export, pre-populated export path, enhanced su…
May 28, 2026
a8654bf
Add MCP server exposing all scan modules as AI-callable tools
May 28, 2026
0d2c2d5
feat(agent-skills): add FinOps multitool skill ecosystem
Jun 1, 2026
0be59a2
Add cost data source routing to FinOps multitool
Jun 1, 2026
3febeda
Fix: throttle-resilient MG cost-scope resolution in FinOps Multitool
Jun 2, 2026
53f9b86
perf(cost-trend): single grouped MG query + single-sub fast path
Jun 2, 2026
f57b4a9
perf(savings): MG query grouped by SubscriptionId + single-sub fast path
Jun 2, 2026
10fc88b
feat(finops-multitool): friendly rotating throttle messages, Budget H…
Jun 2, 2026
cb593b3
feat(finops-multitool): add carbon, unit economics, and legacy resour…
Jun 3, 2026
4f4fee9
fix(finops-multitool): use KQL verbatim string for legacy VM regex
Jun 3, 2026
26d8c1e
feat(finops-multitool): derive AI workload KPIs from FinOps Hub expor…
Jun 3, 2026
9b4e761
Show a single status message while waiting out rate limits
Jun 3, 2026
c779195
Port ResourceId-based cost-by-tag engine to FinOps Multitool
Jun 3, 2026
285239d
Quietly handle management group access denial in hierarchy load
Jun 3, 2026
4802b27
fix(finops-multitool): correct MACC consumption reading (consumed = o…
Jun 4, 2026
e8b1f12
feat(finops-multitool): permission-aware commitment & reservation sca…
Jun 4, 2026
9ee96a4
Update FinOps Multitool
Jun 4, 2026
ad4d9b6
Update FinOps Multitool
Jun 5, 2026
94d31ce
Update FinOps Multitool
Jun 5, 2026
a409555
Update FinOps Multitool
Jun 5, 2026
3c8eaa1
Update FinOps Multitool
Jun 5, 2026
7d6b5e3
Update FinOps Multitool
Jun 6, 2026
78c90ac
Update FinOps Multitool
Jun 6, 2026
423735c
Update FinOps Multitool
Jun 6, 2026
d4ee137
Update FinOps Multitool
Jun 7, 2026
83af32c
Update FinOps Multitool
Jun 7, 2026
6263227
Update FinOps Multitool
Jun 7, 2026
b7f7867
Update FinOps Multitool
Jun 7, 2026
151a223
Update FinOps Multitool
Jun 7, 2026
687bfe9
Update FinOps Multitool
Jun 8, 2026
b550f15
Update FinOps Multitool
Jun 8, 2026
44c1118
Update FinOps Multitool
Jun 11, 2026
8290178
Update FinOps Multitool
Jun 11, 2026
3e6df7c
Update FinOps Multitool
Jun 11, 2026
ead35b3
Update FinOps Multitool
Jun 15, 2026
20474c0
Update FinOps Multitool
Jun 15, 2026
e58931b
Update FinOps Multitool
Jun 15, 2026
532b176
Update FinOps Multitool
Jun 15, 2026
1ef543e
Update FinOps Multitool
Jun 15, 2026
3ba8107
Update FinOps Multitool
Jun 18, 2026
ca47281
Update FinOps Multitool
Jun 19, 2026
ae181d7
Update FinOps Multitool
Jun 19, 2026
0540b94
Update FinOps Multitool
Jul 2, 2026
a13b7a0
Update FinOps Multitool
Jul 2, 2026
8c0dab8
Documentation for multitool
Aug 17, 2026
d551f10
Update FinOps multitool
Aug 17, 2026
959ac15
Update FinOps multitool
Aug 18, 2026
a3ad502
Update FinOps multitool
Aug 18, 2026
59cf0f1
Update FinOps multitool
Aug 18, 2026
caf7d5d
Update FinOps multitool
Aug 20, 2026
19e0d85
Update FinOps multitool
Aug 20, 2026
39eaf0e
Update FinOps multitool
Aug 20, 2026
76910ec
Update FinOps multitool
Aug 20, 2026
5f5deaa
Update FinOps multitool
Aug 20, 2026
a8da2f4
fix(multitool): address review findings 1, 2, 3, 4, 6, 9
Aug 21, 2026
69add06
fix(multitool): correct realized savings math (review finding 7)
Aug 21, 2026
4974f36
fix(multitool): resolve explicit subscription scope before the picker…
Aug 21, 2026
08e945a
fix(multitool): project scan results to flat rows before CSV export (…
Aug 21, 2026
5e3a1b2
fix(multitool): support consoles without arrow-key input and add a no…
Aug 22, 2026
ddc72db
fix(multitool): remove the unreachable write path and correct the doc…
Aug 22, 2026
fa442bf
chore(multitool): remove a scratch test script committed by mistake
Aug 22, 2026
4e4615e
Merge origin/dev into feature/finops-multitool
Aug 22, 2026
a9f1690
docs(multitool): drop the production safety claim from the read-only …
Aug 22, 2026
6311634
fix(multitool): render scan guidance in the HTML report and scope the…
Aug 22, 2026
9a8fcf4
chore(multitool): remove three unreachable modules
Aug 22, 2026
b336ab0
fix(multitool): address the three issues from the 08/23 review
Aug 24, 2026
cdb9680
Merge remote-tracking branch 'origin/dev' into feature/finops-multitool
Aug 24, 2026
801c6ac
fix(multitool): correct tag allocation KPIs and measure coverage per …
Aug 24, 2026
6744f0a
chore(multitool): ignore the scan output folder
Aug 24, 2026
05c00ea
fix(multitool): default export path outside the working folder
Aug 24, 2026
6478445
Update FinOps Multitool
Aug 25, 2026
b92ac4f
Update FinOps Multitool
Aug 25, 2026
5588974
Update FinOps Multitool
Aug 25, 2026
e6ab672
Update FinOps Multitool
Aug 25, 2026
bd868d1
Update FinOps Multitool
Aug 25, 2026
3d14bbb
Update FinOps Multitool
Aug 25, 2026
fa57b3d
Update FinOps Multitool
Aug 25, 2026
5478627
Update FinOps Multitool
Aug 25, 2026
c10ee78
Update FinOps Multitool
Aug 25, 2026
3c3b3b7
Update FinOps Multitool
Aug 25, 2026
3d14393
Update FinOps Multitool
Aug 25, 2026
82558ef
Update FinOps Multitool
Aug 25, 2026
e5ab880
Update FinOps Multitool
Aug 25, 2026
736bb27
Update FinOps Multitool
Aug 25, 2026
346c405
Update FinOps Multitool
Aug 26, 2026
20c38f3
Update FinOps Multitool
Aug 26, 2026
f5c1d60
Update FinOps Multitool
Aug 26, 2026
fcb24ab
Update FinOps Multitool
Aug 26, 2026
4037641
Merge remote-tracking branch 'origin/dev' into feature/finops-multitool
Aug 26, 2026
bf2d27b
Update FinOps Multitool
Aug 27, 2026
859178d
Merge remote-tracking branch 'origin/dev' into feature/finops-multitool
Sep 7, 2026
215001f
Update FinOps Multitool
Sep 7, 2026
4c5ec11
FinOps Multitool Update - Sep 07-08 Review findings
Sep 9, 2026
ab1c349
FinOps Multitool Update - Sep 07-08 Review findings
Sep 9, 2026
cc458b4
FinOps Multitool Update - Sep 07-08 Review findings
Sep 9, 2026
595ca0a
FinOps Multitool Update - Sep 07-08 Review findings
Sep 9, 2026
940c027
FinOps Multitool Update - Sep 07-08 Review findings
Sep 9, 2026
97a7159
Update FinOps Multitool
Sep 9, 2026
45f6a4e
Update FinOps Multitool
Sep 9, 2026
4c99844
FinOps Multitool Update - Sep 09-14 Review findings
Sep 14, 2026
435e895
FinOps Multitool Update - Sep 14 Review findings
Sep 15, 2026
89fb634
FinOps Multitool Update - Sep 14 Review findings
Sep 15, 2026
582ff2f
FinOps Multitool Update - Sep 14 Review findings
Sep 15, 2026
93b0339
FinOps Multitool Update - Sep 14 Review findings
Sep 15, 2026
478ab89
Documentation update
Sep 15, 2026
8ce188f
Update documentation
Sep 15, 2026
1d90c50
FinOps Multitool Update - Sep 15 Review findings
Sep 15, 2026
582aca3
FinOps Multitool Update - Sep 15 Review findings
Sep 15, 2026
250652f
Merge remote-tracking branch 'origin/dev' into feature/finops-multitool
Sep 15, 2026
018dba5
FinOps Multitool Update - Sep 15 Review findings
Sep 16, 2026
b37d3e9
FinOps Multitool Update - Sep 15 Review findings
Sep 16, 2026
8b1d68c
FinOps Multitool Update - Sep 16 Review findings
Sep 16, 2026
d3c99d1
FinOps Multitool Update - Sep 16 Review findings
Sep 16, 2026
1fe0cda
Documentation update
Sep 16, 2026
9fd8a4c
FinOps Multitool Update - Sep 16 Review findings
Sep 17, 2026
e11f860
chore: merge dev into finops-multitool
Sep 17, 2026
1af4f06
fix(multitool): FinOps Multitool Update - Sep 17 Review findings
Sep 17, 2026
787504a
fix(multitool): FinOps Multitool Update - Sep 17 Review findings
Sep 17, 2026
791de7d
fix(multitool): FinOps Multitool Update - Sep 17-18 Review findings
Sep 18, 2026
839276d
fix(multitool): auto-save reports and correct Hub output
Sep 19, 2026
dc5be03
fix(multitool): improve reports and policy coverage
Sep 20, 2026
7de42fc
fix(multitool): harden data handling
Sep 20, 2026
ed43aab
fix(multitool): honor budget history filters
Sep 20, 2026
87e03fa
fix(multitool): handle incomplete scan results
Sep 21, 2026
ae36741
fix(multitool): FinOps Multitool Update - Sep 23-24 Review findings
Sep 24, 2026
f11f861
fix(ci): scope multitool temporary paths to test steps
Sep 24, 2026
a1b3537
feat(multitool): explain KPI values and scan thresholds
Sep 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .build/BuildHelper/Build-PsModule.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ function Build-PsModule
$moduleName = 'FinOpsToolkit'
$moduleFullName = "$moduleName.psm1"
$modulePath = Join-Path -Path $rootPath -ChildPath "src/powershell/$moduleFullName"
$privatePath = Join-Path -Path $rootPath -ChildPath "src/powershell/private"
$publicPath = Join-Path -Path $rootPath -ChildPath "src/powershell/public"
$privatePath = Join-Path -Path $rootPath -ChildPath "src/powershell/Private"
$publicPath = Join-Path -Path $rootPath -ChildPath "src/powershell/Public"
$stringsPath = Join-Path -Path $rootPath -ChildPath 'src/powershell/en-US'
$releasePath = Join-Path -Path $rootPath -ChildPath "release/$moduleName/$baseVersion"
$manifestPath = Join-Path -Path $releasePath -ChildPath "$moduleName.psd1"
Expand Down
130 changes: 130 additions & 0 deletions .github/workflows/dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ name: 'PowerShell Tests'
on:
pull_request:
paths:
- '.github/workflows/dev.yml'
- '.build/BuildHelper/**'
- '.build/BuildHelper.psm1'
- 'package.json'
- 'src/scripts/Get-Version.ps1'
- 'src/powershell/**'
# KQL sources are covered by unit tests (HubsKqlOperators.Tests.ps1)
- 'src/templates/finops-hub/**/*.kql'
Expand All @@ -11,6 +16,10 @@ on:
- 'src/templates/finops-hub/**/timeZones.bicep'
- 'docs/deploy/finops-hub-latest.json'
- 'docs/deploy/finops-hub-preview.json'

permissions:
contents: read

jobs:
run_pester_tests:
name: Pester
Expand All @@ -25,3 +34,124 @@ jobs:
- name: Run Tests
shell: pwsh
run: .build/start.ps1 -Task Test.PowerShell.All

multitool_native:
name: Multitool (${{ matrix.os }})
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
env:
DOTNET_CLI_TELEMETRY_OPTOUT: '1'
DOTNET_NOLOGO: '1'
steps:
- name: Install and cache test dependencies
uses: potatoqualitee/psmodulecache@9e4b63833c22c1768d648e115a9c849afdda22a5 # v6.3
with:
modules-to-cache: Pester:6.0.0, Az.Accounts, Az.Resources, Az.ResourceGraph, Az.Storage
shell: pwsh
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install SDK for native Parquet restore
if: runner.os == 'Linux'
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5
with:
dotnet-version: '8.0.x'
- name: Run native multitool tests
shell: pwsh
env:
TMPDIR: ${{ runner.temp }}
run: |
$ErrorActionPreference = 'Stop'
Import-Module Pester -RequiredVersion 6.0.0 -Force
$names = @(
'AzGraphPagination', 'BudgetCoverage', 'CommitmentUtilizationDedupe'
'CostQueryPagination', 'CurrencyLabel', 'FOHubProvider', 'HubSizeProbe'
'MultitoolSafety', 'ParquetPackageClient', 'PolicyEffect'
'RetryJitter', 'Start-FinOpsMultitool'
)
$paths = @($names | ForEach-Object {
Join-Path 'src/powershell/Tests/Unit' "$_.Tests.ps1"
})
foreach ($path in $paths) {
if (-not (Test-Path -LiteralPath $path -PathType Leaf)) { throw "Missing test: $path" }
}
$configuration = New-PesterConfiguration
$configuration.Run.Path = $paths
$configuration.Run.PassThru = $true
$configuration.Run.Exit = $false
$configuration.Output.Verbosity = 'Detailed'
$configuration.TestResult.Enabled = $true
$configuration.TestResult.OutputFormat = 'NUnitXml'
$configuration.TestResult.OutputPath = Join-Path $env:RUNNER_TEMP 'multitool-unit.xml'
$result = Invoke-Pester -Configuration $configuration
$result | Select-Object Result, TotalCount, PassedCount, FailedCount, SkippedCount, FailedContainersCount
@(
'## Multitool validation'
"Tested merge commit: $env:GITHUB_SHA"
"Host: $([Runtime.InteropServices.RuntimeInformation]::OSDescription); PowerShell: $($PSVersionTable.PSVersion)"
"Unit tests: $($result.Result); passed $($result.PassedCount), failed $($result.FailedCount), skipped $($result.SkippedCount)."
) | Add-Content -LiteralPath $env:GITHUB_STEP_SUMMARY
if ($null -eq $result -or $result.Result -ne 'Passed' -or
$result.TotalCount -le 0 -or $result.PassedCount -le 0 -or
$result.FailedCount -ne 0 -or $result.FailedContainersCount -ne 0 -or
$result.FailedBlocksCount -ne 0 -or $result.Containers.Count -ne $paths.Count) {
throw 'Native multitool tests failed or discovery was incomplete.'
}
exit 0
- name: Run package and real Parquet integration tests
if: ${{ !cancelled() }}
shell: pwsh
env:
TMPDIR: ${{ runner.temp }}
run: |
$ErrorActionPreference = 'Stop'
Import-Module Pester -RequiredVersion 6.0.0 -Force
$paths = @('src/powershell/Tests/Integration/MultitoolPackage.Tests.ps1')
$minimumPassed = 3
$parquetCoverage = 'Not run on macOS: NuGet signed-package verification is not supported. https://learn.microsoft.com/dotnet/core/tools/nuget-signed-package-verification#macos'
if (-not $IsMacOS) {
$paths += 'src/powershell/Tests/Integration/MultitoolParquet.Tests.ps1'
$minimumPassed += 2
$parquetCoverage = 'Real signed Parquet restore and cold/cached reads in separate processes.'
}
foreach ($path in $paths) {
if (-not (Test-Path -LiteralPath $path -PathType Leaf)) { throw "Missing test: $path" }
}
$configuration = New-PesterConfiguration
$configuration.Run.Path = $paths
$configuration.Run.PassThru = $true
$configuration.Run.Exit = $false
$configuration.Output.Verbosity = 'Detailed'
$configuration.TestResult.Enabled = $true
$configuration.TestResult.OutputFormat = 'NUnitXml'
$configuration.TestResult.OutputPath = Join-Path $env:RUNNER_TEMP 'multitool-integration.xml'
$result = Invoke-Pester -Configuration $configuration
$result | Select-Object Result, TotalCount, PassedCount, FailedCount, SkippedCount, FailedContainersCount
@(
"Integration tests: $($result.Result); passed $($result.PassedCount), failed $($result.FailedCount), skipped $($result.SkippedCount)."
'Checks: isolated module build and public launch; CSV, HTML, and text reports.'
"Parquet coverage: $parquetCoverage"
'Azure access is replaced with synthetic responses. Package downloads and signature verification require network access.'
) | Add-Content -LiteralPath $env:GITHUB_STEP_SUMMARY
if ($null -eq $result -or $result.Result -ne 'Passed' -or
$result.PassedCount -lt $minimumPassed -or $result.FailedCount -ne 0 -or
$result.SkippedCount -ne 0 -or $result.NotRunCount -ne 0 -or
$result.FailedContainersCount -ne 0 -or $result.FailedBlocksCount -ne 0 -or
$result.Containers.Count -ne $paths.Count) {
throw 'Multitool integration tests failed, were skipped, or discovery was incomplete.'
}
exit 0
- name: Upload multitool test evidence
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: multitool-tests-${{ matrix.os }}
path: |
${{ runner.temp }}/multitool-unit.xml
${{ runner.temp }}/multitool-integration.xml
if-no-files-found: error
retention-days: 14
12 changes: 12 additions & 0 deletions docs-mslearn/TOC.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,12 @@
href: toolkit/alerts/finops-alerts-overview.md
- name: Configure alerts
href: toolkit/alerts/configure-finops-alerts.md
- name: FinOps multitool
items:
- name: Overview
href: toolkit/multitool/finops-multitool-overview.md
- name: Commands
href: toolkit/powershell/multitool/finops-multitool-commands.md
- name: Optimization engine
items:
- name: Overview
Expand Down Expand Up @@ -242,6 +248,12 @@
href: toolkit/powershell/cost/remove-finopscostexport.md
- name: Start-FinOpsCostExport
href: toolkit/powershell/cost/start-finopscostexport.md
- name: FinOps multitool
items:
- name: FinOps multitool commands
href: toolkit/powershell/multitool/finops-multitool-commands.md
- name: Start-FinOpsMultitool
href: toolkit/powershell/multitool/start-finopsmultitool.md
- name: FinOps hubs
items:
- name: FinOps hubs commands
Expand Down
15 changes: 14 additions & 1 deletion docs-mslearn/toolkit/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: FinOps toolkit changelog
description: Review the latest features and enhancements in the FinOps toolkit, including updates to FinOps hubs, Power BI reports, and more.
author: MSBrett
ms.author: brettwil
ms.date: 09/11/2026
ms.date: 09/24/2026
ms.topic: reference
ms.service: finops
ms.subservice: finops-toolkit
Expand Down Expand Up @@ -54,6 +54,19 @@ The following section lists features and enhancements that are currently in deve
- **Fixed**
- Made the idle application gateway and idle public IP query join kinds explicit so they no longer rely on the `innerunique` default ([#2225](https://github.com/microsoft/finops-toolkit/pull/2225)).

### [FinOps multitool](multitool/finops-multitool-overview.md)

- **Added**
- Added the FinOps multitool, which scans an Azure environment for cost optimization, governance, and FinOps insights through a PowerShell 7 terminal UI ([#2155](https://github.com/microsoft/finops-toolkit/pull/2155)).
- Included 30 read-only scan modules, with 26 available in the menu, covering orphaned resources, idle VMs, storage tier advice, Azure Hybrid Benefit, tag and policy inventory and recommendations, cost data, cost trend, cost by tag, resource costs, reservation advice, commitment utilization, estimated savings, budget status and history, anomaly alerts, Advisor recommendations, billing structure, and contract info.
- Added a companion set of agent skills that carry the investigation routing, the queries, and the interpretation rules so AI agents can run the same analysis through Azure CLI or an Azure MCP server.
- Added engine-side aggregation through the FinOps hub's Azure Data Explorer or Microsoft Fabric Kusto database for large environments, with a storage reader as a small-dataset fallback.
- Added a non-interactive mode for an already-authenticated pipeline or scheduled job, and automatic private CSV, HTML, and text reports. Consoles that can't render the arrow-key menus, such as PowerShell remoting sessions, fall back to numbered prompts.
- Added a searchable KPI reference and in-report calculation details for cost shares, unit rates, VM and storage screening, and budget coverage and forecast availability.
- **Fixed**
- Fixed storage-backed Parquet imports returning empty values or misaligning costs when an export contains nested metadata.
- Fixed measured zero unit-cost KPIs appearing unavailable.

### [Power BI reports](power-bi/reports.md)

- **Changed**
Expand Down
3 changes: 2 additions & 1 deletion docs-mslearn/toolkit/finops-toolkit-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: FinOps toolkit overview
description: Learn how the FinOps toolkit helps you automate and extend the Microsoft Cloud with starter kits, scripts, and advanced solutions to improve FinOps practices.
author: flanakin
ms.author: micflan
ms.date: 08/05/2026
ms.date: 09/16/2026
ms.topic: concept-article
ms.service: finops
ms.subservice: finops-toolkit
Expand Down Expand Up @@ -33,6 +33,7 @@ The FinOps toolkit is an ever-evolving collection of tools and resources. The fo
- [Governance workbook](./workbooks/governance.md) – Central hub for governance.
- [Azure Optimization Engine](./optimization-engine/overview.md) – Extensible solution for custom optimization recommendations.
- [PowerShell module](./powershell/powershell-commands.md) – Automate and manage FinOps solutions and capabilities.
- [FinOps multitool](./powershell/multitool/finops-multitool-commands.md) – Scan an Azure environment for cost, governance, and optimization insights from a terminal UI, with agent skills so AI assistants can run the same analysis.
- [Bicep Registry modules](./bicep-registry/modules.md) – Official repository for Bicep modules.
- [Open data](open-data.md) – Data available for anyone to access, use, and share without restriction.
- [Pricing units](open-data.md#pricing-units) – Microsoft pricing units, distinct units, and scaling factors.
Expand Down
90 changes: 90 additions & 0 deletions docs-mslearn/toolkit/multitool/finops-multitool-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
title: FinOps multitool overview
description: FinOps multitool scans an Azure environment for cost optimization, governance, and FinOps insights from a terminal UI, with agent skills so AI assistants can run the same analysis.
author: z-larsen
ms.author: zlarsen
ms.date: 09/20/2026
ms.topic: concept-article
ms.service: finops
ms.subservice: finops-toolkit
ms.reviewer: micflan
#customer intent: As a FinOps practitioner, I need to learn about the FinOps multitool.
---

# FinOps multitool

FinOps multitool scans an Azure environment for cost optimization, governance, and FinOps insights, grounded in your live resource state. It reports on cost trends, orphaned resources, idle VMs, tag hygiene, reservation and savings plan utilization, Azure Hybrid Benefit opportunities, budgets, anomaly alerts, and policy compliance. Run it from an interactive terminal, or call it as tools from an AI agent.

## How it works

FinOps multitool provides 30 scan modules, with 26 available in the terminal menu, and renders findings for the subscriptions you select:

- **Interactive scanning** <br> Choose the subscriptions and scan modules you want, then review results in the terminal. Every completed run automatically saves CSV files, an HTML report, and a text summary to a private local folder. See [Report storage](../powershell/multitool/start-finopsmultitool.md#report-storage) for locations and privacy limits. Consoles that can't render the arrow-key menus fall back to numbered prompts. Non-interactive runs require an existing Azure sign-in context.

- **AI agent support** <br> Agent skills describe the same investigations, the queries behind them, and how to read the results, so AI assistants can answer cost questions from your environment's data.

- **Cost data sources** <br> When a [FinOps hub](../hubs/finops-hubs-overview.md) is available, cost scans query the hub's Azure Data Explorer or Microsoft Fabric database and push aggregation into the engine, returning only summarized results. A storage reader covers smaller datasets, and the Cost Management API is used when no hub is present.

- **Read-only** <br> The multitool never creates, changes, or deletes a resource.

## Benefits

FinOps multitool provides the following benefits:

- Choose from 26 menu scans across optimization, governance, cost analysis, commitments, monitoring, and sustainability, with four more modules for direct investigations.
- Scope each scan to the subscriptions you select.
- Get a CSV file per selected scan, an HTML report, and a text summary saved automatically to a private local folder.
- Read costs from a FinOps hub or the Cost Management API, with resource inventory from Azure Resource Graph.
- Run the same scans from a pipeline or a scheduled job with `-NonInteractive`.
- Run the same investigations from an AI assistant through agent skills.

## Why FinOps multitool?

[FinOps workbooks](../workbooks/finops-workbooks-overview.md) and the [Azure Optimization Engine](../optimization-engine/overview.md) surface optimization opportunities in the Azure portal. FinOps multitool reports the same kinds of findings in the terminal and through AI agent skills, so you can scan an environment during a working session without leaving the command line.

## Required permissions

Most scans need [Reader](/azure/role-based-access-control/built-in-roles#reader) or [Cost Management Reader](/azure/role-based-access-control/built-in-roles#cost-management-reader) on the target scope. Account scans (billing structure, contract info, and Microsoft Azure Consumption Commitment balance) also need agreement-specific billing access: [Billing account reader or Billing profile reader for a Microsoft Customer Agreement](/azure/cost-management-billing/manage/understand-mca-roles), or [Enterprise Administrator (read only) for an Enterprise Agreement](/azure/cost-management-billing/manage/understand-ea-roles), at the scope the scan reads.

Commitment utilization reads reservation and savings plan usage at billing account or billing profile scope, so it needs the same access as account scans. Reader on a subscription isn't enough. Without it, the scan tells you it couldn't reach a billing scope instead of showing zero commitments.

The carbon scan needs Reader or [Carbon Optimization Reader](/azure/carbon-optimization/permissions) assigned at the subscription. Carbon emissions permissions don't apply at resource group or resource scope.

## Give feedback

Let us know how we're doing with a quick review. We use these reviews to improve and expand FinOps tools and resources.

<!-- prettier-ignore-start -->
> [!div class="nextstepaction"]
> [Give feedback](https://portal.azure.com/#view/HubsExtension/InProductFeedbackBlade/extensionName/FinOpsToolkit/cesQuestion/How%20easy%20or%20hard%20is%20it%20to%20use%20FinOps%20multitool%3F/cvaQuestion/How%20valuable%20are%20FinOps%20multitool%3F/surveyId/FTK/bladeName/Multitool/featureName/Overview)
<!-- prettier-ignore-end -->

If you're looking for something specific, vote for an existing or create a new idea. Share ideas with others to get more votes. We focus on ideas with the most votes.

<!-- prettier-ignore-start -->
> [!div class="nextstepaction"]
> [Vote on or suggest ideas](https://github.com/microsoft/finops-toolkit/issues?q=is%3Aissue%20is%3Aopen%20label%3A%22Tool%3A%20PowerShell%22%20sort%3Areactions-%2B1-desc)
<!-- prettier-ignore-end -->

<br>

## Related content

Related FinOps capabilities:

- [Reporting and analytics](../../framework/understand/reporting.md)
- [Workload optimization](../../framework/optimize/workloads.md)
- [Rate optimization](../../framework/optimize/rates.md)

Related products:

- [Azure Resource Graph](/azure/governance/resource-graph/)
- [Cost Management](/azure/cost-management-billing/)

Related solutions:

- [FinOps multitool commands](../powershell/multitool/finops-multitool-commands.md)
- [FinOps hubs](../hubs/finops-hubs-overview.md)
- [FinOps workbooks](../workbooks/finops-workbooks-overview.md)

<br>
Loading