使用PowerShell构建Azure详细使用报告

在Azure中運行工作負載的最重要方面之一是追蹤費用。通過使用Azure詳細使用報告跟踪資源使用情況,您可以實現這一目標。在本文中,您將學習如何創建一個PowerShell腳本,以便按日期輕鬆查詢所有Azure資源的使用情況和費用。

Azure中的資源以多種方式不斷增加成本。雖然您可以通過Web門戶查看資源使用情況,但這是有限的。但是,通過使用一些PowerShell cmdlet,您可以構建一個方便的報告,以便一覽您的Azure資源正在進行的使用情況(因此產生的費用)。

本文是根據TechSnips YouTube視頻創作的。如果您是一個更喜歡視覺學習的人,可以隨時查看該視頻。否則,請繼續閱讀!

通過Azure帳戶中心下載報告

您可以從Azure Account Center下載各種不同的使用報告。 Azure Account Center 是一個網絡門戶,您可以在其中查看您的計費週期歷史、下載發票並查看您的 Azure 訂閱概覽。

雖然您可以通過 Azure Account Center 下載 Azure 使用報告,但在選擇日期範圍方面並沒有靈活性。您無法限制使用量在特定日期範圍內,因為日期是固定與您的計費週期相吻合的。

您可以在下面看到一個計費週期的示例以及下載使用報告的鏈接。

Azure Account Center usage reports

這些使用報告中包含了您可能不需要的其他訊息。

也許您需要過去 60 天的使用報告。要使用 Azure Account Center 獲取此信息,您需要下載至少三個計費週期的使用報告,以涵蓋所需的所有日期。

報告下載完成後,您需要刪除多餘的數據。然後,您需要找出一種方法來合併這些數據。不,謝謝!這太繁瑣了。

使用PowerShell,您可以建立一個可重複使用的腳本、函數或模塊來提取Azure資源使用報告。這些報告可以手動運行幾行命令,也可以作為定時任務自動執行。

先決條件

本文是一個演示文稿。要跟隨本文操作,您需要做一些準備工作。

如何獲取資源使用數據

在創建腳本之前,讓我們先使用Get-UsageAggregates cmdlet討論基本知識。這是一個可以按日期範圍、每小時或每天等指標,從Azure資源中提取使用情況的cmdlet。 Get-UsageAggregates cmdlet是在本文中學習大部分魔術的主要cmdlet。

為了演示Get-UsageAggregates cmdlet,假設您需要查找2019年4月1日至2019年9月12日的Azure資源使用情況。相同的技巧可用於任何日期範圍。下面是根據這些日期查找使用數據的片段。

$params = @{
    ReportedStartTime = '04-01-19'
    ReportedEndTime = '09-12-19'
    AggregationGranularity = 'Hourly'
    ShowDetails = $true
}
$usageData = Get-UsageAggregates @params
Parameter Value Usage Explanation
ReportStartTime 04-01-19 This is the oldest date you want to retrieve.

(月 日 年)

ReportEndTime 09-12-19 This is the latest date you want to retrieve.

(月 日 年)

AggregationGranularity Hourly The granularity of data to return. Valid values are “Daily” and “Hourly”
ShowDetails $True Indicates whether the instance-level details are expanded

如果返回了數據,您應該會獲得類似下面截圖的結果。您可以看到實際使用數據存儲在UsageAggregations屬性中。

Raw UsageAggregations output properties

處理Get-UsageAggregates中的分頁

在上面的部分中,命令返回的對象數量可能會達到數千個,特別是對於長時間範圍。為了防止API過載,Get-UsageAggregates命令只返回最多1000個結果。如果您已經像前面的部分所述保存了$usageData變量,您可以通過運行此命令$usageData.UsageAggregations.count來確認它。

如果結果超過1000個,您需要做更多的工作。

當您檢查Get-UsageAggregates返回的屬性時,您會注意到一個名為ContinuationToken的屬性,如下所示。您可以看到這個令牌是一個長字符串。

Usage aggregates continuation token

ContinuationToken是指向下一組結果的指標。這個屬性充當書籤,用於知道從哪個頁面獲取下一批結果。

