diff --git a/docs-mslearn/TOC.yml b/docs-mslearn/TOC.yml index 8126a2bcf..c94151e89 100644 --- a/docs-mslearn/TOC.yml +++ b/docs-mslearn/TOC.yml @@ -256,6 +256,8 @@ href: toolkit/powershell/data/open-data-commands.md - name: Get-FinOpsPricingUnit href: toolkit/powershell/data/get-finopspricingunit.md + - name: Get-FinOpsRecommendationType + href: toolkit/powershell/data/get-finopsrecommendationtype.md - name: Get-FinOpsRegion href: toolkit/powershell/data/get-finopsregion.md - name: Get-FinOpsResourceType diff --git a/docs-mslearn/toolkit/changelog.md b/docs-mslearn/toolkit/changelog.md index 7c5d94e4b..d2d86ffac 100644 --- a/docs-mslearn/toolkit/changelog.md +++ b/docs-mslearn/toolkit/changelog.md @@ -41,6 +41,11 @@ The following section lists features and enhancements that are currently in deve ### Documentation improvements +### [Open data](open-data.md) v13 + +- **Added** + - Added [RecommendationTypes.csv](open-data.md#recommendation-types) open data file with Azure Advisor recommendation type metadata including recommendation IDs, categories, impact levels, service names, and learn more links. + ### [Power BI reports](power-bi/reports.md) v13 - **Fixed** diff --git a/docs-mslearn/toolkit/open-data.md b/docs-mslearn/toolkit/open-data.md index c1fad7813..34ad14c3e 100644 --- a/docs-mslearn/toolkit/open-data.md +++ b/docs-mslearn/toolkit/open-data.md @@ -113,6 +113,32 @@ Convert resource type values to lowercase before mapping. This helps reduce dupl
+## Recommendation types + +Azure Advisor provides recommendations to help you optimize your Azure deployments. The Recommendation types file includes metadata about each recommendation type to help you organize and provide additional context in your reports and dashboards. + +Sample data: + + + +| RecommendationTypeId | Category | Impact | ServiceName | ResourceType | DisplayName | LearnMoreLink | +| ------------------------------------ | --------------------- | ------ | -------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| a06456ed-afb7-4d16-86fd-0054e25268ed | Performance | Medium | Virtual Machines | microsoft.compute/virtualmachines | Enable Accelerated Networking to improve network performance and latency | https://docs.microsoft.com/azure/virtual-network/create-vm-accelerated-networking-cli#enable-accelerated-networking-on-existing-vms | +| 9c0c3708-17f6-4108-9aff-f0e052c3cd41 | OperationalExcellence | Low | Azure App Service | microsoft.subscriptions/subscriptions | Eliminate replica staging environments and ship new versions and features with zero downtime using deployment slots | https://docs.microsoft.com/azure/app-service/deploy-staging-slots | +| a205074f-8049-48b3-903f-556f5e530ae3 | Cost | High | ReservedInstances | microsoft.subscriptions/subscriptions | Buy reserved instance | https://aka.ms/rirecommendations | +| 94aea435-ef39-493f-a547-8408092c22a7 | Cost | High | Virtual Machine Scale Sets | microsoft.compute/virtualmachinescalesets | Shut down or resize your virtual machine scale sets | https://aka.ms/aa_lowusagerec_vmss_learnmore | +| afdf4c1a-e46b-4817-a5d6-4b9909f58e2a | Cost | Low | Azure Synapse Analytics | microsoft.synapse/workspaces | Consider enabling automatic pause feature on spark compute | https://aka.ms/EnableSynapseSparkComputeAutoPauseGuidance | +| ed651749-cd37-4fd5-9897-01b416926745 | HighAvailability | Medium | Site Recovery | microsoft.compute/virtualmachines | Enable virtual machine replication | https://aka.ms/azure-site-recovery-dr-azure-vms | + + + +Convert resource type values to lowercase before mapping. This helps reduce duplication and speed up the mapping process. + +> [!div class="nextstepaction"] +> [Download](https://github.com/microsoft/finops-toolkit/releases/latest/download/RecommendationTypes.csv) + +
+ ## Services In Microsoft Cost Management, `ConsumedService` represents the primary service or resource provider of the resource you used. It's roughly the same as `ServiceName` in [FOCUS](../focus/what-is-focus.md). In some cases, multiple services share the same resource provider, so we're using the `ConsumedService` and `ResourceType` columns to map to `ServiceName` and `ServiceCategory` values for use within FOCUS. diff --git a/docs-mslearn/toolkit/powershell/data/get-finopsrecommendationtype.md b/docs-mslearn/toolkit/powershell/data/get-finopsrecommendationtype.md new file mode 100644 index 000000000..58e1010b7 --- /dev/null +++ b/docs-mslearn/toolkit/powershell/data/get-finopsrecommendationtype.md @@ -0,0 +1,119 @@ +--- +title: Get-FinOpsRecommendationType command +description: Get metadata for Azure Advisor recommendation types using the Get-FinOpsRecommendationType command in the FinOpsToolkit module. +author: flanakin +ms.author: micflan +ms.date: 10/10/2025 +ms.topic: reference +ms.service: finops +ms.subservice: finops-toolkit +ms.reviewer: micflan +#customer intent: As a FinOps user, I want to understand how to use the Get-FinOpsRecommendationType command in the FinOpsToolkit module. +--- + + +# Get-FinOpsRecommendationType command + +The **Get-FinOpsRecommendationType** command returns metadata about Azure Advisor recommendation types based on the specified filters. This data helps organize and provide additional context for Azure Advisor recommendations in FinOps reports and dashboards. + +The recommendation type metadata includes: + +- RecommendationTypeId - Unique GUID identifier +- Category - Cost, HighAvailability, OperationalExcellence, Performance, or Security +- Impact - High, Medium, or Low +- ServiceName - Name of the Azure service +- ResourceType - Azure resource type (lowercase) +- DisplayName - Human-readable description +- LearnMoreLink - URL to documentation + +
+ +## Syntax + +```powershell +Get-FinOpsRecommendationType ` + [[-RecommendationTypeId] ] ` + [[-Category] ] ` + [[-Impact] ] ` + [-ServiceName ] ` + [-ResourceType ] +``` + +
+ +## Parameters + +| Name | Description | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `‑RecommendationTypeId` | Optional. The recommendation type ID (GUID) to filter by. Accepts wildcards. Default = \* (all). | +| `‑Category` | Optional. The recommendation category to filter by. Accepts wildcards. Default = \* (all). Expected values: Cost, HighAvailability, OperationalExcellence, Performance, Security. | +| `‑Impact` | Optional. The impact level to filter by. Accepts wildcards. Default = \* (all). Expected values: High, Medium, Low. | +| `‑ServiceName` | Optional. The service name to filter by. Accepts wildcards. Default = \* (all). | +| `‑ResourceType` | Optional. The resource type to filter by. Accepts wildcards. Default = \* (all). | + +
+ +## Examples + +The following examples demonstrate how to use the Get-FinOpsRecommendationType command to retrieve recommendation type metadata. + +### Get all recommendation types + +```powershell +Get-FinOpsRecommendationType +``` + +Returns all recommendation types. + +### Get cost recommendations + +```powershell +Get-FinOpsRecommendationType -Category Cost +``` + +Returns all cost-related recommendation types. + +### Get high-impact cost recommendations + +```powershell +Get-FinOpsRecommendationType -Impact High -Category Cost +``` + +Returns all high-impact cost recommendation types. + +### Get virtual machine recommendations + +```powershell +Get-FinOpsRecommendationType -ResourceType "microsoft.compute/virtualmachines" +``` + +Returns all recommendation types that apply to virtual machines. + +
+ +## 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. + +> [!div class="nextstepaction"] +> [Give feedback](https://portal.azure.com/#view/HubsExtension/InProductFeedbackBlade/extensionName/FinOpsToolkit/cesQuestion/How%20easy%20or%20hard%20is%20it%20to%20use%20the%20FinOps%20toolkit%20PowerShell%20module%3F/cvaQuestion/How%20valuable%20are%20the%20FinOps%20toolkit%20PowerShell%20module%3F/surveyId/FTK/bladeName/PowerShell/featureName/OpenData.GetRecommendationType) + +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. + +> [!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%3A"reactions-%2B1-desc") + +
+ +## Related content + +Related products: + +- [Azure Advisor](/azure/advisor/advisor-overview) + +Related solutions: + +- [FinOps toolkit Power BI reports](../../power-bi/reports.md) +- [FinOps toolkit open data](../../open-data.md) + +
diff --git a/docs-mslearn/toolkit/powershell/data/open-data-commands.md b/docs-mslearn/toolkit/powershell/data/open-data-commands.md index a4ea4df27..bd00cd96b 100644 --- a/docs-mslearn/toolkit/powershell/data/open-data-commands.md +++ b/docs-mslearn/toolkit/powershell/data/open-data-commands.md @@ -21,6 +21,7 @@ The FinOps toolkit open data PowerShell commands help you integrate datasets int ## Commands - [Get-FinOpsPricingUnit](Get-FinOpsPricingUnit.md) – Gets an Azure region ID and name. +- [Get-FinOpsRecommendationType](Get-FinOpsRecommendationType.md) – Gets metadata for Azure Advisor recommendation types. - [Get-FinOpsRegion](Get-FinOpsRegion.md) – Gets an Azure region ID and name. - [Get-FinOpsResourceType](Get-FinOpsResourceType.md) – Gets details about an Azure resource type. - [Get-FinOpsService](Get-FinOpsService.md) – Gets the name and category for a service, publisher, and cloud provider. diff --git a/src/open-data/README.md b/src/open-data/README.md index 066add392..d6cb92ebf 100644 --- a/src/open-data/README.md +++ b/src/open-data/README.md @@ -162,6 +162,46 @@ If you run into any issues with the script that gets the data, you can look at e
+## 📋 Recommendation types + + + 📅 Updated: Oct 10, 2025
+ ➡️ Source: Azure Advisor Recommendation Metadata API + MicrosoftDocs/SelfHelpContent repo
+
+ +
+ +The [RecommendationTypes.csv](./RecommendationTypes.csv) file contains metadata about Azure Advisor recommendation types. This data provides context for recommendations to help organize and describe them in reports and dashboards. + +The data is sourced from two locations: + +1. **Azure Advisor Recommendation Metadata API** - Provides recommendation type IDs and display names +2. **MicrosoftDocs/SelfHelpContent repo** (private, FTE-only) - Provides additional metadata like category, impact, service name, resource type, and learn more links + +To update the recommendation metadata from the API: + +```powershell +# Authenticate to Azure +Connect-AzAccount + +# Run the script to fetch metadata +./src/scripts/Get-AdvisorRecommendationTypes.ps1 +``` + +The script retrieves the basic metadata (ID and DisplayName) from the Azure Advisor API. Additional columns should be manually populated or sourced from the SelfHelpContent repository. + +**Columns:** + +- **RecommendationTypeId** - Unique GUID identifier for the recommendation type +- **Category** - Recommendation category (Cost, Performance, HighAvailability, OperationalExcellence, Security) +- **Impact** - Impact level (High, Medium, Low) +- **ServiceName** - Azure service name +- **ResourceType** - Azure resource type (lowercase) +- **DisplayName** - Human-readable description of the recommendation +- **LearnMoreLink** - URL to documentation for more information + +
+ ## 🎛️ Services diff --git a/src/open-data/RecommendationTypes.csv b/src/open-data/RecommendationTypes.csv new file mode 100644 index 000000000..9e5987a22 --- /dev/null +++ b/src/open-data/RecommendationTypes.csv @@ -0,0 +1,7 @@ +RecommendationTypeId,Category,Impact,ServiceName,ResourceType,DisplayName,LearnMoreLink +a06456ed-afb7-4d16-86fd-0054e25268ed,Performance,Medium,Virtual Machines,microsoft.compute/virtualmachines,Enable Accelerated Networking to improve network performance and latency,https://docs.microsoft.com/azure/virtual-network/create-vm-accelerated-networking-cli#enable-accelerated-networking-on-existing-vms +9c0c3708-17f6-4108-9aff-f0e052c3cd41,OperationalExcellence,Low,Azure App Service,microsoft.subscriptions/subscriptions,Eliminate replica staging environments and ship new versions and features with zero downtime using deployment slots,https://docs.microsoft.com/azure/app-service/deploy-staging-slots +a205074f-8049-48b3-903f-556f5e530ae3,Cost,High,ReservedInstances,microsoft.subscriptions/subscriptions,Buy reserved instance,https://aka.ms/rirecommendations +94aea435-ef39-493f-a547-8408092c22a7,Cost,High,Virtual Machine Scale Sets,microsoft.compute/virtualmachinescalesets,Shut down or resize your virtual machine scale sets,https://aka.ms/aa_lowusagerec_vmss_learnmore +afdf4c1a-e46b-4817-a5d6-4b9909f58e2a,Cost,Low,Azure Synapse Analytics,microsoft.synapse/workspaces,Consider enabling automatic pause feature on spark compute,https://aka.ms/EnableSynapseSparkComputeAutoPauseGuidance +ed651749-cd37-4fd5-9897-01b416926745,HighAvailability,Medium,Site Recovery,microsoft.compute/virtualmachines,Enable virtual machine replication,https://aka.ms/azure-site-recovery-dr-azure-vms diff --git a/src/powershell/Private/Get-OpenDataRecommendationType.ps1 b/src/powershell/Private/Get-OpenDataRecommendationType.ps1 new file mode 100644 index 000000000..5b76a0f3a --- /dev/null +++ b/src/powershell/Private/Get-OpenDataRecommendationType.ps1 @@ -0,0 +1,15 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +function Get-OpenDataRecommendationType +{ + param() + return [PSCustomObject]@( + [PSCustomObject]@{ RecommendationTypeId = 'a06456ed-afb7-4d16-86fd-0054e25268ed'; Category = 'Performance'; Impact = 'Medium'; ServiceName = 'Virtual Machines'; ResourceType = 'microsoft.compute/virtualmachines'; DisplayName = 'Enable Accelerated Networking to improve network performance and latency'; LearnMoreLink = 'https://docs.microsoft.com/azure/virtual-network/create-vm-accelerated-networking-cli#enable-accelerated-networking-on-existing-vms'; } + ,[PSCustomObject]@{ RecommendationTypeId = '9c0c3708-17f6-4108-9aff-f0e052c3cd41'; Category = 'OperationalExcellence'; Impact = 'Low'; ServiceName = 'Azure App Service'; ResourceType = 'microsoft.subscriptions/subscriptions'; DisplayName = 'Eliminate replica staging environments and ship new versions and features with zero downtime using deployment slots'; LearnMoreLink = 'https://docs.microsoft.com/azure/app-service/deploy-staging-slots'; } + ,[PSCustomObject]@{ RecommendationTypeId = 'a205074f-8049-48b3-903f-556f5e530ae3'; Category = 'Cost'; Impact = 'High'; ServiceName = 'ReservedInstances'; ResourceType = 'microsoft.subscriptions/subscriptions'; DisplayName = 'Buy reserved instance'; LearnMoreLink = 'https://aka.ms/rirecommendations'; } + ,[PSCustomObject]@{ RecommendationTypeId = '94aea435-ef39-493f-a547-8408092c22a7'; Category = 'Cost'; Impact = 'High'; ServiceName = 'Virtual Machine Scale Sets'; ResourceType = 'microsoft.compute/virtualmachinescalesets'; DisplayName = 'Shut down or resize your virtual machine scale sets'; LearnMoreLink = 'https://aka.ms/aa_lowusagerec_vmss_learnmore'; } + ,[PSCustomObject]@{ RecommendationTypeId = 'afdf4c1a-e46b-4817-a5d6-4b9909f58e2a'; Category = 'Cost'; Impact = 'Low'; ServiceName = 'Azure Synapse Analytics'; ResourceType = 'microsoft.synapse/workspaces'; DisplayName = 'Consider enabling automatic pause feature on spark compute'; LearnMoreLink = 'https://aka.ms/EnableSynapseSparkComputeAutoPauseGuidance'; } + ,[PSCustomObject]@{ RecommendationTypeId = 'ed651749-cd37-4fd5-9897-01b416926745'; Category = 'HighAvailability'; Impact = 'Medium'; ServiceName = 'Site Recovery'; ResourceType = 'microsoft.compute/virtualmachines'; DisplayName = 'Enable virtual machine replication'; LearnMoreLink = 'https://aka.ms/azure-site-recovery-dr-azure-vms'; } + ) +} diff --git a/src/powershell/Public/Get-FinOpsRecommendationType.ps1 b/src/powershell/Public/Get-FinOpsRecommendationType.ps1 new file mode 100644 index 000000000..bef7875e6 --- /dev/null +++ b/src/powershell/Public/Get-FinOpsRecommendationType.ps1 @@ -0,0 +1,103 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +<# + .SYNOPSIS + Gets metadata for Azure Advisor recommendation types. + + .PARAMETER RecommendationTypeId + Optional. The recommendation type ID (GUID) to filter by. Accepts wildcards. Default = * (all). + + .PARAMETER Category + Optional. The recommendation category to filter by. Accepts wildcards. Default = * (all). + Expected values: Cost, HighAvailability, OperationalExcellence, Performance, Security. + + .PARAMETER Impact + Optional. The impact level to filter by. Accepts wildcards. Default = * (all). + Expected values: High, Medium, Low. + + .PARAMETER ServiceName + Optional. The service name to filter by. Accepts wildcards. Default = * (all). + + .PARAMETER ResourceType + Optional. The resource type to filter by. Accepts wildcards. Default = * (all). + + .DESCRIPTION + The Get-FinOpsRecommendationType command returns metadata about Azure Advisor recommendation types + based on the specified filters. This data helps organize and provide additional context for + Azure Advisor recommendations in FinOps reports and dashboards. + + The recommendation type metadata includes: + - RecommendationTypeId - Unique GUID identifier + - Category - Cost, HighAvailability, OperationalExcellence, Performance, or Security + - Impact - High, Medium, or Low + - ServiceName - Name of the Azure service + - ResourceType - Azure resource type (lowercase) + - DisplayName - Human-readable description + - LearnMoreLink - URL to documentation + + .EXAMPLE + Get-FinOpsRecommendationType + + Returns all recommendation types. + + .EXAMPLE + Get-FinOpsRecommendationType -Category Cost + + Returns all cost-related recommendation types. + + .EXAMPLE + Get-FinOpsRecommendationType -Impact High -Category Cost + + Returns all high-impact cost recommendation types. + + .EXAMPLE + Get-FinOpsRecommendationType -ResourceType "microsoft.compute/virtualmachines" + + Returns all recommendation types that apply to virtual machines. + + .LINK + https://aka.ms/ftk/Get-FinOpsRecommendationType +#> +function Get-FinOpsRecommendationType() +{ + param( + [Parameter(Position = 0)] + [string] + $RecommendationTypeId = "*", + + [Parameter(Position = 1)] + [string] + $Category = "*", + + [Parameter(Position = 2)] + [string] + $Impact = "*", + + [string] + $ServiceName = "*", + + [string] + $ResourceType = "*" + ) + + return Get-OpenDataRecommendationType ` + | Where-Object { + $_.RecommendationTypeId -like $RecommendationTypeId ` + -and $_.Category -like $Category ` + -and $_.Impact -like $Impact ` + -and $_.ServiceName -like $ServiceName ` + -and $_.ResourceType -like $ResourceType + } ` + | ForEach-Object { + [PSCustomObject]@{ + RecommendationTypeId = $_.RecommendationTypeId + Category = $_.Category + Impact = $_.Impact + ServiceName = $_.ServiceName + ResourceType = $_.ResourceType + DisplayName = $_.DisplayName + LearnMoreLink = $_.LearnMoreLink + } + } +} diff --git a/src/powershell/Tests/Unit/Get-FinOpsRecommendationType.Tests.ps1 b/src/powershell/Tests/Unit/Get-FinOpsRecommendationType.Tests.ps1 new file mode 100644 index 000000000..3ccbc1ea6 --- /dev/null +++ b/src/powershell/Tests/Unit/Get-FinOpsRecommendationType.Tests.ps1 @@ -0,0 +1,109 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +& "$PSScriptRoot/../Initialize-Tests.ps1" + +InModuleScope 'FinOpsToolkit' { + Describe 'Get-FinOpsRecommendationType' { + BeforeAll { + function getAllRecommendationTypes( + [string]$RecommendationTypeId = "*", + [string]$Category = "*", + [string]$Impact = "*", + [string]$ServiceName = "*", + [string]$ResourceType = "*" + ) + { + Get-OpenDataRecommendationType ` + | Where-Object { + $_.RecommendationTypeId -like $RecommendationTypeId ` + -and $_.Category -like $Category ` + -and $_.Impact -like $Impact ` + -and $_.ServiceName -like $ServiceName ` + -and $_.ResourceType -like $ResourceType + } ` + | Select-Object -Property RecommendationTypeId, Category, Impact, ServiceName, ResourceType, DisplayName, LearnMoreLink -Unique + } + } + Context "No parameters" { + BeforeAll { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "")] + $actual = Get-FinOpsRecommendationType + } + It 'Should return all recommendation types by default' { + # Arrange + $expected = getAllRecommendationTypes + + # Act + # Assert + $expected.Count | Should -BeGreaterThan 0 + $actual.Count | Should -Be $expected.Count + } + } + Context "Wildcards" { + It 'Should return Cost category matches' { + # Arrange + $filter = 'Cost' + $expected = getAllRecommendationTypes -Category $filter + + # Act + $actual = Get-FinOpsRecommendationType -Category $filter + + # Assert + $expected.Count | Should -BeGreaterThan 0 + $actual.Count | Should -Be $expected.Count + } + It 'Should return High impact matches' { + # Arrange + $filter = 'High' + $expected = getAllRecommendationTypes -Impact $filter + + # Act + $actual = Get-FinOpsRecommendationType -Impact $filter + + # Assert + $expected.Count | Should -BeGreaterThan 0 + $actual.Count | Should -Be $expected.Count + } + It 'Should return Virtual* wildcard ServiceName matches' { + # Arrange + $filter = 'Virtual*' + $expected = getAllRecommendationTypes -ServiceName $filter + + # Act + $actual = Get-FinOpsRecommendationType -ServiceName $filter + + # Assert + $expected.Count | Should -BeGreaterThan 0 + $actual.Count | Should -Be $expected.Count + } + It 'Should return *virtualmachines wildcard ResourceType matches' { + # Arrange + $filter = '*virtualmachines' + $expected = getAllRecommendationTypes -ResourceType $filter + + # Act + $actual = Get-FinOpsRecommendationType -ResourceType $filter + + # Assert + $expected.Count | Should -BeGreaterThan 0 + $actual.Count | Should -Be $expected.Count + } + } + Context "Specific recommendations" { + It 'Should return a specific recommendation by ID' { + # Arrange + $id = 'a06456ed-afb7-4d16-86fd-0054e25268ed' + $expected = getAllRecommendationTypes -RecommendationTypeId $id + + # Act + $actual = Get-FinOpsRecommendationType -RecommendationTypeId $id + + # Assert + $expected.Count | Should -Be 1 + $actual.Count | Should -Be $expected.Count + $actual[0].RecommendationTypeId | Should -Be $id + } + } + } +} diff --git a/src/powershell/Tests/Unit/Get-OpenDataRecommendationType.Tests.ps1 b/src/powershell/Tests/Unit/Get-OpenDataRecommendationType.Tests.ps1 new file mode 100644 index 000000000..9d974c9bf --- /dev/null +++ b/src/powershell/Tests/Unit/Get-OpenDataRecommendationType.Tests.ps1 @@ -0,0 +1,16 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +Describe 'Get-OpenDataRecommendationType' { + It 'Should return same rows as the CSV file' { + # Arrange + . "$PSScriptRoot/../../Private/Get-OpenDataRecommendationType.ps1" + $csv = Import-Csv "$PSScriptRoot/../../../open-data/RecommendationTypes.csv" + + # Act + $cmd = Get-OpenDataRecommendationType + + # Assert + $cmd.Count | Should -Be $csv.Count + } +} diff --git a/src/scripts/Build-OpenData.ps1 b/src/scripts/Build-OpenData.ps1 index be8ffe2ec..35ecd1a3a 100644 --- a/src/scripts/Build-OpenData.ps1 +++ b/src/scripts/Build-OpenData.ps1 @@ -6,7 +6,7 @@ Creates open data files and compiles contents into corresponding PowerShell functions. .PARAMETER Name - Name of the data to build. Allowed = PricingUnits, Regions, ResourceTypes, Services. Default = * (all). + Name of the data to build. Allowed = PricingUnits, Regions, RecommendationTypes, ResourceTypes, Services. Default = * (all). .PARAMETER Json Indicates that JSON files should be generated. Only applies to resource types. Default = false, if -PowerShell is not specified. @@ -38,6 +38,11 @@ Step 3: Generates PowerShell commands and run tests for all datasets. + .EXAMPLE + ./Build-OpenData RecommendationTypes + + Generates a private Get-OpenDataRecommendationType PowerShell function from the contents of open-data/RecommendationTypes.csv. + .EXAMPLE ./Build-OpenData Services diff --git a/src/scripts/Get-AdvisorRecommendationTypes.ps1 b/src/scripts/Get-AdvisorRecommendationTypes.ps1 new file mode 100644 index 000000000..48e57e0b1 --- /dev/null +++ b/src/scripts/Get-AdvisorRecommendationTypes.ps1 @@ -0,0 +1,147 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +<# + .SYNOPSIS + Retrieves Azure Advisor recommendation type metadata from the Azure Advisor API. + + .DESCRIPTION + The Get-AdvisorRecommendationTypes script calls the Azure Advisor Recommendation Metadata API + to retrieve metadata about all available recommendation types. This includes recommendation IDs, + categories, impact levels, service names, and learn more links. + + The output is saved as a CSV file that can be used as open data for FinOps reporting and analysis. + + .PARAMETER OutputPath + Optional. Path where the CSV file should be saved. Defaults to src/open-data/RecommendationTypes.csv. + + .PARAMETER SubscriptionId + Optional. Azure subscription ID to use for authentication. If not specified, uses the current context. + + .EXAMPLE + ./Get-AdvisorRecommendationTypes.ps1 + + Retrieves recommendation metadata and saves to the default location. + + .EXAMPLE + ./Get-AdvisorRecommendationTypes.ps1 -OutputPath "C:\temp\recommendations.csv" + + Retrieves recommendation metadata and saves to a custom location. + + .LINK + https://learn.microsoft.com/rest/api/advisor/recommendation-metadata/list +#> + +param( + [Parameter()] + [string] + $OutputPath = "$PSScriptRoot/../open-data/RecommendationTypes.csv", + + [Parameter()] + [string] + $SubscriptionId +) + +# Ensure Az.Accounts module is available +if (-not (Get-Module -ListAvailable -Name Az.Accounts)) +{ + Write-Error "Az.Accounts module is required. Please install it using: Install-Module -Name Az.Accounts" + return +} + +# Import required modules +Import-Module Az.Accounts -ErrorAction Stop + +# Get the current Azure context +$context = Get-AzContext +if (-not $context) +{ + Write-Error "No Azure context found. Please run Connect-AzAccount first." + return +} + +if ($SubscriptionId) +{ + Set-AzContext -SubscriptionId $SubscriptionId | Out-Null + $context = Get-AzContext +} + +Write-Output "Using subscription: $($context.Subscription.Name) ($($context.Subscription.Id))" + +# Get access token for Azure Management API +$token = (Get-AzAccessToken -ResourceUrl "https://management.azure.com").Token + +# Set up API request +$apiVersion = "2023-01-01" +$uri = "https://management.azure.com/providers/Microsoft.Advisor/metadata?api-version=$apiVersion" + +Write-Output "Fetching recommendation metadata from Azure Advisor API..." + +# Call the API +$headers = @{ + "Authorization" = "Bearer $token" + "Content-Type" = "application/json" +} + +try +{ + $response = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get +} +catch +{ + Write-Error "Failed to retrieve recommendation metadata: $_" + return +} + +Write-Output "Retrieved $($response.value.Count) metadata entities" + +# Find the recommendationType metadata +$recommendationTypeMetadata = $response.value | Where-Object { $_.name -eq "recommendationType" } + +if (-not $recommendationTypeMetadata) +{ + Write-Error "Could not find recommendationType metadata in the response" + return +} + +Write-Output "Found $($recommendationTypeMetadata.properties.supportedValues.Count) recommendation types" + +# Create array to store recommendation data +$recommendations = @() + +# Process each recommendation type +foreach ($rec in $recommendationTypeMetadata.properties.supportedValues) +{ + # The ID is the recommendation type GUID + $recId = $rec.id + $displayName = $rec.displayName + + # Create recommendation object + # Note: The API doesn't provide all the columns from the issue sample (Category, Impact, ServiceName, etc.) + # Those might need to be sourced from other locations or parsed from the displayName + $recommendation = [PSCustomObject]@{ + RecommendationTypeId = $recId + DisplayName = $displayName + } + + $recommendations += $recommendation +} + +# Sort by DisplayName +$recommendations = $recommendations | Sort-Object -Property DisplayName + +# Create output directory if it doesn't exist +$outputDir = Split-Path -Parent $OutputPath +if (-not (Test-Path $outputDir)) +{ + New-Item -ItemType Directory -Path $outputDir -Force | Out-Null +} + +# Export to CSV +$recommendations | Export-Csv -Path $OutputPath -NoTypeInformation -Force + +Write-Output "Exported $($recommendations.Count) recommendation types to: $OutputPath" +Write-Output "" +Write-Output "Note: The API only provides RecommendationTypeId and DisplayName." +Write-Output "Additional metadata like Category, Impact, ServiceName, ResourceType, etc." +Write-Output "may need to be sourced from other locations or parsed from active recommendations."