Public/Get-FinOpsCostExport.ps1
# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. <# .SYNOPSIS Get list of Cost Management exports. .DESCRIPTION The Get-FinOpsCostExport command gets a list of Cost Management exports for a given scope. This command has been tested with the following API versions: - 2023-07-01-preview (default) – Enables FocusCost and other datasets. - 2023-08-01 .PARAMETER Name Optional. Name of the export. Supports wildcards. .PARAMETER Scope Optional. Resource ID of the scope the export was created for. If empty, defaults to current subscription context. .PARAMETER DataSet Optional. Dataset to export. Allowed values = "ActualCost", "AmortizedCost", "FocusCost", "PriceSheet", "ReservationDetails", "ReservationTransactions", "ReservationRecommendations". Default = null (all exports). .PARAMETER DataSetVersion Optional. Schema version of the dataset to export. Default = null (all exports). .PARAMETER StorageAccountId Optional. Resource ID of the storage account to get exports for. Default = null (all exports). .PARAMETER StorageContainer Optional. Name of the container to get exports for. Supports wildcards. Default = null (all exports). .PARAMETER RunHistory Optional. Indicates whether the run history should be expanded. Default = false. .PARAMETER ApiVersion Optional. API version to use when calling the Cost Management exports API. Default = 2023-07-01-preview. .EXAMPLE Get-FinOpsCostExport -Scope "/subscriptions/00000000-0000-0000-0000-000000000000" 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" 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" 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" 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*" 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 "2023-07-01-preview" Gets all exports within the subscription scope for a container matching wildcard pattern and using a specific API version. .LINK https://aka.ms/ftk/Get-FinOpsCostExport #> function Get-FinOpsCostExport { param ( [Parameter()] [SupportsWildcards()] [string] $Name, [Parameter()] [string] $Scope, [Parameter()] [ValidateSet("ActualCost", "AmortizedCost", "FocusCost", "PriceSheet", "ReservationDetails", "ReservationTransactions", "ReservationRecommendations")] [string] $Dataset, [Parameter()] [string] $DatasetVersion, [Parameter()] [string] $StorageAccountId, [Parameter()] [SupportsWildcards()] [string] $StorageContainer, [Parameter()] [switch] $RunHistory, [Parameter()] [string] $ApiVersion = '2023-07-01-preview' ) $context = Get-AzContext if (-not $context) { throw $script:LocalizedData.Common_ContextNotFound } # if Scope is not passed, use current subscription scope if ([System.String]::IsNullOrEmpty($Scope)) { $contextsubscription = $context.Subscription.Id $Scope = "subscriptions/$contextsubscription" Write-Verbose -Message "Scope parameter was not passed. Setting to subscription scope from current context" } $scope = $scope.Trim("/") $path = "$scope/providers/Microsoft.CostManagement/exports?api-version=$ApiVersion$(if ($RunHistory) { '&$expand=runHistory' })" # Get operation does not allow wildcards. Fetching all exports using list operation and then filtering in script # https://learn.microsoft.com/rest/api/cost-management/exports/list?tabs=HTTP Write-Verbose -Message "fetching all exports for scope:$scope" $response = Invoke-Rest -Method GET -Uri $path -CommandName "Get-FinOpsCostExport" Write-Verbose -Message "response received with status code $($response.StatusCode)" if ($response.Success) { $content = $response.Content.Value Write-Verbose -Message "found $($content.count) export items for the scope $scope" # Name parameter received if (-not [System.String]::IsNullOrEmpty($Name)) { $content = $content | Where-Object { $_.name -like $Name } Write-Verbose -Message "$($content.count) items left after filtering for Name $Name" } if (-not [System.String]::IsNullOrEmpty($Dataset)) { $content = $content | Where-Object { $_.properties.definition.type -like $Dataset } Write-Verbose -Message "$($content.count) items left after filtering for Dataset $Dataset" } if (-not [System.String]::IsNullOrEmpty($DatasetVersion)) { $content = $content | Where-Object { $_.properties.definition.type -like $DatasetVersion } Write-Verbose -Message "$($content.count) items left after filtering for DatasetVersion $DatasetVersion" } if (-not [System.String]::IsNullOrEmpty($StorageAccountId)) { $content = $content | Where-Object { $_.properties.deliveryInfo.destination.resourceId.tostring() -eq $StorageAccountId } Write-Verbose -Message "found $($content.count) items after filtering for storageaccountid $StorageAccountId" } if (-not [System.String]::IsNullOrEmpty($StorageContainer)) { $content = $content | Where-Object { $_.properties.deliveryInfo.destination.container.tostring() -like $StorageContainer } Write-Verbose -Message "found $($content.count) items after filtering for StorageContainer $StorageContainer" } $exportdetails = @() $content | ForEach-Object { $item = [PSCustomObject]@{ Name = $_.name Id = $_.id Type = $_.type eTag = $_.eTag Description = $_.properties.exportDescription Dataset = $_.properties.definition.type DatasetVersion = $_.properties.definition.configuration.dataVersion DatasetFilters = $_.properties.definition.configuration.filter DatasetTimeFrame = $_.properties.definition.timeframe DatasetStartDate = $_.properties.definition.timePeriod.from DatasetEndDate = $_.properties.definition.timePeriod.to DatasetGranularity = $_.properties.definition.dataset.granularity ScheduleStatus = $_.properties.schedule.status ScheduleRecurrence = $_.properties.schedule.recurrence ScheduleStartDate = $_.properties.schedule.recurrencePeriod.from ScheduleEndDate = $_.properties.schedule.recurrencePeriod.to NextRuntimeEstimate = $_.properties.nextRunTimeEstimate Format = $_.properties.format StorageAccountId = $_.properties.deliveryInfo.destination.resourceId StorageContainer = $_.properties.deliveryInfo.destination.container StoragePath = $_.properties.deliveryInfo.destination.rootfolderpath OverwriteData = $_.properties.deliveryInfo.dataOverwriteBehavior -eq "OverwritePreviousReport" PartitionData = $_.properties.deliveryInfo.partitionData CompressionMode = $_.properties.deliveryInfo.compressionMode RunHistory = $_.properties.runHistory.value | Where-Object { $_ -ne $null } | ForEach-Object { [PSCustomObject]@{ Id = $_.id ExecutionType = $_.properties.executionType FileName = $_.fileName StartTime = $_.processingStartTime EndTime = $_.processingEndTime Status = $_.status SubmittedBy = $_.submittedBy SubmittedTime = $_.submittedTime } } } $exportdetails += $item } return $exportdetails } } |