為了演示,使用$usageData.UsageAggregations[-1]獲取上一個結果中的最後一個項目,如下所示。注意Usage StartUsage End的時間。

First usage object

現在再次將相同的參數傳遞給Get-UsageAggregates命令。但是這次,使用ContinuationToken參數,並使用之前返回的ContinuationToken屬性的值。下面是一個如何執行此操作的示例。

$params = @{
    ReportedStartTime      = '04-01-19'
    ReportedEndTime        = '09-12-19'
    AggregationGranularity = 'Hourly'
    ShowDetails            = $true
    ContinuationToken      = $usageData.ContinuationToken
}
$usageData = Get-UsageAggregates @params

現在使用$usageData.UsageAggregations[-1]獲取UsageAggregations屬性數組中的最後一個項目。將其與之前的結果進行比較,以確認新的結果是否不同。

比較應該類似於下面的示例。注意日期範圍相差七天。通過使用ContinuationToken,您檢索了第二頁的結果。

Second page of usage reports
First page of usage reports

構建Azure資源使用報告功能

你應該知道分頁是如何工作並如何使用ContinuationToken屬性和參數。但如果要檢索數以萬計甚至數十萬的結果呢?手動使用令牌這種方式並不會很好地工作。

讓我們建立一個處理這種分頁需求並允許我們進一步靈活操作的PowerShell腳本。這個腳本將允許您提供自己的參數並處理分頁需求。同時,它還將為您提供靈活性,以便在需要時擴展它以執行其他任務。

建立參數

首先建立一些函數框架。下面是一個名為Get-AzureUsage的示例函數。這個函數有三個可能看起來很熟悉的參數。

以前,這些參數是在Get-UsageAggregates cmdlet自身上定義的。現在,您正在建立一個“包裝”函數,它將向該cmdlet傳遞值。

Function Get-AzureUsage {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [datetime]$FromTime,
 
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [datetime]$ToTime,
 
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [ValidateSet('Hourly', 'Daily')]
        [string]$Interval = 'Daily'
    )

下面是一個表格,提供有關所有這些參數的更多信息。

Parameter Usage
FromTime This is a mandatory parameter that accepts a DateTime value. The value represents the oldest date of the report.
ToTime This is a mandatory parameter that accepts a DateTime value. The value represents the latest date of the report.
Interval This is a non-empty parameter that accepts two possible values: ‘Daily’ and ‘Hourly’. The default value is Daily. This represents the granularity of the report to return.

查詢資源使用情況

一旦函數被創建並且所有參數都被定義,就該填寫函數的其餘部分了。

您可以在下面看到其餘的Get-AzureUsage函數。請務必查看註釋以更深入地了解代碼的執行過程。

Write-Verbose -Message "Querying usage data [$($FromTime) - $($ToTime)]..."
    $usageData = $null
    ## 開始執行 do/while 迴圈以自動處理繼續標記
    do {    
        ## 定義傳遞給 Get-UsageAggregates 的所有參數
        $params = @{
            ReportedStartTime      = $FromTime
            ReportedEndTime        = $ToTime
            AggregationGranularity = $Interval
            ShowDetails            = $true
        }
        ## 只有在第一次執行時不使用 ContinuationToken 參數
        if ((Get-Variable -Name usageData -ErrorAction Ignore) -and $usageData) {
            Write-Verbose -Message "Querying usage data with continuation token $($usageData.ContinuationToken)..."
            $params.ContinuationToken = $usageData.ContinuationToken
        }
        $usageData = Get-UsageAggregates @params
        $usageData.UsageAggregations | Select-Object -ExpandProperty Properties
    } while ('ContinuationToken' -in $usageData.psobject.properties.name -and $usageData.ContinuationToken)
}

完成的腳本(可複製/貼上)

將參數和功能代碼結合後,您將得到一個完成的腳本,如下所示。您現在可以將其複製到您自己的腳本中,或直接複製到 PowerShell 控制台進行測試。

