diff --git a/docs-mslearn/toolkit/powershell/cost/add-finopsserviceprincipal.md b/docs-mslearn/toolkit/powershell/cost/add-finopsserviceprincipal.md index 8d4a0262f..6561adcce 100644 --- a/docs-mslearn/toolkit/powershell/cost/add-finopsserviceprincipal.md +++ b/docs-mslearn/toolkit/powershell/cost/add-finopsserviceprincipal.md @@ -3,7 +3,7 @@ title: Add-FinOpsServicePrincipal command description: Grants the specified service principal or managed identity access to an Enterprise Agreement billing account or department. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 ms.topic: reference ms.service: finops ms.subservice: finops-toolkit @@ -13,7 +13,7 @@ ms.reviewer: brettwil # Add-FinOpsServicePrincipal command -The **Add-FinOpsServicePrincipal** command grants the specified service principal or managed identity access to an Enterprise Agreement billing account or department. +The **Add-FinOpsServicePrincipal** command grants the specified service principal or managed identity access to an Enterprise Agreement billing account or department. For more information about granting roles to service principals, see [Assign Enterprise Agreement roles to service principals](/azure/cost-management-billing/manage/assign-roles-azure-service-principals). For more information about the permissions associated with each role, see [Usage and costs access by role](/azure/cost-management-billing/manage/understand-ea-roles#usage-and-costs-access-by-role). @@ -23,22 +23,22 @@ For more information about granting roles to service principals, see [Assign Ent ```powershell Add-FinOpsServicePrincipal ` - -ObjectId 00000000-0000-0000-0000-000000000000 ` - -TenantId 00000000-0000-0000-0000-000000000000 ` - -BillingAccountId 12345 ` - -DepartmentId 67890 + [‑ObjectId] ` + [‑TenantId] ` + [‑BillingAccountId] ` + [[‑DepartmentId] ] ```
## Parameters -| Name | Description | -| ------------------ | ---------------------------------------------------------------------------------- | -| `ObjectId` | Required. The object ID of the service principal or managed identity. | -| `TenantId` | Required. The Azure Active Directory tenant which contains the identity. | -| `BillingAccountId` | Required. The billing account ID (enrollment number) to grant permissions against. | -| `DepartmentId` | Optional. The department ID to grant permissions against. | +| Name | Description | +| ------------------- | ---------------------------------------------------------------------------------- | +| `‑ObjectId` | Required. The object ID of the service principal or managed identity. | +| `‑TenantId` | Required. The Azure Active Directory tenant which contains the identity. | +| `‑BillingAccountId` | Required. The billing account ID (enrollment number) to grant permissions against. | +| `‑DepartmentId` | Optional. The department ID to grant permissions against. |
@@ -49,10 +49,7 @@ The following examples demonstrate how to use the Add-FinOpsServicePrincipal com ### Enterprise Administrator (read only) ```powershell -Add-FinOpsServicePrincipal ` - -ObjectId 00000000-0000-0000-0000-000000000000 ` - -TenantId 00000000-0000-0000-0000-000000000000 ` - -BillingAccountId 12345 +Add-FinOpsServicePrincipal -ObjectId 00000000-0000-0000-0000-000000000000 -TenantId 00000000-0000-0000-0000-000000000000 -BillingAccountId 12345 ``` Grants Enterprise Administrator (read only) permissions to the specified service principal or managed identity. @@ -60,11 +57,7 @@ Grants Enterprise Administrator (read only) permissions to the specified service ### Department Administrator (read only) ```powershell -Add-FinOpsServicePrincipal ` - -ObjectId 00000000-0000-0000-0000-000000000000 ` - -TenantId 00000000-0000-0000-0000-000000000000 ` - -BillingAccountId 12345 ` - -DepartmentId 67890 +Add-FinOpsServicePrincipal -ObjectId 00000000-0000-0000-0000-000000000000 -TenantId 00000000-0000-0000-0000-000000000000 -BillingAccountId 12345 -DepartmentId 67890 ``` Grants Department Administrator (read only) permissions to the specified service principal or managed identity. diff --git a/docs-mslearn/toolkit/powershell/cost/cost-management-commands.md b/docs-mslearn/toolkit/powershell/cost/cost-management-commands.md index 2542f4fbf..c086627c9 100644 --- a/docs-mslearn/toolkit/powershell/cost/cost-management-commands.md +++ b/docs-mslearn/toolkit/powershell/cost/cost-management-commands.md @@ -3,7 +3,7 @@ title: Cost Management commands description: Learn about PowerShell commands in the FinOpsToolkit module to support Cost Management capabilities. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 ms.topic: reference ms.service: finops ms.subservice: finops-toolkit @@ -19,6 +19,7 @@ The Cost Management PowerShell commands help you manage Cost Management features ## Commands +- [Add-FinOpsServicePrincipal](add-finopsserviceprincipal.md) – Grants a service principal or managed identity access to an Enterprise Agreement billing account or department. - [Get-FinOpsCostExport](Get-FinOpsCostExport.md) – Get details about Cost Management exports. - [New-FinOpsCostExport](New-FinOpsCostExport.md) – Create a new Cost Management export. - [Remove-FinOpsCostExport](Remove-FinOpsCostExport.md) – Delete a Cost Management export and optionally data associated with the export. diff --git a/docs-mslearn/toolkit/powershell/cost/get-finopscostexport.md b/docs-mslearn/toolkit/powershell/cost/get-finopscostexport.md index 15efa2ac4..9fe5c4861 100644 --- a/docs-mslearn/toolkit/powershell/cost/get-finopscostexport.md +++ b/docs-mslearn/toolkit/powershell/cost/get-finopscostexport.md @@ -3,12 +3,12 @@ title: Get-FinOpsCostExport command description: Get a list of Cost Management exports for a given scope using the Get-FinOpsCostExport command in the FinOpsToolkit module. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 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 what Get-FinOpsCostExport command in the FinOpsToolkit module. +#customer intent: As a FinOps user, I want to understand how to use the Get-FinOpsCostExport command in the FinOpsToolkit module. --- # Get-FinOpsCostExport command @@ -28,30 +28,30 @@ This command was tested with the following API versions: ```powershell Get-FinOpsCostExport ` - [-Name ] ` - [-Scope ] ` - [-DataSet ] ` - [-DataSetVersion ] ` - [-StorageAccountId ] ` - [-StorageContainer ] ` - [-RunHistory] ` - [-ApiVersion ] + [[‑Name] ] ` + [[‑Scope] ] ` + [[‑Dataset] ] ` + [[‑DatasetVersion] ] ` + [[‑StorageAccountId] ] ` + [[‑StorageContainer] ] ` + [‑RunHistory] ` + [[‑ApiVersion] ] ```
## Parameters -| Name | Description | -| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `‑Name` | Optional. Name of the export. Supports wildcards. | -| `‑Scope` | Optional. Resource ID of the scope the export was created for. If empty, defaults to current subscription context. | -| `‑DataSet` | Optional. Dataset to get exports for. Allowed values = "ActualCost", "AmortizedCost", "FocusCost", "PriceSheet", "ReservationDetails", "ReservationTransactions", "ReservationRecommendations". Default = null (all exports). | -| `‑DataSetVersion` | Optional. Schema version of the dataset to export. Default = null (all exports). | -| `‑StorageAccountId` | Optional. Resource ID of the storage account to get exports for. Default = null (all exports). | -| `‑StorageContainer` | Optional. Name of the container to get exports for. Supports wildcards. Default = null (all exports). | -| `‑RunHistory` | Optional. Indicates whether the run history should be expanded. Default = false. | -| `‑ApiVersion` | Optional. API version to use when calling the Cost Management exports API. Default = 2025-03-01. | +| Name | Description | +| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `‑Name` | Optional. Name of the export. Supports wildcards. | +| `‑Scope` | Optional. Resource ID of the scope the export was created for. If empty, defaults to current subscription context. | +| `‑Dataset` | Optional. Dataset to export. Allowed values = "ActualCost", "AmortizedCost", "FocusCost", "PriceSheet", "ReservationDetails", "ReservationTransactions", "ReservationRecommendations". Default = null (all exports). | +| `‑DatasetVersion` | Optional. Schema version of the dataset to export. Default = null (all exports). | +| `‑StorageAccountId` | Optional. Resource ID of the storage account to get exports for. Default = null (all exports). | +| `‑StorageContainer` | Optional. Name of the container to get exports for. Supports wildcards. Default = null (all exports). | +| `‑RunHistory` | Optional. Indicates whether the run history should be expanded. Default = false. | +| `‑ApiVersion` | Optional. API version to use when calling the Cost Management exports API. Default = 2025-03-01. |
@@ -89,16 +89,21 @@ Get-FinOpsCostExport ` ### FinOpsCostExportRunHistory object -| Property | Type | JSON path | -| --------------- | -------- | -------------------------------------------------------- | -| `Id` | String | `properties.runHistory.value[].id` | -| `ExecutionType` | String | `properties.runHistory.value[].properties.executionType` | -| `FileName` | String | `properties.runHistory.value[].fileName` | -| `StartTime` | DateTime | `properties.runHistory.value[].processingStartTime` | -| `EndTime` | DateTime | `properties.runHistory.value[].processingEndTime` | -| `Status` | String | `properties.runHistory.value[].status` | -| `SubmittedBy` | String | `properties.runHistory.value[].submittedBy` | -| `SubmittedTime` | DateTime | `properties.runHistory.value[].submittedTime` | +| Property | Type | JSON path | +| ---------------- | -------- | ----------------------------------------------------------- | +| `ResourceId` | String | `properties.runHistory.value[].id` | +| `RunId` | String | `properties.runHistory.value[].name` | +| `ExecutionType` | String | `properties.runHistory.value[].properties.executionType` | +| `Status` | String | `properties.runHistory.value[].properties.status` | +| `SubmittedBy` | String | `properties.runHistory.value[].properties.submittedBy` | +| `SubmittedTime` | DateTime | `properties.runHistory.value[].properties.submittedTime` | +| `RunStartTime` | DateTime | `properties.runHistory.value[].properties.processingStartTime` | +| `RunEndTime` | DateTime | `properties.runHistory.value[].properties.processingEndTime` | +| `FileName` | String | `properties.runHistory.value[].properties.fileName` | +| `QueryStartDate` | DateTime | `properties.runHistory.value[].properties.startDate` | +| `QueryEndDate` | DateTime | `properties.runHistory.value[].properties.endDate` | +| `ErrorCode` | String | `properties.runHistory.value[].properties.error.code` | +| `ErrorMessage` | String | `properties.runHistory.value[].properties.error.message` |
@@ -107,27 +112,23 @@ Get-FinOpsCostExport ` ### Get all cost exports for a subscription ```powershell -Get-FinOpsCostExport ` - -Scope "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e" +Get-FinOpsCostExport -Scope "/subscriptions/00000000-0000-0000-0000-000000000000" ``` -Gets all exports for a subscription. Doesn't include exports in nested resource groups. +Gets all exports for a subscription. Does not include exports in nested resource groups. ### Get exports matching a wildcard name ```powershell -Get-FinOpsCostExport ` - -Name mtd* ` - -Scope "providers/Microsoft.Billing/billingAccounts/00000000" +Get-FinOpsCostExport -Name mtd* -Scope "providers/Microsoft.Billing/billingAccounts/00000000" ``` -Gets export with name matching wildcard mtd\* within the specified billing account scope. Doesn't include exports in nested resource groups. +Gets export with name matching wildcard mtd* within the specified billing account scope. Does not include exports in nested resource groups. ### Get all amortized cost exports ```powershell -Get-FinOpsCostExport ` - -DataSet "AmortizedCost" +Get-FinOpsCostExport -Dataset "AmortizedCost" ``` Gets all exports within the current context subscription scope and filtered by dataset AmortizedCost. @@ -135,9 +136,7 @@ Gets all exports within the current context subscription scope and filtered by d ### Get exports using a specific storage account ```powershell -Get-FinOpsCostExport ` - -Scope "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e"` - -StorageAccountId "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/MyResourceGroup/providers/Microsoft.Storage/storageAccounts/MyStorageAccount" +Get-FinOpsCostExport -Scope "/subscriptions/00000000-0000-0000-0000-000000000000" -StorageAccountId "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Storage/storageAccounts/MyStorageAccount" ``` Gets all exports within the subscription scope filtered by a specific storage account. @@ -145,9 +144,7 @@ Gets all exports within the subscription scope filtered by a specific storage ac ### Get exports using a specific container ```powershell -Get-FinOpsCostExport ` - -Scope "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e" ` - -StorageContainer "MyContainer*" +Get-FinOpsCostExport -Scope "/subscriptions/00000000-0000-0000-0000-000000000000" -StorageContainer "MyContainer*" ``` Gets all exports within the subscription scope for a specific container. Supports wildcard. @@ -155,11 +152,7 @@ Gets all exports within the subscription scope for a specific container. Support ### Get exports using a specific API version ```powershell -Get-FinOpsCostExport ` - -Scope "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e" - -StorageContainer "mtd*" - -ApiVersion "2023-08-01" - -StorageContainer "MyContainer*" +Get-FinOpsCostExport -Scope "/subscriptions/00000000-0000-0000-0000-000000000000" -StorageContainer "mtd*" -ApiVersion "2025-03-01" ``` Gets all exports within the subscription scope for a container matching wildcard pattern and using a specific API version. diff --git a/docs-mslearn/toolkit/powershell/cost/new-finopscostexport.md b/docs-mslearn/toolkit/powershell/cost/new-finopscostexport.md index 3d53ee583..1373c7a6b 100644 --- a/docs-mslearn/toolkit/powershell/cost/new-finopscostexport.md +++ b/docs-mslearn/toolkit/powershell/cost/new-finopscostexport.md @@ -3,12 +3,12 @@ title: New-FinOpsCostExport command description: Create a new Cost Management export for the specified scope using the New-FinOpsCostExport command in the FinOpsToolkit module. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 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 what New-FinOpsCostExport command in the FinOpsToolkit module. +#customer intent: As a FinOps user, I want to understand how to use the New-FinOpsCostExport command in the FinOpsToolkit module. --- # New-FinOpsCostExport command @@ -28,42 +28,60 @@ This command was tested with the following API versions: ```powershell # Create a new daily/monthly export New-FinOpsCostExport ` - [-Name] ` - -Scope ` - [-Dataset ] ` - [-DatasetVersion ] ` - [-DatasetFilters ] ` - [-Monthly] ` - [-StartDate ] ` - [-EndDate ] ` - -StorageAccountId ` - [-StorageContainer ] ` - [-StoragePath ] ` - [-Location] ` - [-DoNotPartition] ` - [-DoNotOverwrite] ` - [-Execute] ` - [-Backfill ] ` - [-ApiVersion ] + ‑Name ` + ‑Scope ` + [‑Dataset ] ` + [‑Format ] ` + [‑CompressionMode ] ` + [‑DatasetVersion ] ` + [‑DatasetFilters ] ` + [‑CommitmentDiscountScope ] ` + [‑CommitmentDiscountResourceType ] ` + [‑CommitmentDiscountLookback ] ` + [‑Monthly] ` + [‑StartDate ] ` + [‑EndDate ] ` + ‑StorageAccountId ` + [‑StorageContainer ] ` + [‑StoragePath ] ` + [‑Location ] ` + [‑DoNotPartition] ` + [‑DoNotOverwrite] ` + [‑SystemAssignedIdentity] ` + [‑Execute] ` + [‑Backfill ] ` + [‑ApiVersion ] ` + [‑WhatIf] ` + [] ``` ```powershell # Create a new one-time export New-FinOpsCostExport ` - [-Name] ` - -Scope ` - [-Dataset ] ` - [-DatasetVersion ] ` - [-DatasetFilters ] ` - -OneTime ` - -StartDate ` - -EndDate ` - -StorageAccountId ` - [-StorageContainer ] ` - [-StoragePath ] ` - [-Location] ` - [-DoNotPartition] ` - [-ApiVersion ] + ‑Name ` + ‑Scope ` + [‑Dataset ] ` + [‑Format ] ` + [‑CompressionMode ] ` + [‑DatasetVersion ] ` + [‑DatasetFilters ] ` + [‑CommitmentDiscountScope ] ` + [‑CommitmentDiscountResourceType ] ` + [‑CommitmentDiscountLookback ] ` + [‑OneTime] ` + [‑StartDate ] ` + [‑EndDate ] ` + ‑StorageAccountId ` + [‑StorageContainer ] ` + [‑StoragePath ] ` + [‑Location ] ` + [‑DoNotPartition] ` + [‑DoNotOverwrite] ` + [‑SystemAssignedIdentity] ` + [‑Execute] ` + [‑ApiVersion ] ` + [‑WhatIf] ` + [] ```
@@ -75,6 +93,8 @@ New-FinOpsCostExport ` | `‑Name` | Required. Name of the export. | | `‑Scope` | Required. Resource ID of the scope to export data for. | | `‑Dataset` | Optional. Dataset to export. Allowed values = "ActualCost", "AmortizedCost", "FocusCost", "PriceSheet", "ReservationDetails", "ReservationRecommendations", "ReservationTransactions". Default = "FocusCost". | +| `‑Format` | Optional. Format of the export files. Allowed values = "Csv", "Parquet". Default = "Csv". | +| `‑CompressionMode` | Optional. Compression used for exported files. Allowed values = "None", "GZip", "Snappy". Default = "None". | | `‑DatasetVersion` | Optional. Schema version of the dataset to export. Default = "1.2-preview" (applies to FocusCost only). | | `‑DatasetFilters` | Optional. Dictionary of key/value pairs to filter the dataset with. Only applies to ReservationRecommendations dataset in 2023-07-01-preview or newer. Valid filters are reservationScope (Shared or Single), resourceType (for example, VirtualMachines), lookBackPeriod (Last7Days, Last30Days, Last60Days). | | `‑CommitmentDiscountScope` | Optional. Reservation scope filter to use when exporting reservation recommendations. Ignored for other export types. Allowed values: Shared, Single. Default: Shared. | @@ -87,13 +107,14 @@ New-FinOpsCostExport ` | `‑StorageAccountId` | Required. Resource ID of the storage account to export data to. | | `‑StorageContainer` | Optional. Name of the container to export data to. Container is created if it doesn't exist. Default = "cost-management". | | `‑StoragePath` | Optional. Path to export data to within the storage container. Default = (scope ID). | +| `‑Location` | Optional. Indicates the Azure location to use for the managed identity used to push data to the storage account. Managed identity is required in order to work with storage accounts behind a firewall but require access to grant permissions (for example, Owner). If specified, managed identity will be used; otherwise, managed identity will not be used and your export will not be able to push data to a storage account behind a firewall. Default = (empty). | | `‑DoNotPartition` | Optional. Indicates whether to partition the exported data into multiple files. Partitioning is recommended for reliability so this option is to disable partitioning. Default = false. | | `‑DoNotOverwrite` | Optional. Indicates whether to overwrite previously exported data for the current month. Overwriting is recommended to keep storage size and costs down so this option is to disable overwriting. If creating an export for FinOps hubs, we recommend you specify the -DoNotOverwrite option to improve troubleshooting. Default = false. | | `‑SystemAssignedIdentity` | Optional. Indicates that managed identity should be used to push data to the storage account. Managed identity is required in order to work with storage accounts behind a firewall but require access to grant permissions (for example, Owner). If specified, managed identity will be used; otherwise, managed identity will not be used and your export will not be able to push data to a storage account behind a firewall. Default = (empty). | -| `‑Location` | Optional. Indicates the Azure location to use for the managed identity used to push data to the storage account. Managed identity is required in order to work with storage accounts behind a firewall but require access to grant permissions (for example, Owner). If specified, managed identity will be used; otherwise, managed identity will not be used and your export will not be able to push data to a storage account behind a firewall. Default = (empty). | | `‑Execute` | Optional. Indicates that the export should be run immediately after created. | | `‑Backfill` | Optional. Number of months to export the data for. This is only run once at create time. Failed exports are not re-attempted. Not supported when -OneTime is set. Default = 0. | | `‑ApiVersion` | Optional. API version to use when calling the Cost Management Exports API. Default = 2025-03-01. | +| `‑WhatIf` | Optional. Shows what would happen if the command runs without actually running it. |
@@ -103,8 +124,8 @@ New-FinOpsCostExport ` ```powershell New-FinopsCostExport -Name 'July2023OneTime' ` - -Scope "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e" ` - -StorageAccountId "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/SharedStorage/providers/Microsoft.Storage/storageAccounts/ddsharedstorage" ` + -Scope "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ` + -StorageAccountId "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/SharedStorage/providers/Microsoft.Storage/storageAccounts/ddsharedstorage" ` -DataSet ActualCost ` -OneTime ` -StartDate "2023-07-01" ` @@ -117,8 +138,8 @@ Creates a new one time export called 'July2023OneTime' from **2023-07-01** to ** ```powershell New-FinopsCostExport -Name 'DailyMTD' ` - -Scope "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e" ` - -StorageAccountId "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/SharedStorage/providers/Microsoft.Storage/storageAccounts/ddsharedstorage" ` + -Scope "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ` + -StorageAccountId "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/SharedStorage/providers/Microsoft.Storage/storageAccounts/ddsharedstorage" ` -DataSet AmortizedCost ` -EndDate "2024-12-31" ` -Execute @@ -130,8 +151,8 @@ Creates a new scheduled export called **Daily-MTD** with StartDate = DateTime.No ```powershell New-FinopsCostExport -Name 'Monthly-Report' ` - -Scope "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e" ` - -StorageAccountId "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/SharedStorage/providers/Microsoft.Storage/storageAccounts/ddsharedstorage" ` + -Scope "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ` + -StorageAccountId "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/SharedStorage/providers/Microsoft.Storage/storageAccounts/ddsharedstorage" ` -DataSet AmortizedCost ` -StartDate $(Get-Date).AddDays(5) ` -EndDate "2024-08-15" ` @@ -145,8 +166,8 @@ Creates a new monthly export called **Monthly-Report** with StartDate = 1 day fr ```powershell New-FinopsCostExport -Name 'Daily--MTD' ` - -Scope "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e" ` - -StorageAccountId "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/SharedStorage/providers/Microsoft.Storage/storageAccounts/ddsharedstorage" ` + -Scope "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ` + -StorageAccountId "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/SharedStorage/providers/Microsoft.Storage/storageAccounts/ddsharedstorage" ` -DataSet ActualCost ` -StorageContainer "costreports" ` -Backfill 4 ` diff --git a/docs-mslearn/toolkit/powershell/cost/remove-finopscostexport.md b/docs-mslearn/toolkit/powershell/cost/remove-finopscostexport.md index 6075309f4..1f6f0cbfe 100644 --- a/docs-mslearn/toolkit/powershell/cost/remove-finopscostexport.md +++ b/docs-mslearn/toolkit/powershell/cost/remove-finopscostexport.md @@ -3,17 +3,17 @@ title: Remove-FinOpsCostExport command description: Delete a Cost Management export and optionally data associated with the export using the Remove-FinOpsCostExport command in the FinOpsToolkit module. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 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 what Remove-FinOpsCostExport command in the FinOpsToolkit module. +#customer intent: As a FinOps user, I want to understand how to use the Remove-FinOpsCostExport command in the FinOpsToolkit module. --- # Remove-FinOpsCostExport command -The **Remove-FinOpsCostExport** command deletes a Cost Management export and optionally data associated with the export. +The **Remove-FinOpsCostExport** command deletes a Cost Management export and optionally deletes all data associated with the export from the related storage account. This command was tested with the following API versions: @@ -28,22 +28,25 @@ This command was tested with the following API versions: ```powershell Remove-FinOpsCostExport ` - -Name ` - -Scope ` - [-RemoveData ] ` - [-ApiVersion ] ` + [‑Name] ` + [‑Scope] ` + [‑RemoveData] ` + [[‑ApiVersion] ] ` + [‑WhatIf] ` + [] ```
## Parameters -| Name | Description | -| ------------- | ---------------------------------------------------------------------------------------------------- | -| `‑Name` | Required. Name of the Cost Management export. | -| `‑Scope` | Required. Resource ID of the scope to export data for context. | -| `‑RemoveData` | Optional. Optional. Indicates that all cost data associated with the Export scope should be deleted. | -| `‑ApiVersion` | Optional. API version to use when calling the Cost Management exports API. Default = 2025-03-01. | +| Name | Description | +| ------------- | ------------------------------------------------------------------------------------------------ | +| `‑Name` | Required. Name of the Cost Management export to delete. | +| `‑Scope` | Required. Resource ID of the scope to export data for. | +| `‑RemoveData` | Optional. Indicates that all cost data associated with the Export scope should be deleted. | +| `‑ApiVersion` | Optional. API version to use when calling the Cost Management Exports API. Default = 2025-03-01. | +| `‑WhatIf` | Optional. Shows what would happen if the command runs without actually running it. |
@@ -52,10 +55,7 @@ Remove-FinOpsCostExport ` ### Delete a Cost Management export ```powershell -Remove-FinOpsCostExport ` - -Name MyExport` - -Scope "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e"` - -RemoveData +Remove-FinOpsCostExport -Name MyExport -Scope "/subscriptions/00000000-0000-0000-0000-000000000000" -RemoveData ``` Deletes a Cost Management export and removes the exported data from the linked storage account. diff --git a/docs-mslearn/toolkit/powershell/cost/start-finopscostexport.md b/docs-mslearn/toolkit/powershell/cost/start-finopscostexport.md index 45ebaf118..6ff69cddd 100644 --- a/docs-mslearn/toolkit/powershell/cost/start-finopscostexport.md +++ b/docs-mslearn/toolkit/powershell/cost/start-finopscostexport.md @@ -3,12 +3,12 @@ title: Start-FinOpsCostExport command description: Initiate a Cost Management export run for the most recent period using the Start-FinOpsCostExport command in the FinOpsToolkit module. author: flanakin ms.author: micflan -ms.date: 08/22/2026 +ms.date: 08/27/2026 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 what Start-FinOpsCostExport command in the FinOpsToolkit module. +#customer intent: As a FinOps user, I want to understand how to use the Start-FinOpsCostExport command in the FinOpsToolkit module. --- # Start-FinOpsCostExport command @@ -20,6 +20,7 @@ This command was tested with the following API versions: - 2025-03-01 (default) – GA version for FocusCost and other datasets. - 2023-07-01-preview - 2023-08-01 +- 2023-03-01
@@ -27,12 +28,14 @@ This command was tested with the following API versions: ```powershell Start-FinOpsCostExport ` - [-Name] ` - [-Scope ] ` - [-StartDate ] ` - [-EndDate ] ` - [-Backfill ] ` - [-ApiVersion ] + [‑Name] ` + [[‑Scope] ] ` + [[‑StartDate] ] ` + [[‑EndDate] ] ` + [[‑Backfill] ] ` + [[‑ApiVersion] ] ` + [‑WhatIf] ` + [] ```
@@ -47,6 +50,7 @@ Start-FinOpsCostExport ` | `‑EndDate` | Optional. Last day to pull data for. Interpreted as a UTC calendar date, so the day you specify is the day that gets exported, regardless of your local time zone. If not set and -StartDate is set, -EndDate uses the last day of the month. If not set and -StartDate isn't set, the export uses the dates defined in the export configuration. | | `‑Backfill` | Optional. Number of months to export the data for. Make note of throttling (429) errors. It only runs once. Failed exports aren't reattempted. Default = 0. | | `‑ApiVersion` | Optional. API version to use when calling the Cost Management Exports API. Default = 2025-03-01. | +| `‑WhatIf` | Optional. Shows what would happen if the command runs without actually running it. |
diff --git a/docs-mslearn/toolkit/powershell/data/get-finopspricingunit.md b/docs-mslearn/toolkit/powershell/data/get-finopspricingunit.md index 7e79f009a..c90235415 100644 --- a/docs-mslearn/toolkit/powershell/data/get-finopspricingunit.md +++ b/docs-mslearn/toolkit/powershell/data/get-finopspricingunit.md @@ -3,12 +3,12 @@ title: Get-FinOpsPricingUnit command description: Get a pricing unit, distinct unit, and block size using the Get-FinOpsPricingUnit command in the FinOpsToolkit module. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 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 what Get-FinOpsPricingUnit command in the FinOpsToolkit module. +#customer intent: As a FinOps user, I want to understand how to use the Get-FinOpsPricingUnit command in the FinOpsToolkit module. --- # Get-FinOpsPricingUnit command @@ -24,20 +24,20 @@ The **Get-FinOpsPricingUnit** command returns a pricing unit (also known as unit ```powershell Get-FinOpsPricingUnit ` - [[-UnitOfMeasure] ] ` - [-DistinctUnits ] ` - [-BlockSize ] + [[‑UnitOfMeasure] ] ` + [‑DistinctUnits ] ` + [‑BlockSize ] ```
## Parameters -| Name | Description | -| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| UnitOfMeasure | Optional. Unit of measure (also known as pricing unit) value from a Cost Management cost/usage details or price sheet dataset. Accepts wildcards. Default = \* (all). | -| DistinctUnits | Optional. The distinct unit for the pricing unit without block pricing. Accepts wildcards. Default = \* (all). | -| BlockSize | Optional. The number of units for block pricing (for example, 100 for "100 Hours"). Default = null (all). | +| Name | Description | +| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `‑UnitOfMeasure` | Optional. Unit of measure (also known as pricing unit) value from a Cost Management cost/usage details or price sheet dataset. Accepts wildcards. Default = \* (all). | +| `‑DistinctUnits` | Optional. The distinct unit for the pricing unit without block pricing. Accepts wildcards. Default = \* (all). | +| `‑BlockSize` | Optional. The number of units for block pricing (for example, 100 for "100 Hours"). Default = null (all). |
diff --git a/docs-mslearn/toolkit/powershell/data/get-finopsregion.md b/docs-mslearn/toolkit/powershell/data/get-finopsregion.md index ec651b1aa..2865c077f 100644 --- a/docs-mslearn/toolkit/powershell/data/get-finopsregion.md +++ b/docs-mslearn/toolkit/powershell/data/get-finopsregion.md @@ -3,12 +3,12 @@ title: Get-FinOpsRegion command description: Get an Azure region ID and name based on the specified resource location using the Get-FinOpsRegion command in the FinOpsToolkit module. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 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 what Get-FinOpsRegion command in the FinOpsToolkit module. +#customer intent: As a FinOps user, I want to understand how to use the Get-FinOpsRegion command in the FinOpsToolkit module. --- # Get-FinOpsRegion command @@ -21,20 +21,22 @@ The **Get-FinOpsRegion** command returns an Azure region ID and name based on th ```powershell Get-FinOpsRegion ` - [[-ResourceLocation] ] ` - [-RegionId ] ` - [-RegionName ] + [[‑ResourceLocation] ] ` + [‑RegionId ] ` + [‑RegionName ] ` + [‑IncludeResourceLocation] ```
## Parameters -| Name | Description | Notes | -| ---------------- | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -| ResourceLocation | Optional. Resource location value from a Cost Management cost/usage details dataset. Accepts wildcards. Default = \* (all). | -| RegionId | Optional. Azure region ID (lowercase English name without spaces). Accepts wildcards. Default = \* (all). | -| RegionName | Optional. Azure region name (title case English name with spaces). Accepts wildcards. Default = \* (all).IncludeResourceLocation | Optional. Indicates whether to include the ResourceLocation property in the output. Default = false. | +| Name | Description | +| -------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `‑ResourceLocation` | Optional. Resource location value from a Cost Management cost/usage details dataset. Accepts wildcards. Default = \* (all). | +| `‑RegionId` | Optional. Azure region ID (lowercase English name without spaces). Accepts wildcards. Default = \* (all). | +| `‑RegionName` | Optional. Azure region name (title case English name with spaces). Accepts wildcards. Default = \* (all). | +| `‑IncludeResourceLocation` | Optional. Indicates whether to include the ResourceLocation property in the output. Default = false. |
diff --git a/docs-mslearn/toolkit/powershell/data/get-finopsresourcetype.md b/docs-mslearn/toolkit/powershell/data/get-finopsresourcetype.md index 6713f80d5..570739d99 100644 --- a/docs-mslearn/toolkit/powershell/data/get-finopsresourcetype.md +++ b/docs-mslearn/toolkit/powershell/data/get-finopsresourcetype.md @@ -3,12 +3,12 @@ title: Get-FinOpsResourceType command description: Get an Azure resource type with readable display names, preview status, description, icon, and support links using the Get-FinOpsResourceType command. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 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 what Get-FinOpsResourceType command in the FinOpsToolkit module. +#customer intent: As a FinOps user, I want to understand how to use the Get-FinOpsResourceType command in the FinOpsToolkit module. --- # Get-FinOpsResourceType command @@ -21,8 +21,8 @@ The **Get-FinOpsResourceType** command returns an Azure resource type with reada ```powershell Get-FinOpsResourceType ` - [[-ResourceType] ] ` - [-IsPreview ] + [[‑ResourceType] ] ` + [‑IsPreview ] ```
diff --git a/docs-mslearn/toolkit/powershell/data/get-finopsservice.md b/docs-mslearn/toolkit/powershell/data/get-finopsservice.md index acf93cfc0..ef51e4b52 100644 --- a/docs-mslearn/toolkit/powershell/data/get-finopsservice.md +++ b/docs-mslearn/toolkit/powershell/data/get-finopsservice.md @@ -3,50 +3,54 @@ title: Get-FinOpsService command description: Get the name and category for a service, publisher, and cloud provider using the Get-FinOpsService command in the FinOpsToolkit module. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 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 what Get-FinOpsService command in the FinOpsToolkit module. +#customer intent: As a FinOps user, I want to understand how to use the Get-FinOpsService command in the FinOpsToolkit module. --- # Get-FinOpsService command The **Get-FinOpsService** command returns service details based on the specified filters. This command is designed to help map Cost Management cost data to the FinOps Open Cost and Usage Specification (FOCUS) schema but can also be useful for general data cleansing. +Please note that both ConsumedService and ResourceType are required to find a unique service in many cases. +
## Syntax ```powershell Get-FinOpsService ` - [[-ConsumedService] ] ` - [[-ResourceId] ] ` - [[-ResourceType] ] ` - [-ServiceName ] ` - [-ServiceCategory ] ` - [-ServiceModel ] ` - [-Environment ] ` - [-PublisherName ] ` - [-PublisherCategory ] + [[‑ConsumedService] ] ` + [[‑ResourceId] ] ` + [[‑ResourceType] ] ` + [‑ServiceName ] ` + [‑ServiceCategory ] ` + [‑ServiceSubcategory ] ` + [‑ServiceModel ] ` + [‑Environment ] ` + [‑PublisherName ] ` + [‑PublisherCategory ] ```
## Parameters -| Name | Description | -| -------------------- | ------------------------------------------------------------------------------------------------------------------------- | -| `‑ConsumedService` | Optional. ConsumedService value from a Cost Management cost/usage details dataset. Accepts wildcards. Default = \* (all). | -| `‑ResourceId` | Optional. The Azure resource ID for resource you want to look up. Accepts wildcards. Default = \* (all). | -| `‑ResourceType` | Optional. The Azure resource type for the resource you want to find the service for. Default = null (all). | -| `‑ServiceName` | Optional. The service name to find. Default = null (all). | -| `‑ServiceCategory` | Optional. The service category to find services for. Default = null (all). | -| `‑Servicemodel` | Optional. The service model the service aligns to. Expected values: IaaS, PaaS, SaaS. Default = null (all). | -| `‑Environment` | Optional. The environment the service runs in. Expected values: Cloud, Hybrid. Default = null (all). | -| `‑PublisherName` | Optional. The publisher name to find services for. Default = null (all). | -| `‑PublisherCategory` | Optional. The publisher category to find services for. Default = null (all). | +| Name | Description | +| --------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| `‑ConsumedService` | Optional. ConsumedService value from a Cost Management cost/usage details dataset. Accepts wildcards. Default = \* (all). | +| `‑ResourceId` | Optional. The Azure resource ID for resource you want to look up. Accepts wildcards. Default = \* (all). | +| `‑ResourceType` | Optional. The Azure resource type for the resource you want to find the service for. Default = null (all). | +| `‑ServiceName` | Optional. The service name to find. Default = null (all). | +| `‑ServiceCategory` | Optional. The service category to find services for. Default = null (all). | +| `‑ServiceSubcategory` | Optional. The service subcategory to find services for. Default = null (all). | +| `‑ServiceModel` | Optional. The service model the service aligns to. Expected values: IaaS, PaaS, SaaS. Default = null (all). | +| `‑Environment` | Optional. The environment the service runs in. Expected values: Cloud, Hybrid, On-Premises. Default = null (all). | +| `‑PublisherName` | Optional. The publisher name to find services for. Default = null (all). | +| `‑PublisherCategory` | Optional. The publisher category to find services for. Default = null (all). |
@@ -54,15 +58,13 @@ Get-FinOpsService ` The following example demonstrates how to use the Get-FinOpsService command to retrieve service details. -### Get a specific region +### Get services for a resource provider ```powershell -Get-FinOpsService ` - -ConsumedService "Microsoft.C*" ` - -ResourceType "Microsoft.Compute/virtualMachines" +Get-FinOpsService -ConsumedService "Microsoft.C*" -ResourceType "Microsoft.Compute/virtualMachines" ``` -Returns all services with a resource provider that starts with `Microsoft.C`. +Returns all services with a resource provider that starts with "Microsoft.C".
diff --git a/docs-mslearn/toolkit/powershell/hubs/add-finopshubscope.md b/docs-mslearn/toolkit/powershell/hubs/add-finopshubscope.md new file mode 100644 index 000000000..78e04beff --- /dev/null +++ b/docs-mslearn/toolkit/powershell/hubs/add-finopshubscope.md @@ -0,0 +1,77 @@ +--- +title: Add-FinOpsHubScope command +description: Add a scope to be monitored by a FinOps hub instance using the Add-FinOpsHubScope command in the FinOpsToolkit module. +author: flanakin +ms.author: micflan +ms.date: 08/27/2026 +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 Add-FinOpsHubScope command in the FinOpsToolkit module. +--- + +# Add-FinOpsHubScope command + +The **Add-FinOpsHubScope** command adds a scope to the settings.json configuration file used by a FinOps hub instance so the scope can be monitored going forward. This command doesn't create the Cost Management export for the scope; use New-FinOpsCostExport to create the export. + +
+ +## Syntax + +```powershell +Add-FinOpsHubScope ` + [‑HubName] ` + [‑Scope] ` + [] +``` + +
+ +## Parameters + +| Name | Description | +| ---------- | -------------------------------------------------------------------------- | +| `‑HubName` | Required. Name of the FinOps hub instance. | +| `‑Scope` | Required. Resource ID of the scope to add to the FinOps hub configuration. | + +
+ +## Examples + +### Add a billing account scope + +```powershell +Add-FinOpsHubScope -HubName ftk-FinOps-Hub -Scope "/providers/Microsoft.Billing/billingAccounts/1234567" +``` + +Adds the specified billing account scope to the ftk-FinOps-Hub hub configuration. + +
+ +## 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/Hubs.AddHubScope) + + +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 solutions: + +- [FinOps toolkit Power BI reports](../../power-bi/reports.md) +- [FinOps hubs](../../hubs/finops-hubs-overview.md) + +
diff --git a/docs-mslearn/toolkit/powershell/hubs/deploy-finopshub.md b/docs-mslearn/toolkit/powershell/hubs/deploy-finopshub.md index f6378fbb4..fdab41947 100644 --- a/docs-mslearn/toolkit/powershell/hubs/deploy-finopshub.md +++ b/docs-mslearn/toolkit/powershell/hubs/deploy-finopshub.md @@ -3,12 +3,12 @@ title: Deploy-FinOpsHub command description: Deploy a new or update an existing FinOps hub instance using the Deploy-FinOpsHub command in the FinOpsToolkit module. author: flanakin ms.author: micflan -ms.date: 06/03/2026 +ms.date: 08/27/2026 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 what Deploy-FinOpsHub command in the FinOpsToolkit module. +#customer intent: As a FinOps user, I want to understand how to use the Deploy-FinOpsHub command in the FinOpsToolkit module. --- # Deploy-FinOpsHub command @@ -23,15 +23,33 @@ Deploy-FinOpsHub calls [Initialize-FinOpsHubDeployment](Initialize-FinOpsHubDepl ```powershell Deploy-FinOpsHub ` - -Name ` - -ResourceGroup ` - -Location ` - [-Version ] ` - [-Preview] ` - [-StorageSku ] ` - [-RemoteHubStorageUri ] ` - [-RemoteHubStorageKey ] ` - [-Tags ] ` + [‑Name] ` + [‑ResourceGroupName] ` + [‑Location] ` + [[‑Version] ] ` + [‑Preview] ` + [[‑StorageSku] ] ` + [‑EnableInfrastructureEncryption] ` + [‑EnablePurgeProtection] ` + [[‑RemoteHubStorageUri] ] ` + [[‑RemoteHubStorageKey] ] ` + [‑EnableManagedExports] ` + [[‑DataExplorerName] ] ` + [[‑DataExplorerSku] ] ` + [[‑DataExplorerCapacity] ] ` + [[‑FabricQueryUri] ] ` + [[‑FabricCapacityUnits] ] ` + [[‑DataExplorerRawRetentionInDays] ] ` + [[‑DataExplorerFinalRetentionInMonths] ] ` + [[‑NetworkMode] ] ` + [‑DisablePublicAccess] ` + [[‑VirtualNetworkAddressPrefix] ] ` + [[‑Tags] ] ` + [[‑TagsByResource] ] ` + [[‑ScopesToMonitor] ] ` + [[‑ExportRetentionInDays] ] ` + [[‑IngestionRetentionInMonths] ] ` + [‑WhatIf] ` [] ``` @@ -39,17 +57,35 @@ Deploy-FinOpsHub ` ## Parameters -| Name | Description | -| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `‑Name` | Required. Name of the FinOps hub instance. | -| `‑ResourceGroup` | Required. Name of the resource group to deploy to. It gets created if it doesn't exist. | -| `‑Location` | Required. Azure location to execute the deployment from. | -| `‑Version` | Optional. Version of the FinOps hub template to use. Default = "latest". | -| `‑Preview` | Optional. Indicates that preview releases should also be included. Default = false. | -| `‑StorageSku` | Optional. Storage account SKU. Premium_LRS = Lowest cost, Premium_ZRS = High availability. Note Standard SKUs aren't available for Data Lake gen2 storage. Default = "Premium_LRS". | -| `‑RemoteHubStorageUri` | Optional. Data Lake storage endpoint from the remote hub storage account. Used for cross-tenant cost data collection scenarios. Example: `https://primaryhub.dfs.core.windows.net/` | -| `‑RemoteHubStorageKey` | Optional. Storage account access key for the remote hub. Used for cross-tenant cost data collection scenarios. Must be kept secure as it provides full storage access. | -| `‑Tags` | Optional. Tags for all resources. | +| Name | Description | +| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `‑Name` | Required. Name of the hub. Used to ensure unique resource names. | +| `‑ResourceGroupName` | Required. Name of the resource group to deploy to. Will be created if it doesn't exist. | +| `‑Location` | Required. Azure location where all resources should be created. See https://aka.ms/azureregions. | +| `‑Version` | Optional. Version of the FinOps hub template to use. Default = "latest". | +| `‑Preview` | Optional. Indicates that preview releases should also be included. Default = false. | +| `‑StorageSku` | Optional. Storage SKU to use. LRS = Lowest cost, ZRS = High availability. Note Standard SKUs are not available for Data Lake gen2 storage. Allowed: Premium_LRS, Premium_ZRS. Default: Premium_LRS. | +| `‑EnableInfrastructureEncryption` | Optional. Enable infrastructure encryption on the storage account. Default = false. | +| `‑EnablePurgeProtection` | Optional. Enable purge protection for the Key Vault. Default = false. | +| `‑RemoteHubStorageUri` | Optional. Storage account to push data to for ingestion into a remote hub. | +| `‑RemoteHubStorageKey` | Optional. Storage account key to use when pushing data to a remote hub. | +| `‑EnableManagedExports` | Optional. Enable managed exports where your FinOps hub instance creates and runs Cost Management exports on your behalf. Not supported for Microsoft Customer Agreement (MCA) billing profiles. Default = false. | +| `‑DataExplorerName` | Optional. Name of the Azure Data Explorer cluster to use for advanced analytics. If empty, Azure Data Explorer will not be deployed. Required to use with Power BI if you have more than $2-5M/mo in costs being monitored. Default: "" (do not use). | +| `‑DataExplorerSku` | Optional. Name of the Azure Data Explorer SKU. Default: "Dev(No SLA)_Standard_E2a_v4". | +| `‑DataExplorerCapacity` | Optional. Number of nodes to use in the cluster. Allowed values: 1 for the Basic SKU tier and 2-1000 for Standard. Default: 1 for dev/test SKUs, 2 for standard SKUs. | +| `‑FabricQueryUri` | Optional. Microsoft Fabric eventhouse query URI. Default: "" (do not use). | +| `‑FabricCapacityUnits` | Optional. Number of capacity units for the Microsoft Fabric capacity. This is the number in your Fabric SKU (e.g., Trial = 1, F2 = 2, F64 = 64). Allowed values: 1-2048. Default: 2. | +| `‑DataExplorerRawRetentionInDays` | Optional. Number of days of data to retain in the Data Explorer *_raw tables. Default: 0. | +| `‑DataExplorerFinalRetentionInMonths` | Optional. Number of months of data to retain in the Data Explorer *_final_v* tables. Default: 13. | +| `‑NetworkMode` | Optional. Network mode for the hub: 'public' (default), 'vnet' (private endpoints, default outbound), or 'private' (private endpoints + NAT Gateway for controlled outbound access - required when the 'Subnets should be private' policy is enforced). | +| `‑DisablePublicAccess` | Optional. Deprecated. Use -NetworkMode 'vnet' or -NetworkMode 'private' instead. When set without -NetworkMode, behaves as -NetworkMode 'vnet'. Ignored when -NetworkMode is supplied. | +| `‑VirtualNetworkAddressPrefix` | Optional. Address space for the workload. A /26 is required for the workload. Default: "10.20.30.0/26". | +| `‑Tags` | Optional. Tags to apply to all resources. We will also add the cm-resource-parent tag for improved cost roll-ups in Cost Management. | +| `‑TagsByResource` | Optional. Tags to apply to resources based on their resource type. Resource type specific tags will be merged with tags for all resources. | +| `‑ScopesToMonitor` | Optional. Array of scope IDs to monitor and ingest cost for. Used with managed exports to automatically create Cost Management exports. Scope ID formats:
- EA billing account: /providers/Microsoft.Billing/billingAccounts/{enrollment-number}
- MCA billing profile: /providers/Microsoft.Billing/billingAccounts/{billing-account-id}/billingProfiles/{billing-profile-id}
- Subscription: /subscriptions/{subscription-id}
- Resource group: /subscriptions/{subscription-id}/resourceGroups/{resource-group-name}
Example: @('/subscriptions/00000000-0000-0000-0000-000000000000', '/subscriptions/11111111-1111-1111-1111-111111111111') | +| `‑ExportRetentionInDays` | Optional. Number of days of data to retain in the msexports container. Default: 0. | +| `‑IngestionRetentionInMonths` | Optional. Number of months of data to retain in the ingestion container. Default: 13. | +| `‑WhatIf` | Optional. Shows what would happen if the command runs without actually running it. | > [!NOTE] > Not all Data Explorer SKUs are available in every region. If deployment fails with a SKU error, see [common errors](../../help/errors.md#the-sku-skuname-is-not-supported-in-region). @@ -63,35 +99,23 @@ The following examples demonstrate how to use the Deploy-FinOpsHub command to de ### Deploy latest version ```powershell -Deploy-FinOpsHub ` - -Name MyHub ` - -ResourceGroup MyNewResourceGroup ` - -Location westus +Deploy-FinOpsHub -Name MyHub -ResourceGroupName MyNewResourceGroup -Location westus -DataExplorerName MyFinOpsHubCluster ``` -Deploys a FinOps hub instance named MyHub to the MyNewResourceGroup resource group. If the resource group doesn't exist, it gets created. If the hub already exists, it gets updated to the latest version. +Deploys a FinOps hub instance named MyHub to the MyNewResourceGroup resource group with a new MyFinOpsHubCluster Data Explorer cluster. If the resource group does not exist, it will be created. If the hub already exists, it will be updated to the latest version. ### Deploy specific version ```powershell -Deploy-FinOpsHub ` - -Name MyHub ` - -ResourceGroup MyExistingResourceGroup ` - -Location westus ` - -Version 0.1.1 +Deploy-FinOpsHub -Name MyHub -ResourceGroupName MyExistingResourceGroup -Location westus -Version 0.1.1 ``` -Deploys a FinOps hub instance named MyHub to the MyExistingResourceGroup resource group using version 0.1.1 of the template. This version is required for Microsoft Online Services Agreement (MOSA) subscriptions since FOCUS exports aren't available from Cost Management. If the resource group doesn't exist, it gets created. If the hub already exists, it gets updated to version 0.1.1. +Deploys a FinOps hub instance named MyHub to the MyExistingResourceGroup resource group using version 0.1.1 of the template. This version is required for Microsoft Online Services Agreement (MOSA) subscriptions since FOCUS exports aren't available from Cost Management. If the resource group does not exist, it will be created. If the hub already exists, it will be updated to version 0.1.1. ### Deploy with remote hub configuration ```powershell -Deploy-FinOpsHub ` - -Name MyRemoteHub ` - -ResourceGroup MyRemoteHubResourceGroup ` - -Location westus ` - -RemoteHubStorageUri "https://centralfinooshub123.dfs.core.windows.net/" ` - -RemoteHubStorageKey "abc123...xyz789==" +Deploy-FinOpsHub -Name MyRemoteHub -ResourceGroupName MyRemoteHubResourceGroup -Location westus -RemoteHubStorageUri "https://centralfinopshub123.dfs.core.windows.net/" -RemoteHubStorageKey "abc123...xyz789==" ``` Deploys a FinOps hub instance named MyRemoteHub configured to send data to a remote (central) hub. The remote hub storage URI and key enable cross-tenant data collection scenarios where a central tenant aggregates cost data from multiple tenants. The RemoteHubStorageUri should be copied from the central hub's storage account Settings > Endpoints > Data Lake storage, and the RemoteHubStorageKey should be copied from Security + networking > Access keys. Remote hubs require template version 0.4 or later. diff --git a/docs-mslearn/toolkit/powershell/hubs/finops-hubs-commands.md b/docs-mslearn/toolkit/powershell/hubs/finops-hubs-commands.md index 70e6a8152..9a92068bd 100644 --- a/docs-mslearn/toolkit/powershell/hubs/finops-hubs-commands.md +++ b/docs-mslearn/toolkit/powershell/hubs/finops-hubs-commands.md @@ -3,7 +3,7 @@ title: FinOps hubs automation description: Learn about PowerShell commands available in the FinOpsToolkit module that deploy and manage FinOps hubs. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 ms.topic: reference ms.service: finops ms.subservice: finops-toolkit @@ -19,11 +19,14 @@ The FinOps hubs PowerShell commands help you deploy and manage FinOps hubs insta ## Commands +- [Add-FinOpsHubScope](add-finopshubscope.md) – Adds a scope to be monitored by a FinOps hub instance. - [Deploy-FinOpsHub](Deploy-FinOpsHub.md) – Deploy your first hub or update to the latest version. - [Get-FinOpsHub](Get-FinOpsHub.md) – Get details about your FinOps hub instance. - [Initialize-FinOpsHubDeployment](Initialize-FinOpsHubDeployment.md) – Initializes the deployment for FinOps hubs. +- [Initialize-FinOpsHubLocal](initialize-finopshublocal.md) – Set up a local FinOps hub in a running Kusto emulator. - [Register-FinOpsHubProviders](Register-FinOpsHubProviders.md) – Registers resource providers for FinOps hubs. - [Remove-FinOpsHub](Remove-FinOpsHub.md) – Deletes a FinOps hub instance. +- [Remove-FinOpsHubScope](remove-finopshubscope.md) – Stops monitoring a scope within a FinOps hub instance.
diff --git a/docs-mslearn/toolkit/powershell/hubs/get-finopshub.md b/docs-mslearn/toolkit/powershell/hubs/get-finopshub.md index fcbb7cd0f..5c0c0d94c 100644 --- a/docs-mslearn/toolkit/powershell/hubs/get-finopshub.md +++ b/docs-mslearn/toolkit/powershell/hubs/get-finopshub.md @@ -3,17 +3,17 @@ title: Get-FinOpsHub command description: Get details about a FinOps hub instance using the Get-FinOpsHub command in the FinOpsToolkit module. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 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 what Get-FinOpsHub command in the FinOpsToolkit module. +#customer intent: As a FinOps user, I want to understand how to use the Get-FinOpsHub command in the FinOpsToolkit module. --- # Get-FinOpsHub command -The Get-FinOpsHubs command calls GitHub to retrieve all toolkit releases, then filters the list based on the specified options. +The **Get-FinOpsHub** command gets details about a FinOps hub instance using the cm-resource-parent tag to identify hub resources.
@@ -21,8 +21,8 @@ The Get-FinOpsHubs command calls GitHub to retrieve all toolkit releases, then f ```powershell Get-FinOpsHub ` - [[-Name] ] ` - [-ResourceGroupName ] ` + [[‑Name] ] ` + [‑ResourceGroupName ] ` [] ``` @@ -32,8 +32,8 @@ Get-FinOpsHub ` | Name | Description | | -------------------- | ---------------------------------------------------------------------------------------- | -| '‑Name' | Optional. Name of the FinOps hub instance. Supports wildcards. | -| '‑ResourceGroupName' | Optional. Name of the resource group the FinOps hub was deployed to. Supports wildcards. | +| `‑Name` | Optional. Name of the FinOps hub instance. Supports wildcards. | +| `‑ResourceGroupName` | Optional. Name of the resource group the FinOps hub was deployed to. Supports wildcards. |
diff --git a/docs-mslearn/toolkit/powershell/hubs/initialize-finopshubdeployment.md b/docs-mslearn/toolkit/powershell/hubs/initialize-finopshubdeployment.md index b74e19c1c..2ad441bbb 100644 --- a/docs-mslearn/toolkit/powershell/hubs/initialize-finopshubdeployment.md +++ b/docs-mslearn/toolkit/powershell/hubs/initialize-finopshubdeployment.md @@ -3,12 +3,12 @@ title: Initialize-FinOpsHubDeployment command description: Initialize a FinOps hub deployment using the Initialize-FinOpsHubDeployment command in the FinOpsToolkit module. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 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 what Initialize-FinOpsHubDeployment command in the FinOpsToolkit module. +#customer intent: As a FinOps user, I want to understand how to use the Initialize-FinOpsHubDeployment command in the FinOpsToolkit module. --- # Initialize-FinOpsHubDeployment command @@ -21,7 +21,8 @@ The **Initialize-FinOpsHubDeployment** command performs any initialization tasks ```powershell Initialize-FinOpsHubDeployment ` - [-WhatIf ] + [‑WhatIf] ` + [] ```
@@ -30,7 +31,7 @@ Initialize-FinOpsHubDeployment ` | Name | Description | | --------- | ---------------------------------------------------------------------------------- | -| '‑WhatIf' | Optional. Shows what would happen if the command runs without actually running it. | +| `‑WhatIf` | Optional. Shows what would happen if the command runs without actually running it. |
@@ -41,8 +42,7 @@ The following example demonstrates how to use the Initialize-FinOpsHubDeployment ### Test FinOps hub deployment initialization ```powershell -Initialize-FinOpsHubDeployment ` - -WhatIf +Initialize-FinOpsHubDeployment -WhatIf ``` Shows what would happen if the command runs without actually running it. diff --git a/docs-mslearn/toolkit/powershell/hubs/register-finopshubproviders.md b/docs-mslearn/toolkit/powershell/hubs/register-finopshubproviders.md index 295cce5ac..8ecee3586 100644 --- a/docs-mslearn/toolkit/powershell/hubs/register-finopshubproviders.md +++ b/docs-mslearn/toolkit/powershell/hubs/register-finopshubproviders.md @@ -3,12 +3,12 @@ title: Register-FinOpsHubProviders command description: Register Azure resource providers required for FinOps hub using the Register-FinOpsHubProviders command in the FinOpsToolkit module. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 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 what Register-FinOpsHubProviders command in the FinOpsToolkit module. +#customer intent: As a FinOps user, I want to understand how to use the Register-FinOpsHubProviders command in the FinOpsToolkit module. --- # Register-FinOpsHubProviders command @@ -23,7 +23,8 @@ To register a resource provider, you must have Contributor access (or the /regis ```powershell Register-FinOpsHubProviders ` - [-WhatIf ] ` + [‑WhatIf] ` + [] ```
@@ -43,8 +44,7 @@ The following example demonstrates how to use the Register-FinOpsHubProviders co ### Test register FinOps hub providers ```powershell -Register-FinOpsHubProviders ` - -WhatIf +Register-FinOpsHubProviders -WhatIf ``` Shows what would happen if the command runs without actually running it. diff --git a/docs-mslearn/toolkit/powershell/hubs/remove-finopshub.md b/docs-mslearn/toolkit/powershell/hubs/remove-finopshub.md index 2eae99459..79a23d81e 100644 --- a/docs-mslearn/toolkit/powershell/hubs/remove-finopshub.md +++ b/docs-mslearn/toolkit/powershell/hubs/remove-finopshub.md @@ -3,17 +3,17 @@ title: Remove-FinOpsHub command description: Remove a FinOps hub instance using the Remove-FinOpsHub command in the FinOpsToolkit module, with an option to keep the storage account hosting cost data. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 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 what New-FinOpsHub command in the FinOpsToolkit module. +#customer intent: As a FinOps user, I want to understand how to use the Remove-FinOpsHub command in the FinOpsToolkit module. --- # Remove-FinOpsHub command -The **Remove-FinOpsHub** command removes a FinOps hub instance and optionally keep the storage account hosting cost data. +The **Remove-FinOpsHub** command deletes a FinOps hub instance and optionally deletes the storage account hosting cost data. The command returns a boolean value indicating whether all resources were successfully deleted. @@ -23,27 +23,35 @@ The command returns a boolean value indicating whether all resources were succes ```powershell Remove-FinOpsHub ` - [-Name] ` - [-ResourceGroup ] ` - [-KeepStorageAccount] + ‑Name ` + [‑ResourceGroupName ] ` + [‑KeepStorageAccount] ` + [‑Force] ` + [‑WhatIf] ` + [] ``` ```powershell Remove-FinOpsHub ` - [-InputObject] ` - [-KeepStorageAccount] + ‑InputObject ` + [‑KeepStorageAccount] ` + [‑Force] ` + [‑WhatIf] ` + [] ```
## Parameters -| Name | Description | -| --------------------- | ----------------------------------------------------------------------------------------------- | -| `‑Name` | Required. Name of the FinOps hub instance. | -| `‑InputObject` | Required when specifying InputObject. Expected object is the output of Get-FinOpsHub. | -| `‑ResourceGroup` | Optional when specifying Name. Resource Group Name for the FinOps hub. | -| `‑KeepStorageAccount` | Optional. Indicates that the storage account associated with the FinOps hub should be retained. | +| Name | Description | +| --------------------- | ---------------------------------------------------------------------------------------------------------------- | +| `‑Name` | Required if not specifying InputObject. Name of the FinOps hub instance. | +| `‑ResourceGroupName` | Optional when specifying Name. Resource group name for the FinOps hub. | +| `‑InputObject` | Required if not specifying Name. Expected object is the output of Get-FinOpsHub. | +| `‑KeepStorageAccount` | Optional. Indicates that the storage account associated with the FinOps hub should be retained. Default = false. | +| `‑Force` | Optional. Deletes specified resources without asking for a confirmation. Default = false. | +| `‑WhatIf` | Optional. Shows what would happen if the command runs without actually running it. |
@@ -54,10 +62,7 @@ The following example demonstrates how to use the Remove-FinOpsHub command to de ### Remove a FinOps hub instance ```powershell -Remove-FinOpsHub ` - -Name MyHub ` - -ResourceGroup MyRG ` - -KeepStorageAccount +Remove-FinOpsHub -Name MyHub -ResourceGroupName MyRG -KeepStorageAccount ``` Deletes a FinOps hub named MyHub and deletes all associated resource except the storage account. diff --git a/docs-mslearn/toolkit/powershell/hubs/remove-finopshubscope.md b/docs-mslearn/toolkit/powershell/hubs/remove-finopshubscope.md index 10821635d..bd9b6236a 100644 --- a/docs-mslearn/toolkit/powershell/hubs/remove-finopshubscope.md +++ b/docs-mslearn/toolkit/powershell/hubs/remove-finopshubscope.md @@ -3,12 +3,12 @@ title: Remove-FinOpsHubScope command description: Stops monitoring a scope within a FinOps hub instance and optionally remove the data using the Remove-FinOpsHubScope command in the FinOpsToolkit module. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 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 Remove-FinOpsHubScope PowerShell command. +#customer intent: As a FinOps user, I want to understand how to use the Remove-FinOpsHubScope command in the FinOpsToolkit module. --- # Remove-FinOpsHubScope command @@ -21,10 +21,12 @@ The **Remove-FinOpsHubScope** command removes a scope from being monitored by a ```powershell Remove-FinOpsHubScope ` - [-Id] ` - -HubName - [-HubResourceGroupName ] - [-RemoveData] + [‑Id] ` + [‑HubName] ` + [[‑HubResourceGroupName] ] ` + [‑RemoveData] ` + [‑WhatIf] ` + [] ```
@@ -37,6 +39,7 @@ Remove-FinOpsHubScope ` | `‑HubName` | Required. Name of the FinOps hub instance. | | `‑HubResourceGroupName` | Optional. Name of the resource group the FinOps hub was deployed to. | | `‑RemoveData` | Optional. Indicates whether to remove data for this scope from storage. Default = false | +| `‑WhatIf` | Optional. Shows what would happen if the command runs without actually running it. |
@@ -50,7 +53,7 @@ The following examples demonstrate how to use the Remove-FinOpsHubScope command Remove-FinOpsHubScope -Id "/providers/Microsoft.Billing/billingAccounts/123" -HubName "FooHub" ``` -Removes the exports configured to use the FooHub hub instance. Existing data is retained in the storage account. +Deletes the exports configured to use the FooHub hub instance. Existing data is retained in the storage account. ### Remove subscription and historical data @@ -58,7 +61,7 @@ Removes the exports configured to use the FooHub hub instance. Existing data is Remove-FinOpsHubScope -Id "/subscriptions/##-#-#-#-###" -HubName "FooHub" -RemoveData ``` -Removes the exports configured to use the FooHub hub instance and removes data for that scope. +Deletes the exports configured to use the FooHub hub instance and removes data for that scope.
diff --git a/docs-mslearn/toolkit/powershell/powershell-commands.md b/docs-mslearn/toolkit/powershell/powershell-commands.md index a1e8531eb..45e70d1ed 100644 --- a/docs-mslearn/toolkit/powershell/powershell-commands.md +++ b/docs-mslearn/toolkit/powershell/powershell-commands.md @@ -3,7 +3,7 @@ title: FinOps toolkit PowerShell module description: Automate and scale your FinOps efforts using the FinOps toolkit PowerShell module, which includes commands to manage FinOps solutions. author: flanakin ms.author: micflan -ms.date: 08/13/2026 +ms.date: 08/27/2026 ms.topic: reference ms.service: finops ms.subservice: finops-toolkit @@ -54,6 +54,7 @@ The FinOps toolkit PowerShell module includes commands to manage FinOps solution ### Cost Management commands +- [Add-FinOpsServicePrincipal](cost/add-finopsserviceprincipal.md) – Grants a service principal or managed identity access to an Enterprise Agreement billing account or department. - [Get-FinOpsCostExport](cost/Get-FinOpsCostExport.md) – Get details about Cost Management exports. - [New-FinOpsCostExport](cost/New-FinOpsCostExport.md) – Create a new Cost Management export. - [Remove-FinOpsCostExport](cost/Remove-FinOpsCostExport.md) – Delete a Cost Management export and optionally data associated with the export. @@ -61,12 +62,14 @@ The FinOps toolkit PowerShell module includes commands to manage FinOps solution ### FinOps hubs commands +- [Add-FinOpsHubScope](hubs/add-finopshubscope.md) – Adds a scope to be monitored by a FinOps hub instance. - [Deploy-FinOpsHub](hubs/Deploy-FinOpsHub.md) – Deploy your first hub or update to the latest version. - [Get-FinOpsHub](hubs/Get-FinOpsHub.md) – Get details about your FinOps hub instance. - [Initialize-FinOpsHubDeployment](hubs/Initialize-FinOpsHubDeployment.md) – Initializes the deployment for FinOps hubs. - [Initialize-FinOpsHubLocal](hubs/initialize-finopshublocal.md) – Set up a local FinOps hub in a running Kusto emulator. - [Register-FinOpsHubProviders](hubs/Register-FinOpsHubProviders.md) – Registers resource providers for FinOps hubs. - [Remove-FinOpsHub](hubs/Remove-FinOpsHub.md) – Deletes a FinOps hub instance. +- [Remove-FinOpsHubScope](hubs/remove-finopshubscope.md) – Stops monitoring a scope within a FinOps hub instance. ### Open data commands diff --git a/docs-mslearn/toolkit/powershell/toolkit/get-finopstoolkitversion.md b/docs-mslearn/toolkit/powershell/toolkit/get-finopstoolkitversion.md index 977ad157e..59dceed22 100644 --- a/docs-mslearn/toolkit/powershell/toolkit/get-finopstoolkitversion.md +++ b/docs-mslearn/toolkit/powershell/toolkit/get-finopstoolkitversion.md @@ -3,17 +3,17 @@ title: Get-FinOpsToolkitVersion command description: Get available versions from published FinOps toolkit releases using the Get-FinOpsToolkitVersion command. author: flanakin ms.author: micflan -ms.date: 04/01/2026 +ms.date: 08/27/2026 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-FinOpsToolkitVersion PowerShell command. +#customer intent: As a FinOps user, I want to understand how to use the Get-FinOpsToolkitVersion command in the FinOpsToolkit module. --- # Get-FinOpsToolkitVersion command -The Get-FinOpsToolkitVersions command calls GitHub to retrieve all toolkit releases, then filters the list based on the specified options. +The **Get-FinOpsToolkitVersion** command calls GitHub to retrieve all toolkit releases, then filters the list based on the specified options.
@@ -21,8 +21,8 @@ The Get-FinOpsToolkitVersions command calls GitHub to retrieve all toolkit relea ```powershell Get-FinOpsToolkitVersion ` - [-Latest] ` - [-Preview] ` + [‑Latest] ` + [‑Preview] ` [] ``` @@ -30,10 +30,10 @@ Get-FinOpsToolkitVersion ` ## Parameters -| Name | Description | -| ------- | ------------------------------------------------------------------------------------------ | -| Latest | Optional. Indicates that only the most recent release should be returned. Default = false. | -| Preview | Optional. Indicates that preview releases should also be included. Default = false. | +| Name | Description | +| ---------- | ------------------------------------------------------------------------------------------ | +| `‑Latest` | Optional. Indicates that only the most recent release should be returned. Default = false. | +| `‑Preview` | Optional. Indicates that preview releases should also be included. Default = false. |
diff --git a/src/powershell/Public/Add-FinOpsHubScope.ps1 b/src/powershell/Public/Add-FinOpsHubScope.ps1 index 15a0626ab..1f7713a61 100644 --- a/src/powershell/Public/Add-FinOpsHubScope.ps1 +++ b/src/powershell/Public/Add-FinOpsHubScope.ps1 @@ -1,29 +1,37 @@ <# .SYNOPSIS - Adds an export scope configuration to the specified Resource group. + Adds a scope to be monitored by a FinOps hub instance. + + .DESCRIPTION + The Add-FinOpsHubScope command adds a scope to the settings.json configuration file used by a FinOps hub instance so the scope can be monitored going forward. This command doesn't create the Cost Management export for the scope; use New-FinOpsCostExport to create the export. .PARAMETER HubName - The name of the resource group. + Required. Name of the FinOps hub instance. .PARAMETER Scope - The export scope to add to the FinOps Hub configuration. + Required. Resource ID of the scope to add to the FinOps hub configuration. .EXAMPLE Add-FinOpsHubScope -HubName ftk-FinOps-Hub -Scope "/providers/Microsoft.Billing/billingAccounts/1234567" - Adds an export scope configuration to the specified Resource group. + ### Add a billing account scope + Adds the specified billing account scope to the ftk-FinOps-Hub hub configuration. + + .LINK + https://aka.ms/ftk/Add-FinOpsHubScope #> Function Add-FinOpsHubScope { [CmdletBinding()] param ( - [Parameter()] - [string] + [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] + [string] $HubName, - [Parameter()] - [String] + + [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] + [string] $Scope ) diff --git a/src/powershell/Public/Add-FinOpsServicePrincipal.ps1 b/src/powershell/Public/Add-FinOpsServicePrincipal.ps1 index 663d37480..d4a85af33 100644 --- a/src/powershell/Public/Add-FinOpsServicePrincipal.ps1 +++ b/src/powershell/Public/Add-FinOpsServicePrincipal.ps1 @@ -2,27 +2,37 @@ .SYNOPSIS Grants the specified service principal or managed identity access to an Enterprise Agreement billing account or department. + .DESCRIPTION + The Add-FinOpsServicePrincipal command grants the specified service principal or managed identity access to an Enterprise Agreement billing account or department. + + For more information about granting roles to service principals, see [Assign Enterprise Agreement roles to service principals](/azure/cost-management-billing/manage/assign-roles-azure-service-principals). For more information about the permissions associated with each role, see [Usage and costs access by role](/azure/cost-management-billing/manage/understand-ea-roles#usage-and-costs-access-by-role). + .PARAMETER ObjectId - The object ID of the service principal or managed identity. + Required. The object ID of the service principal or managed identity. .PARAMETER TenantId - The Azure Active Directory tenant which contains the identity. + Required. The Azure Active Directory tenant which contains the identity. .PARAMETER BillingAccountId - The billing account ID (enrollment number) to grant permissions against. + Required. The billing account ID (enrollment number) to grant permissions against. .PARAMETER DepartmentId - The department ID to grant permissions against. + Optional. The department ID to grant permissions against. .EXAMPLE Add-FinOpsServicePrincipal -ObjectId 00000000-0000-0000-0000-000000000000 -TenantId 00000000-0000-0000-0000-000000000000 -BillingAccountId 12345 - Grants Enterprise Administrator (read only) permissions to the specified service principal or managed identity + ### Enterprise Administrator (read only) + Grants Enterprise Administrator (read only) permissions to the specified service principal or managed identity. .EXAMPLE Add-FinOpsServicePrincipal -ObjectId 00000000-0000-0000-0000-000000000000 -TenantId 00000000-0000-0000-0000-000000000000 -BillingAccountId 12345 -DepartmentId 67890 - Grants Department Administrator (read only) permissions to the specified service principal or managed identity + ### Department Administrator (read only) + Grants Department Administrator (read only) permissions to the specified service principal or managed identity. + + .LINK + https://aka.ms/ftk/Add-FinOpsServicePrincipal #> function Add-FinOpsServicePrincipal { diff --git a/src/powershell/Public/Deploy-FinOpsHub.ps1 b/src/powershell/Public/Deploy-FinOpsHub.ps1 index 6140e0af8..0a30c7b9d 100644 --- a/src/powershell/Public/Deploy-FinOpsHub.ps1 +++ b/src/powershell/Public/Deploy-FinOpsHub.ps1 @@ -6,9 +6,9 @@ Deploys a FinOps hub instance. .DESCRIPTION - The Deploy-FinOpsHub command either creates a new or updates an existing FinOps hub instance by deploying an Azure Resource Manager deployment template. The FinOps hub template is downloaded from GitHub. + The Deploy-FinOpsHub command either creates a new or updates an existing FinOps hub instance by deploying an Azure Resource Manager deployment template. The FinOps hub template is downloaded from GitHub. To learn more about the template, see the [FinOps hub template](../../hubs/template.md). - Deploy-FinOpsHub calls Initialize-FinOpsHubDeployment before deploying the template. + Deploy-FinOpsHub calls [Initialize-FinOpsHubDeployment](Initialize-FinOpsHubDeployment.md) before deploying the template. .PARAMETER Name Required. Name of the hub. Used to ensure unique resource names. @@ -96,13 +96,21 @@ .EXAMPLE Deploy-FinOpsHub -Name MyHub -ResourceGroupName MyNewResourceGroup -Location westus -DataExplorerName MyFinOpsHubCluster + ### Deploy latest version Deploys a FinOps hub instance named MyHub to the MyNewResourceGroup resource group with a new MyFinOpsHubCluster Data Explorer cluster. If the resource group does not exist, it will be created. If the hub already exists, it will be updated to the latest version. .EXAMPLE Deploy-FinOpsHub -Name MyHub -ResourceGroupName MyExistingResourceGroup -Location westus -Version 0.1.1 + ### Deploy specific version Deploys a FinOps hub instance named MyHub to the MyExistingResourceGroup resource group using version 0.1.1 of the template. This version is required for Microsoft Online Services Agreement (MOSA) subscriptions since FOCUS exports aren't available from Cost Management. If the resource group does not exist, it will be created. If the hub already exists, it will be updated to version 0.1.1. + .EXAMPLE + Deploy-FinOpsHub -Name MyRemoteHub -ResourceGroupName MyRemoteHubResourceGroup -Location westus -RemoteHubStorageUri "https://centralfinopshub123.dfs.core.windows.net/" -RemoteHubStorageKey "abc123...xyz789==" + + ### Deploy with remote hub configuration + Deploys a FinOps hub instance named MyRemoteHub configured to send data to a remote (central) hub. The remote hub storage URI and key enable cross-tenant data collection scenarios where a central tenant aggregates cost data from multiple tenants. The RemoteHubStorageUri should be copied from the central hub's storage account Settings > Endpoints > Data Lake storage, and the RemoteHubStorageKey should be copied from Security + networking > Access keys. Remote hubs require template version 0.4 or later. + .LINK https://aka.ms/ftk/Deploy-FinOpsHub #> diff --git a/src/powershell/Public/Get-FinOpsCostExport.ps1 b/src/powershell/Public/Get-FinOpsCostExport.ps1 index 9ced41c78..fe17532f0 100644 --- a/src/powershell/Public/Get-FinOpsCostExport.ps1 +++ b/src/powershell/Public/Get-FinOpsCostExport.ps1 @@ -3,7 +3,7 @@ <# .SYNOPSIS - Get list of Cost Management exports. + Get a list of Cost Management exports for a given scope. .DESCRIPTION The Get-FinOpsCostExport command gets a list of Cost Management exports for a given scope. @@ -12,6 +12,7 @@ - 2025-03-01 (default) – GA version for FocusCost and other datasets. - 2023-07-01-preview - 2023-08-01 + - 2023-03-01 .PARAMETER Name Optional. Name of the export. Supports wildcards. @@ -40,31 +41,37 @@ .EXAMPLE Get-FinOpsCostExport -Scope "/subscriptions/00000000-0000-0000-0000-000000000000" + ### Get all cost exports for a subscription Gets all exports for a subscription. Does not include exports in nested resource groups. .EXAMPLE Get-FinOpsCostExport -Name mtd* -Scope "providers/Microsoft.Billing/billingAccounts/00000000" + ### Get exports matching a wildcard name Gets export with name matching wildcard mtd* within the specified billing account scope. Does not include exports in nested resource groups. .EXAMPLE Get-FinOpsCostExport -Dataset "AmortizedCost" + ### Get all amortized cost exports Gets all exports within the current context subscription scope and filtered by dataset AmortizedCost. .EXAMPLE Get-FinOpsCostExport -Scope "/subscriptions/00000000-0000-0000-0000-000000000000" -StorageAccountId "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/MyResourceGroup/providers/Microsoft.Storage/storageAccounts/MyStorageAccount" + ### Get exports using a specific storage account Gets all exports within the subscription scope filtered by a specific storage account. .EXAMPLE Get-FinOpsCostExport -Scope "/subscriptions/00000000-0000-0000-0000-000000000000" -StorageContainer "MyContainer*" + ### Get exports using a specific container Gets all exports within the subscription scope for a specific container. Supports wildcard. .EXAMPLE Get-FinOpsCostExport -Scope "/subscriptions/00000000-0000-0000-0000-000000000000" -StorageContainer "mtd*" -ApiVersion "2025-03-01" + ### Get exports using a specific API version Gets all exports within the subscription scope for a container matching wildcard pattern and using a specific API version. .LINK @@ -237,6 +244,22 @@ function Get-FinOpsCostExport { if ($null -eq $run) { continue } $runs += [PSCustomObject]@{ + # .OUTPUTS FinOpsCostExportRunHistory + # | Property | Type | JSON path | + # | ---------------- | -------- | ----------------------------------------------------------- | + # | `ResourceId` | String | `properties.runHistory.value[].id` | + # | `RunId` | String | `properties.runHistory.value[].name` | + # | `ExecutionType` | String | `properties.runHistory.value[].properties.executionType` | + # | `Status` | String | `properties.runHistory.value[].properties.status` | + # | `SubmittedBy` | String | `properties.runHistory.value[].properties.submittedBy` | + # | `SubmittedTime` | DateTime | `properties.runHistory.value[].properties.submittedTime` | + # | `RunStartTime` | DateTime | `properties.runHistory.value[].properties.processingStartTime` | + # | `RunEndTime` | DateTime | `properties.runHistory.value[].properties.processingEndTime` | + # | `FileName` | String | `properties.runHistory.value[].properties.fileName` | + # | `QueryStartDate` | DateTime | `properties.runHistory.value[].properties.startDate` | + # | `QueryEndDate` | DateTime | `properties.runHistory.value[].properties.endDate` | + # | `ErrorCode` | String | `properties.runHistory.value[].properties.error.code` | + # | `ErrorMessage` | String | `properties.runHistory.value[].properties.error.message` | ResourceId = $run.id RunId = $run.name ExecutionType = $run.properties.executionType @@ -253,6 +276,34 @@ function Get-FinOpsCostExport } } $item = [PSCustomObject]@{ + # .OUTPUTS FinOpsCostExport + # | Property | Type | JSON path | + # | --------------------- | ---------------------------- | ---------------------------------------------------------------------------- | + # | `Name` | String | `name` | + # | `Id` | String | `id` | + # | `Type` | String | `type` | + # | `eTag` | String | `eTag` | + # | `Description` | String | `properties.exportDescription` | + # | `Dataset` | String | `properties.definition.type` | + # | `DatasetVersion` | String | `properties.definition.configuration.dataVersion` | + # | `DatasetFilters` | String | `properties.definition.configuration.filter` | + # | `DatasetTimeFrame` | String | `properties.definition.timeframe` | + # | `DatasetStartDate` | DateTime | `properties.definition.timePeriod.from` | + # | `DatasetEndDate` | DateTime | `properties.definition.timePeriod.to` | + # | `DatasetGranularity` | String | `properties.definition.dataset.granularity` | + # | `ScheduleStatus` | String | `properties.schedule.status` | + # | `ScheduleRecurrence` | String | `properties.schedule.recurrence` | + # | `ScheduleStartDate` | DateTime | `properties.schedule.recurrencePeriod.from` | + # | `ScheduleEndDate` | DateTime | `properties.schedule.recurrencePeriod.to` | + # | `NextRuntimeEstimate` | DateTime | `properties.nextRunTimeEstimate` | + # | `Format` | String | `properties.format` | + # | `StorageAccountId` | String | `properties.deliveryInfo.destination.resourceId` | + # | `StorageContainer` | String | `properties.deliveryInfo.destination.container` | + # | `StoragePath` | String | `properties.deliveryInfo.destination.rootfolderpath` | + # | `OverwriteData` | Boolean | `properties.deliveryInfo.dataOverwriteBehavior` == "OverwritePreviousReport" | + # | `PartitionData` | Boolean | `properties.deliveryInfo.partitionData` | + # | `CompressionMode` | String | `properties.deliveryInfo.compressionMode` | + # | `RunHistory` | FinOpsCostExportRunHistory[] | `properties.runHistory.value` | Name = $export.name Id = $export.id Type = $export.type diff --git a/src/powershell/Public/Get-FinOpsHub.ps1 b/src/powershell/Public/Get-FinOpsHub.ps1 index 8450f7899..691e6b97e 100644 --- a/src/powershell/Public/Get-FinOpsHub.ps1 +++ b/src/powershell/Public/Get-FinOpsHub.ps1 @@ -17,22 +17,26 @@ .EXAMPLE Get-FinOpsHub + ### Get all hubs Returns all FinOps hubs for the selected subscription. .EXAMPLE Get-FinOpsHub -Name foo* - Returns all FinOps hubs that start with 'foo'. + ### Get named hubs + Returns all FinOps hubs that start with `foo`. .EXAMPLE Get-FinOpsHub -ResourceGroupName foo - Returns all resources associated with a FinOps hub in the 'foo' resource group. + ### Get hubs in a resource group + Returns all hubs in the `foo` resource group. .EXAMPLE Get-FinOpsHub -Name foo -ResourceGroupName bar - Returns all FinOps hubs named 'foo' in the 'bar' resource group. + ### Get named hubs in a resource group + Returns all FinOps hubs named `foo` in the `bar` resource group. .LINK https://aka.ms/ftk/Get-FinOpsHub diff --git a/src/powershell/Public/Get-FinOpsPricingUnit.ps1 b/src/powershell/Public/Get-FinOpsPricingUnit.ps1 index 2239fd2bb..62106feb7 100644 --- a/src/powershell/Public/Get-FinOpsPricingUnit.ps1 +++ b/src/powershell/Public/Get-FinOpsPricingUnit.ps1 @@ -6,7 +6,7 @@ Gets a pricing unit with its corresponding distinct unit and block size. .PARAMETER UnitOfMeasure - Optional. Unit of measure (aka pricing unit) value from a Cost Management cost/usage details or price sheet dataset. Accepts wildcards. Default = * (all). + Optional. Unit of measure (also known as pricing unit) value from a Cost Management cost/usage details or price sheet dataset. Accepts wildcards. Default = * (all). .PARAMETER DistinctUnits Optional. The distinct unit for the pricing unit without block pricing. Accepts wildcards. Default = * (all). @@ -15,16 +15,18 @@ Optional. The number of units for block pricing (for example, 100 for "100 Hours"). Default = null (all). .DESCRIPTION - The Get-FinOpsPricingUnit command returns a pricing unit (aka unit of measure) with the singular, distinct unit based on applicable block pricing rules, and the pricing block size. + The Get-FinOpsPricingUnit command returns a pricing unit (also known as unit of measure) with the singular, distinct unit based on applicable block pricing rules, and the pricing block size. .EXAMPLE Get-FinOpsPricingUnit -UnitOfMeasure "*hours*" + ### Get based on unit of measure Returns all pricing units with "hours" in the name. .EXAMPLE Get-FinOpsPricingUnit -DistinctUnits "GB" + ### Get based on distinct units Returns all pricing units measured in gigabytes. .LINK diff --git a/src/powershell/Public/Get-FinOpsRegion.ps1 b/src/powershell/Public/Get-FinOpsRegion.ps1 index 6adafaf82..0f30e806d 100644 --- a/src/powershell/Public/Get-FinOpsRegion.ps1 +++ b/src/powershell/Public/Get-FinOpsRegion.ps1 @@ -23,11 +23,13 @@ .EXAMPLE Get-FinOpsRegion -ResourceLocation "US East" + ### Get a specific region Returns the region ID and name for the East US region. .EXAMPLE Get-FinOpsRegion -RegionId "*asia*" -IncludeResourceLocation + ### Get many regions with the original Cost Management value Returns all Asia regions with the original Cost Management ResourceLocation value. .LINK diff --git a/src/powershell/Public/Get-FinOpsResourceType.ps1 b/src/powershell/Public/Get-FinOpsResourceType.ps1 index 50efac2dd..23026ab4e 100644 --- a/src/powershell/Public/Get-FinOpsResourceType.ps1 +++ b/src/powershell/Public/Get-FinOpsResourceType.ps1 @@ -9,20 +9,22 @@ Optional. Azure resource type value. Accepts wildcards. Default = * (all). .PARAMETER IsPreview - Optional. Indicates whether to include or exclude resource types that are in preview. Note: Not all resource types self-identify as being in preview, so this may not be completely accurate. Default = null (include all). + Optional. Indicates whether to include or exclude resource types that are in preview. Not all resource types self-identify as being in preview, so this information might not be accurate. Default = null (include all). .DESCRIPTION - The Get-FinOpsResourceType command returns an Azure resource type with readable display names, a flag to indicate if the resource provider identified this as a preview resource type, a description, an icon, and help and support links. + The Get-FinOpsResourceType command returns an Azure resource type with readable display names, a flag to indicate if the resource provider identified it as a preview resource type, a description, an icon, and help and support links. .EXAMPLE Get-FinOpsResourceType -ResourceType "microsoft.compute/virtualmachines" + ### Get resource type details Returns the resource type details for virtual machines. .EXAMPLE Get-FinOpsResourceType -Preview $false - Returns all resource types that are not in preview. + ### Get non-preview resource types + Returns all resource types that aren't in preview. .LINK https://aka.ms/ftk/Get-FinOpsResourceType diff --git a/src/powershell/Public/Get-FinOpsService.ps1 b/src/powershell/Public/Get-FinOpsService.ps1 index 07f440b1c..2ff211ee0 100644 --- a/src/powershell/Public/Get-FinOpsService.ps1 +++ b/src/powershell/Public/Get-FinOpsService.ps1 @@ -20,10 +20,10 @@ .PARAMETER ServiceCategory Optional. The service category to find services for. Default = null (all). - .PARAMETER ServiceCategory + .PARAMETER ServiceSubcategory Optional. The service subcategory to find services for. Default = null (all). - .PARAMETER Servicemodel + .PARAMETER ServiceModel Optional. The service model the service aligns to. Expected values: IaaS, PaaS, SaaS. Default = null (all). .PARAMETER Environment @@ -43,6 +43,7 @@ .EXAMPLE Get-FinOpsService -ConsumedService "Microsoft.C*" -ResourceType "Microsoft.Compute/virtualMachines" + ### Get services for a resource provider Returns all services with a resource provider that starts with "Microsoft.C". .LINK diff --git a/src/powershell/Public/Get-FinOpsToolkitVersion.ps1 b/src/powershell/Public/Get-FinOpsToolkitVersion.ps1 index 5aa2835ad..27688a1f6 100644 --- a/src/powershell/Public/Get-FinOpsToolkitVersion.ps1 +++ b/src/powershell/Public/Get-FinOpsToolkitVersion.ps1 @@ -6,7 +6,7 @@ Gets available versions from published FinOps toolkit releases. .DESCRIPTION - The Get-FinOpsToolkitVersions command calls GitHub to retrieve all toolkit releases, then filters the list based on the specified options. + The Get-FinOpsToolkitVersion command calls GitHub to retrieve all toolkit releases, then filters the list based on the specified options. .PARAMETER Latest Optional. Indicates that only the most recent release should be returned. Default = false. @@ -17,16 +17,19 @@ .EXAMPLE Get-FinOpsToolkitVersion + ### Get stable release versions Returns all stable (non-preview) release versions. .EXAMPLE Get-FinOpsToolkitVersion -Latest + ### Get latest stable release only Returns only the latest stable (non-preview) release version. .EXAMPLE Get-FinOpsToolkitVersion -Preview + ### Get all versions Returns all release versions, including preview releases. .LINK diff --git a/src/powershell/Public/Initialize-FinOpsHubDeployment.ps1 b/src/powershell/Public/Initialize-FinOpsHubDeployment.ps1 index 0eed7260f..d49debac8 100644 --- a/src/powershell/Public/Initialize-FinOpsHubDeployment.ps1 +++ b/src/powershell/Public/Initialize-FinOpsHubDeployment.ps1 @@ -8,10 +8,11 @@ .EXAMPLE Initialize-FinOpsHubDeployment -WhatIf + ### Test FinOps hub deployment initialization Shows what would happen if the command runs without actually running it. .DESCRIPTION - The Initialize-FinOpsHubDeployment command performs any initialization tasks required for a resource group contributor to be able to deploy a FinOps hub instance in Azure, like registering resource providers. To view the full list of tasks performed, run the command with the -WhatIf option. + The Initialize-FinOpsHubDeployment command performs any initialization tasks required for a resource group contributor to be able to deploy a FinOps hub instance in Azure, like registering resource providers. To view the full list of tasks performed, run the command with the `-WhatIf` option. .LINK https://aka.ms/ftk/Initialize-FinOpsHubDeployment diff --git a/src/powershell/Public/New-FinOpsCostExport.ps1 b/src/powershell/Public/New-FinOpsCostExport.ps1 index 64c2b74ca..861189cd2 100644 --- a/src/powershell/Public/New-FinOpsCostExport.ps1 +++ b/src/powershell/Public/New-FinOpsCostExport.ps1 @@ -1,4 +1,4 @@ -# Copyright (c) Microsoft Corporation. +# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. <# @@ -9,7 +9,7 @@ The New-FinOpsCostExport command creates a new Cost Management export for the specified scope. This command has been tested with the following API versions: - - 2025-03-01 (default) + - 2025-03-01 (default) – GA version for FocusCost and other datasets. - 2023-07-01-preview - 2023-08-01 @@ -94,7 +94,8 @@ -StartDate "2023-07-01" ` -EndDate "2023-07-31" - Creates a new one time export called 'July2023OneTime from 2023-07-01 to 2023-07-31 with Dataset = Actual and execute it once. + ### Create one time export + Creates a new one time export called 'July2023OneTime' from **2023-07-01** to **2023-07-31** with Dataset = Actual and execute it once. .EXAMPLE New-FinopsCostExport -Name 'DailyMTD' ` @@ -104,7 +105,8 @@ -EndDate "2024-12-31" ` -Execute - Creates a new scheduled export called Daily-MTD with StartDate = DateTime.Now and EndDate = 2024-12-31. Export is run immediately after creation. + ### Create and run a daily export + Creates a new scheduled export called **Daily-MTD** with StartDate = DateTime.Now and EndDate = 2024-12-31. Export is run immediately after creation. .EXAMPLE New-FinopsCostExport -Name 'Monthly-Report' ` @@ -116,7 +118,8 @@ -Monthly ` -Execute - Creates a new monthly export called Monthly-Report with StartDate = 1 day from DateTime.Now and EndDate 2024-08-15. Export is run immediately after creation. + ### Create a monthly export + Creates a new monthly export called **Monthly-Report** with StartDate = 1 day from DateTime.Now and EndDate **2024-08-15**. Export is run immediately after creation. .EXAMPLE New-FinopsCostExport -Name 'Daily--MTD' ` @@ -127,7 +130,8 @@ -Backfill 4 ` -Execute - Creates a new daily export called Daily-MTD with StartDate = DateTime.Now and EndDate 5 years from StartDate. Additiionally, export cost data for the previous 4 months and save all results in costreports container of the specified storage account. + ### Create daily export and backfill four months + Creates a new daily export called **Daily-MTD** with StartDate = DateTime.Now and EndDate 5 years from StartDate. Additionally, export cost data for the previous four months and save all results in `costreports` container of the specified storage account. .LINK https://aka.ms/ftk/New-FinOpsCostExport @@ -184,10 +188,12 @@ function New-FinOpsCostExport [int] $CommitmentDiscountLookback = 30, + # .PARAMETERSET Create a new daily/monthly export [Parameter(ParameterSetName = "Scheduled")] [switch] $Monthly, + # .PARAMETERSET Create a new one-time export [Parameter(ParameterSetName = "OneTime")] [switch] $OneTime, diff --git a/src/powershell/Public/Register-FinOpsHubProviders.ps1 b/src/powershell/Public/Register-FinOpsHubProviders.ps1 index 1bbf02831..929cd6302 100644 --- a/src/powershell/Public/Register-FinOpsHubProviders.ps1 +++ b/src/powershell/Public/Register-FinOpsHubProviders.ps1 @@ -11,10 +11,13 @@ .EXAMPLE Register-FinOpsHubProviders -WhatIf + ### Test register FinOps hub providers Shows what would happen if the command runs without actually running it. .Description - The Register-FinOpsHubProviders command registers the Azure resource providers required to deploy and operate a FinOps hub instance. To register a resource provider, you must have Contributor access (or the /register permission for each resource provider) for the entire subscription. Subscription readers can check the status of the resource providers but cannot register them. If you do not have access to register resource providers, please contact a subscription contributor or owner to run the Register-FinOpsHubProviders command. + The Register-FinOpsHubProviders command registers the Azure resource providers required to deploy and operate a FinOps hub instance. + + To register a resource provider, you must have Contributor access (or the /register permission for each resource provider) for the entire subscription. Subscription readers can check the status of the resource providers but can't register them. If you don't have access to register resource providers, contact a subscription contributor or owner to run the Register-FinOpsHubProviders command. #> function Register-FinOpsHubProviders { diff --git a/src/powershell/Public/Remove-FinOpsCostExport.ps1 b/src/powershell/Public/Remove-FinOpsCostExport.ps1 index 7cf84f00f..ed6cb4ba3 100644 --- a/src/powershell/Public/Remove-FinOpsCostExport.ps1 +++ b/src/powershell/Public/Remove-FinOpsCostExport.ps1 @@ -15,7 +15,7 @@ - 2023-03-01 .PARAMETER Name - Name of the Cost Management export. + Required. Name of the Cost Management export to delete. .PARAMETER Scope Required. Resource ID of the scope to export data for. @@ -23,13 +23,14 @@ .PARAMETER RemoveData Optional. Indicates that all cost data associated with the Export scope should be deleted. - .PARAMETER APIVersion + .PARAMETER ApiVersion Optional. API version to use when calling the Cost Management Exports API. Default = 2025-03-01. .EXAMPLE Remove-FinOpsCostExport -Name MyExport -Scope "/subscriptions/00000000-0000-0000-0000-000000000000" -RemoveData - Deletes a Cost Management export named MyExport scoped to /subscriptions/00000000-0000-0000-0000-000000000000, and deletes all exported data from the related storage account. + ### Delete a Cost Management export + Deletes a Cost Management export and removes the exported data from the linked storage account. #> function Remove-FinOpsCostExport diff --git a/src/powershell/Public/Remove-FinOpsHub.ps1 b/src/powershell/Public/Remove-FinOpsHub.ps1 index 480fe172d..e4fdc2b9a 100644 --- a/src/powershell/Public/Remove-FinOpsHub.ps1 +++ b/src/powershell/Public/Remove-FinOpsHub.ps1 @@ -6,29 +6,30 @@ Delete a FinOps hub instance and optionally keep the storage account hosting cost data. .DESCRIPTION - The Remove-FinOpsHub command deletes a FinOps Hub instance and optionally deletes the storage account hosting cost data. + The Remove-FinOpsHub command deletes a FinOps hub instance and optionally deletes the storage account hosting cost data. The command returns a boolean value indicating whether all resources were successfully deleted. .PARAMETER Name - Required when specifying Name. Name of the FinOps Hub. + Required if not specifying InputObject. Name of the FinOps hub instance. .PARAMETER ResourceGroupName - Optional when specifying Name. Resource Group Name for the FinOps Hub. + Optional when specifying Name. Resource group name for the FinOps hub. .PARAMETER InputObject - Required when specifying InputObject. Expected object is the output of Get-FinOpsHub. + Required if not specifying Name. Expected object is the output of Get-FinOpsHub. .PARAMETER KeepStorageAccount - Optional. Indicates that the storage account associated with the FinOps Hub should be retained. + Optional. Indicates that the storage account associated with the FinOps hub should be retained. Default = false. .PARAMETER Force - Optional. Deletes specified resources without asking for a confirmation. + Optional. Deletes specified resources without asking for a confirmation. Default = false. .EXAMPLE Remove-FinOpsHub -Name MyHub -ResourceGroupName MyRG -KeepStorageAccount - Deletes a FinOps Hub named MyHub and deletes all associated resources except the storage account. + ### Remove a FinOps hub instance + Deletes a FinOps hub named MyHub and deletes all associated resource except the storage account. #> function Remove-FinOpsHub @@ -88,7 +89,7 @@ function Remove-FinOpsHub throw $script:LocalizedData.Hub_Remove_NotFound -f $Name } - Write-Verbose -Message "Found FinOps Hub: $Name in resource group $ResourceGroupName" + Write-Verbose -Message "Found FinOps hub: $Name in resource group $ResourceGroupName" $uniqueId = Get-HubIdentifier -Collection $hub.Resources.Name diff --git a/src/powershell/Public/Remove-FinOpsHubScope.ps1 b/src/powershell/Public/Remove-FinOpsHubScope.ps1 index d90889061..ac5fc2783 100644 --- a/src/powershell/Public/Remove-FinOpsHubScope.ps1 +++ b/src/powershell/Public/Remove-FinOpsHubScope.ps1 @@ -6,7 +6,7 @@ Stops monitoring a scope within a FinOps hub instance. .DESCRIPTION - The Remove-FinOpsHubScope command removes a scope from being monitored by a FinOps hub instance. Data related to that scope is kept by default. To remove the data, use the -RemoveData option. + The Remove-FinOpsHubScope command removes a scope from being monitored by a FinOps hub instance. Data related to that scope is kept by default. To remove the data, use the `-RemoveData` option. .PARAMETER Id Required resource ID of the scope to remove. @@ -23,11 +23,13 @@ .EXAMPLE Remove-FinOpsHubScope -Id "/providers/Microsoft.Billing/billingAccounts/123" -HubName "FooHub" + ### Remove billing account and keep data Deletes the exports configured to use the FooHub hub instance. Existing data is retained in the storage account. .EXAMPLE Remove-FinOpsHubScope -Id "/subscriptions/##-#-#-#-###" -HubName "FooHub" -RemoveData + ### Remove subscription and historical data Deletes the exports configured to use the FooHub hub instance and removes data for that scope. .LINK diff --git a/src/powershell/Public/Start-FinOpsCostExport.ps1 b/src/powershell/Public/Start-FinOpsCostExport.ps1 index 87a651c86..34542602b 100644 --- a/src/powershell/Public/Start-FinOpsCostExport.ps1 +++ b/src/powershell/Public/Start-FinOpsCostExport.ps1 @@ -9,7 +9,7 @@ The Start-FinOpsCostExport command runs a Cost Management export for the most recent period using the Run API. This command has been tested with the following API versions: - - 2025-03-01 (default) – Enables FocusCost and other datasets. + - 2025-03-01 (default) – GA version for FocusCost and other datasets. - 2023-07-01-preview - 2023-08-01 - 2023-03-01 @@ -21,13 +21,13 @@ Optional. Resource ID of the scope to export data for. If empty, defaults to current subscription context. .PARAMETER StartDate - Optional. Day to start pulling the data for. Interpreted as a UTC calendar date, so the day you specify is the day that is exported, regardless of the local time zone. If not set, the export will use the dates defined in the export configuration. + Optional. Day to start pulling the data for. Interpreted as a UTC calendar date, so the day you specify is the day that gets exported, regardless of your local time zone. If not set, the export uses the dates defined in the export configuration. .PARAMETER EndDate - Optional. Last day to pull data for. Interpreted as a UTC calendar date, so the day you specify is the day that is exported, regardless of the local time zone. If not set and -StartDate is set, -EndDate will use the last day of the month. If not set and -StartDate is not set, the export will use the dates defined in the export configuration. + Optional. Last day to pull data for. Interpreted as a UTC calendar date, so the day you specify is the day that gets exported, regardless of your local time zone. If not set and -StartDate is set, -EndDate uses the last day of the month. If not set and -StartDate isn't set, the export uses the dates defined in the export configuration. .PARAMETER Backfill - Optional. Number of months to export the data for. Make note of throttling (429) errors. This is only run once. Failed exports are not re-attempted. Default = 0. + Optional. Number of months to export the data for. Make note of throttling (429) errors. It only runs once. Failed exports aren't reattempted. Default = 0. .PARAMETER ApiVersion Optional. API version to use when calling the Cost Management Exports API. Default = 2025-03-01. @@ -35,16 +35,19 @@ .EXAMPLE Start-FinopsCostExport -Name 'CostExport' + ### Export configured period Runs an export called 'CostExport' for the configured period on the subscription configured in Get-AzContext. .EXAMPLE Start-FinopsCostExport -Scope '/providers/Microsoft.Billing/billingAccounts/1234' -Name 'CostExport' -StartDate '2023-01-01' -EndDate '2023-12-31' + ### Export specific dates Runs an export called 'CostExport' for a specific date range on the 1234 billing account. .EXAMPLE Start-FinopsCostExport -Scope '/providers/Microsoft.Billing/billingAccounts/1234/billingProfiles/5678' -Name 'CostExport' -Backfill 12 + ### Backfill export Runs an export called 'CostExport' for the previous 12 months on the 5678 billing profile. .LINK diff --git a/src/scripts/Build-Documentation.ps1 b/src/scripts/Build-Documentation.ps1 new file mode 100644 index 000000000..74d91b8e3 --- /dev/null +++ b/src/scripts/Build-Documentation.ps1 @@ -0,0 +1,524 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +<# + .SYNOPSIS + Generates PowerShell command reference docs for the Microsoft Learn documentation site. + + .DESCRIPTION + The Build-Documentation command generates one reference page per public PowerShell command + under docs-mslearn/toolkit/powershell/{category}/{command-name-lowercase}.md by parsing each + command's comment-based help. It imports the FinOpsToolkit module, uses Get-Help -Full to read + parameters, examples, and syntax, and regex-scans the raw source for ".OUTPUTS" and + ".PARAMETERSET" markers, since PowerShell's native help XML does not expose return-value + schemas or friendly parameter set names. + + Only the command pages are generated. Category index pages (for example, + cost/cost-management-commands.md) and the top-level powershell-commands.md are hand-maintained + and are not regenerated by this script. + + .PARAMETER Command + Optional. PowerShell command to generate documentation for. Default = * (all). + + .PARAMETER NewDate + Optional. Date to stamp in ms.date for brand-new doc pages, in MM/dd/yyyy format. Default = today. + Existing pages keep their current ms.date; a CI workflow updates it when body content changes. + + .EXAMPLE + ./Build-Documentation + + ### Generate documentation + Generates documentation for all public commands. + + .EXAMPLE + ./Build-Documentation -Command Get-FinOpsHub + + ### Generate documentation for a single command + Generates documentation for the Get-FinOpsHub command only. + + .LINK + https://github.com/microsoft/finops-toolkit/blob/dev/src/scripts/README.md#-build-documentation +#> +[CmdletBinding()] +param +( + [string] + $Command = '*', + + [string] + $NewDate = (Get-Date -Format 'MM/dd/yyyy') +) + +$ErrorActionPreference = 'Stop' + +$srcDir = "$PSScriptRoot/../powershell" +$docsDir = "$PSScriptRoot/../../docs-mslearn/toolkit/powershell" + +# Map a command noun to its docs-mslearn category folder and "Give feedback" featureName prefix. +# Mirrors the grouping used in powershell-commands.md and the individual category index pages. +function Get-CommandCategory([string] $CommandName) +{ + $noun = $CommandName -replace '^[A-Za-z]+-FinOps', '' + + if ($noun -eq 'ServicePrincipal' -or $noun.StartsWith('Cost')) + { + return @{ Folder = 'cost'; FeaturePrefix = 'CostManagement' } + } + elseif ($noun.StartsWith('Hub')) + { + return @{ Folder = 'hubs'; FeaturePrefix = 'Hubs' } + } + elseif (@('PricingUnit', 'Region', 'ResourceType', 'Service') -contains $noun) + { + return @{ Folder = 'data'; FeaturePrefix = 'OpenData' } + } + else + { + return @{ Folder = 'toolkit'; FeaturePrefix = 'Toolkit' } + } +} + +# Renders a GitHub-flavored markdown table with prettier-style column padding so re-generating +# unchanged content doesn't produce formatting-only diffs. +function Format-MarkdownTable([string[]] $Headers, [string[][]] $Rows) +{ + $widths = @() + for ($i = 0; $i -lt $Headers.Count; $i++) + { + $cellLengths = @($Rows | ForEach-Object { $_[$i].Length }) + $widths += [Math]::Max($Headers[$i].Length, ((@($cellLengths) + 0) | Measure-Object -Maximum).Maximum) + } + + $headerCells = @() + for ($i = 0; $i -lt $Headers.Count; $i++) { $headerCells += $Headers[$i].PadRight($widths[$i]) } + + $lines = @() + $lines += '| ' + ($headerCells -join ' | ') + ' |' + $lines += '| ' + ((0..($Headers.Count - 1) | ForEach-Object { '-' * $widths[$_] }) -join ' | ') + ' |' + foreach ($row in $Rows) + { + $lines += '| ' + ((0..($Headers.Count - 1) | ForEach-Object { $row[$_].PadRight($widths[$_]) }) -join ' | ') + ' |' + } + return $lines +} + +# Import the module so Get-Help resolves the same way it would for an installed module (importing +# the module -- rather than dot-sourcing a single file -- picks up private function dependencies). +Import-Module "$srcDir/FinOpsToolkit.psm1" -Force -ErrorAction Stop + +# Map .NET type names from Get-Help to the PowerShell type aliases used in the hand-written docs +# (for example, "String" -> "string", "Int32" -> "int"). +$typeAliasMap = @{ + 'String' = 'string' + 'Int32' = 'int' + 'Int64' = 'long' + 'Boolean' = 'bool' + 'Double' = 'double' + 'Object' = 'object' + 'Hashtable' = 'hashtable' + 'SwitchParameter' = 'switch' + 'DateTime' = 'datetime' +} +function Get-FriendlyTypeName([string] $TypeName) +{ + # Get-Help renders Nullable[T] as "Nullable`1" -- unwrap to the friendly name of T. + if ($TypeName -match '^Nullable``?1$') { $TypeName = 'Boolean' } + if ($typeAliasMap.ContainsKey($TypeName)) { return $typeAliasMap[$TypeName] } + return $TypeName +} + +Write-Host 'Generating PowerShell command documentation...' + +Get-ChildItem -Path "$srcDir/Public/$Command.ps1" | ForEach-Object { + $file = $_ + $commandName = $file.BaseName + + Write-Host "- $commandName" + + $category = Get-CommandCategory -CommandName $commandName + $folder = $category.Folder + $featurePrefix = $category.FeaturePrefix + $outFile = "$docsDir/$folder/$($commandName.ToLowerInvariant()).md" + $isNewFile = -not (Test-Path $outFile) + + $help = Get-Help $commandName -Full + $rawText = Get-Content $file.FullName + $rawTextJoined = $rawText -join "`n" + + # Collect file contents via string builder for perf + $sb = [System.Text.StringBuilder]::new() + function append([string] $Text) + { + [void]$sb.AppendLine($Text) + } + + # ------------------------------------------------------------------ + # Front matter + # ------------------------------------------------------------------ + if ($isNewFile) + { + $msDate = $NewDate + $author = 'flanakin' + $msAuthor = 'micflan' + $msReviewer = 'micflan' + } + else + { + $existing = Get-Content $outFile -Raw + $msDate = if ($existing -match '(?m)^ms\.date:\s*(.+)$') { $Matches[1].Trim() } else { $NewDate } + $author = if ($existing -match '(?m)^author:\s*(.+)$') { $Matches[1].Trim() } else { 'flanakin' } + $msAuthor = if ($existing -match '(?m)^ms\.author:\s*(.+)$') { $Matches[1].Trim() } else { 'micflan' } + $msReviewer = if ($existing -match '(?m)^ms\.reviewer:\s*(.+)$') { $Matches[1].Trim() } else { $msAuthor } + } + + $synopsis = ($help.Synopsis | Out-String).Trim().TrimEnd('.') + # Convert the synopsis's leading 3rd-person verb to imperative for the meta description, + # e.g. "Gets a list of..." -> "Get a list of...". + $synopsisImperative = [regex]::Replace($synopsis, '^(\w+?)s\b', '$1') + + # The meta description is often a hand-curated paraphrase rather than a mechanical function of + # the synopsis, so preserve it verbatim from the existing file. New pages get a synthesized + # description built from the synopsis. + if (-not $isNewFile -and $existing -match '(?m)^description:\s*(.+)$') + { + $description = $Matches[1].Trim() + } + else + { + $description = "$synopsisImperative using the $commandName command in the FinOpsToolkit module." + } + + append '---' + append "title: $commandName command" + append "description: $description" + append "author: $author" + append "ms.author: $msAuthor" + append "ms.date: $msDate" + append 'ms.topic: reference' + append 'ms.service: finops' + append 'ms.subservice: finops-toolkit' + append "ms.reviewer: $msReviewer" + append "#customer intent: As a FinOps user, I want to understand how to use the $commandName command in the FinOpsToolkit module." + append '---' + append '' + append "# $commandName command" + append '' + + # ------------------------------------------------------------------ + # Description + API version note + # ------------------------------------------------------------------ + $descText = (($help.Description.Text | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }) -join "`n`n").Trim() + + # Split off a leading "This command was/has been tested with the following API versions" + # paragraph (including its bullet list) so it renders as its own paragraph, matching the + # existing hand-written docs. + $apiVersionBlock = $null + $bodyDescText = $descText + if ($descText -match '(?ms)^(This command (?:was|has been) tested with the following API versions:\r?\n(?:- .+\r?\n?)+)') + { + $apiVersionBlock = $Matches[1].Trim() + $apiVersionBlock = $apiVersionBlock -replace 'has been tested', 'was tested' + # Insert a blank line between the header and the bullet list to match the hand-written docs. + $apiVersionBlock = $apiVersionBlock -replace '(API versions:)\r?\n', "`$1`n`n" + $bodyDescText = $descText.Replace($Matches[1], '').Trim() + } + + if (-not $bodyDescText) + { + $synopsisLowerFirst = [regex]::Replace($synopsisImperative, '^[A-Z]', { param($m) $m.Value.ToLowerInvariant() }) + $bodyDescText = "The **$commandName** command $synopsisLowerFirst." + } + elseif ($bodyDescText -notmatch [regex]::Escape("**$commandName**")) + { + $lines = $bodyDescText -split "`n" + # Bold only the first standalone mention of the command name, in the opening sentence. + $pattern = [regex]"(? \[!NOTE\]\r?\n(?:> .*\r?\n?)+)') + { + # A "> [!NOTE]" callout directly under the intro description (no API-version block in + # between, and before the Syntax section) is hand-written and can't be derived from + # source -- preserve it verbatim. + append $Matches[1].TrimEnd("`r", "`n") + append '' + } + + append '
' + append '' + + # ------------------------------------------------------------------ + # Syntax + # ------------------------------------------------------------------ + append '## Syntax' + append '' + + $paramSets = $rawText | Select-String -Pattern '#\s*\.PARAMETERSET\s+(.*)$' | ForEach-Object { $_.Matches.Groups[1].Value.Trim() } + $hasConfirm = ($help.Parameters.Parameter | Where-Object { $_.Name -eq 'Confirm' -and (($_.Description.Text -join '')).Length -gt 0 }).Count -gt 0 + $hasCmdletBinding = $rawTextJoined -match '\[CmdletBinding\(' + + $syntaxItems = @($help.Syntax.SyntaxItem) + $paramSetIndex = 0 + foreach ($syntaxItem in $syntaxItems) + { + append '```powershell' + if ($syntaxItems.Count -gt 1 -and $paramSets.Length -gt $paramSetIndex) + { + append "# $($paramSets[$paramSetIndex])" + } + $paramSetIndex++ + + $paramLines = @() + $syntaxItem.Parameter | Where-Object { $_.Name -ne 'Confirm' -or $hasConfirm } | ForEach-Object { + $p = $_ + $piece = '' + if ($p.Required -ne $true) { $piece += '[' } + if ($p.Position -ne 'named') { $piece += '[' } + $piece += "‑$($p.Name)" + if ($p.Position -ne 'named') { $piece += ']' } + if ($p.ParameterValue) { $piece += " <$(Get-FriendlyTypeName $p.ParameterValue)>" } + if ($p.Required -ne $true) { $piece += ']' } + $paramLines += $piece + } + if ($hasCmdletBinding) + { + $paramLines += '[]' + } + + if ($paramLines.Count -gt 0) + { + append "$commandName ``" + for ($i = 0; $i -lt $paramLines.Count; $i++) + { + $suffix = if ($i -lt $paramLines.Count - 1) { ' `' } else { '' } + append " $($paramLines[$i])$suffix" + } + } + else + { + append $commandName + } + append '```' + append '' + } + append '
' + append '' + + # ------------------------------------------------------------------ + # Parameters + # ------------------------------------------------------------------ + $paramRows = @() + $help.Parameters.Parameter | Where-Object { $_.Name -ne 'Confirm' -or $hasConfirm } | ForEach-Object { + $p = $_ + $desc = (($p.Description.Text | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }) -join ' ').Trim() + if ($p.Name -eq 'WhatIf' -and [string]::IsNullOrWhiteSpace($desc)) + { + $desc = 'Optional. Shows what would happen if the command runs without actually running it.' + } + # A multi-line PARAMETER description (e.g. a bullet list of scope ID formats) must not + # contain a raw newline inside a markdown table cell -- join lines with
instead. + $desc = ($desc -split "`r?`n" | ForEach-Object { $_.Trim() }) -join '
' + # Escape a standalone "*" used as a wildcard-default placeholder (e.g. "Default = * (all)") + # so markdown doesn't parse it as emphasis -- but leave a "*" fused inside a word/token + # (e.g. "*_raw", "*_final_v*") alone, since that's a glob fragment, not emphasis markup. + $desc = [regex]::Replace($desc, '(? [!NOTE]" callout directly under the parameter table (e.g. a SKU-availability caveat) + # is hand-written and can't be derived from source -- preserve it verbatim when present. + if (-not $isNewFile -and $existing -match '(?m)^\| `‑[^\r\n]+\r?\n\r?\n(> \[!NOTE\]\r?\n(?:> .*\r?\n?)+)') + { + append $Matches[1].TrimEnd("`r", "`n") + append '' + } + + append '
' + append '' + + # ------------------------------------------------------------------ + # Return value (parsed from ".OUTPUTS" markers in the raw source) + # ------------------------------------------------------------------ + $outputBlocks = @() + $currentPrefix = $null + $currentType = $null + $currentLines = @() + foreach ($line in $rawText) + { + if ($line -match '^(\s*#\s*)\.OUTPUTS\s+(\S+)\s*$') + { + if ($currentType) { $outputBlocks += @{ Type = $currentType; Lines = $currentLines } } + $currentPrefix = $Matches[1] + $currentType = $Matches[2] + $currentLines = @() + } + elseif ($currentPrefix -and $line -match '^\s*#\s?(\|.*\|)\s*$') + { + $currentLines += $Matches[1] + } + elseif ($currentType -and $currentLines.Count -gt 0) + { + $outputBlocks += @{ Type = $currentType; Lines = $currentLines } + $currentPrefix = $null + $currentType = $null + $currentLines = @() + } + } + if ($currentType -and $currentLines.Count -gt 0) + { + $outputBlocks += @{ Type = $currentType; Lines = $currentLines } + } + + # Root type first: a block is "nested" if some other block's rows reference its type name + # (for example, FinOpsCostExport lists a RunHistory column of type FinOpsCostExportRunHistory[]). + # Nested types are documented after the root type they belong to, regardless of source order. + if ($outputBlocks.Count -gt 1) + { + $allLines = ($outputBlocks | ForEach-Object { $_.Lines }) -join "`n" + $outputBlocks = @($outputBlocks | Sort-Object -Property @{ + Expression = { if ($allLines -match [regex]::Escape($_.Type) + '\[\]') { 1 } else { 0 } } + }, @{ Expression = { $outputBlocks.IndexOf($_) } }) + } + + if ($outputBlocks.Count -gt 0) + { + append '## Return value' + append '' + foreach ($block in $outputBlocks) + { + append "### $($block.Type) object" + append '' + $block.Lines | ForEach-Object { append $_ } + append '' + } + append '
' + append '' + } + + # ------------------------------------------------------------------ + # Examples + # ------------------------------------------------------------------ + append '## Examples' + append '' + + # The one-line intro under "## Examples" ("The following example(s) demonstrate...") is a + # hand-written paraphrase of what the examples cover, not mechanically derived from source. + # Preserve it verbatim from the existing file; new pages get a generic intro line. + if (-not $isNewFile -and $existing -match '(?m)^(The following examples? demonstrates? .+)$') + { + append $Matches[1].Trim() + append '' + } + + $help.Examples.Example | ForEach-Object { + $example = $_ + $remarksText = (($example.Remarks.Text | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }) -join "`n").Trim() + $descText = $remarksText + $title = $null + + if ($remarksText -match '(?s)^###\s+(.+?)\r?\n(.*)$') + { + $title = "### $($Matches[1].Trim())" + $descText = $Matches[2].Trim() + } + else + { + $fallback = ($example.Title -replace '-+', '').Trim() -replace '^EXAMPLE\s*(\d*)\s*', 'Example $1' + $title = "### $($fallback.Trim())" + } + + append $title + append '' + append '```powershell' + append ($example.Code.Trim()) + append '```' + append '' + if ($descText) + { + append $descText + append '' + } + } + append '
' + append '' + + # ------------------------------------------------------------------ + # Give feedback + related content + # ------------------------------------------------------------------ + append '## Give feedback' + append '' + append "Let us know how we're doing with a quick review. We use these reviews to improve and expand FinOps tools and resources." + append '' + # The featureName suffix used in the feedback survey link is a hand-picked short label per + # command (for example, "Hubs.InitDeployment", not "Hubs.InitializeHubDeployment"), so it + # can't be reliably derived from the command name. Preserve it from the existing file; only + # synthesize one for brand-new pages that have never had a featureName before. + if (-not $isNewFile -and $existing -match 'featureName/([A-Za-z.]+)\)') + { + $featureName = $Matches[1] + } + else + { + $noun = $commandName -replace '^[A-Za-z]+-FinOps', '' + $verb = ($commandName -split '-')[0] + $featureName = "$featurePrefix.$verb$noun" + } + append '' + append '> [!div class="nextstepaction"]' + append "> [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/$featureName)" + append '' + append '' + append "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." + append '' + append '' + append '> [!div class="nextstepaction"]' + append '> [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")' + append '' + append '' + append '
' + append '' + # "Related content" (products vs. solutions, and which links are included) is hand-curated + # per command and can't be derived from the source .ps1. Preserve it verbatim from the + # existing file; new pages get the standard solutions-only boilerplate. + if (-not $isNewFile -and $existing -match '(?s)(## Related content\r?\n.*)$') + { + $relatedContent = $Matches[1].TrimEnd("`r", "`n") + $relatedContent -split "`r?`n" | ForEach-Object { append $_ } + } + else + { + append '## Related content' + append '' + append 'Related solutions:' + append '' + append '- [FinOps toolkit Power BI reports](../../power-bi/reports.md)' + append '- [FinOps hubs](../../hubs/finops-hubs-overview.md)' + append '' + append '
' + } + + $content = $sb.ToString().TrimEnd("`r", "`n") + "`n" + [System.IO.File]::WriteAllText($outFile, $content, [System.Text.UTF8Encoding]::new($false)) + $sb.Clear() | Out-Null +} + +Write-Host 'Done.'