Function Get-AzureUsage {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [datetime]$FromTime,
 
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [datetime]$ToTime,
 
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [ValidateSet('Hourly', 'Daily')]
        [string]$Interval = 'Daily'
    )
    
    Write-Verbose -Message "Querying usage data [$($FromTime) - $($ToTime)]..."
    $usageData = $null
    do {    
        $params = @{
            ReportedStartTime      = $FromTime
            ReportedEndTime        = $ToTime
            AggregationGranularity = $Interval
            ShowDetails            = $true
        }
        if ((Get-Variable -Name usageData -ErrorAction Ignore) -and $usageData) {
            Write-Verbose -Message "Querying usage data with continuation token $($usageData.ContinuationToken)..."
            $params.ContinuationToken = $usageData.ContinuationToken
        }
        $usageData = Get-UsageAggregates @params
        $usageData.UsageAggregations | Select-Object -ExpandProperty Properties
    } while ('ContinuationToken' -in $usageData.psobject.properties.name -and $usageData.ContinuationToken)
}

使用我們的函數查詢資源使用情況

現在是試驗函數的時候了。將上面的代碼粘貼到腳本中並在當前的 PowerShell 會話中 點源 它,或將代碼直接複製到 PowerShell 會話中。

提示:如果您使用的是 PowerShell ISE 或 Visual Studio Code,您可以將要導入的代碼高亮顯示,然後按 F8。否則,將代碼複製並粘貼到 PowerShell 會話中更容易。

現在運行該函數,為 FromTimeToTime 和您想要查看結果的間隔提供值。下面是如何調用此函數的示例。

$usage = Get-AzureUsage -FromTime '08-12-19' -ToTime '09-12-19' -Interval Hourly -Verbose

一旦运行此代码,如果您选择使用可选的Verbose参数,则会看到一些冗长的消息。如下面的示例所示,使用情况报告计数为4,659。您还会注意到函数对Get-UsageAggregates函数进行了四次调用,每次获取下一页的结果。函数之所以能够这样做,是因为它在每次调用时使用了正确的ContinuationToken值。

Automatically handling the continuation token

过滤报告

此时,报告包含所有可用资源类型的所有使用详细信息。但是您可以对报告进行筛选,只显示您想要的资源。为此,您可以扩展函数以允许此功能,或将输出导入其他PowerShell cmdlet。

Get-Azure函数的输出返回所有资源类型,但包含一个名为MeterCategory的属性。此属性定义了该行代表的资源类型。例如,要仅获取Azure虚拟机使用情况报告,您可以使用Group-Object cmdlet将所有MeterCategory为Virtual Machines的对象分组。

Group-Object cmdlet将返回输出中存在的行数作为Count属性。然后,将输出限制为仅包含Count和Name属性(MeterCategory的值),您可以看到所有Azure资源类型的使用情况报告行数。

如您在下方截圖中所見,報告中有 768 個「虛擬機器」的項目。

Azure Virtual Machines resource usage

為了進一步擴展這個篩選概念,您還可以利用計算屬性來創建更友好的輸出,如下所示。

$usage | Where-Object {$_.MeterCategory -eq 'Virtual Machines'} | `
Format-Table UsageStartTime,UsageEndTime,@{n="VM Name";e={(($_.InstanceData | `
ConvertFrom-Json).'Microsoft.Resources'.resourceURI -split "/")[-1]}},Quantity,Unit

當您運行上面的代碼片段時,您應該會看到類似下面的輸出。

Advanced filtering for Get-AzureUsage

擴展報告的想法

使用本文中的代碼,您可以以多種不同的方式擴展剛剛創建的工具的功能。

您可以將輸出匯出到 CSV 檔案中,在 Excel 中操作數據,或者使用 ConvertTo-HTML 或 EnhancedHTML2 PowerShell 模塊創建 HTML 報告。

再進一步,使用 Send-MailMessage cmdlet,還可以將結果添加到電子郵件通知中。世界是你的舞台!

總結

在本文中,您了解了如何從 Azure 檢索資源使用報告。您還學習了如何構建一個自定義的 PowerShell 函數來自動化這個過程,並使用該函數來操作輸出。

下次你被意外的 Azure 账单冲击到时,你没有借口了!自己构建一个 PowerShell 函数,随时查询 Azure 资源使用情况,以便留意账单。

进一步阅读

Source:
https://adamtheautomator.com/azure-detailed-usage-report/