Public/usage.ps1
|
function Get-CSUsageType { <# .SYNOPSIS Lists the usage record types. .DESCRIPTION Wraps listUsageTypes. Each type's ID is what Get-CSUsageRecord -Type takes; pipe a type straight into Get-CSUsageRecord to filter by it. .EXAMPLE Get-CSUsageType Lists every usage type with its ID and description. .EXAMPLE Get-CSUsageType | Where-Object description -match 'Running VM' | Get-CSUsageRecord -StartDate '2026-09-01' -EndDate '2026-09-30' Gets September's running-VM usage records. #> [CmdletBinding()] param() ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listUsageTypes' -Parameters @{}) -Command 'listUsageTypes' } function Get-CSUsageRecord { <# .SYNOPSIS Lists usage records for a date range. .DESCRIPTION Wraps listUsageRecords (requires the usage server). -StartDate and -EndDate take either a string, passed to CloudStack unchanged, or a DateTime: - A date-only string follows CloudStack's rules: '2026-09-30' as an end date means the end of that day, as a start date the beginning. - A DateTime is sent with its UTC offset, so (Get-Date).AddDays(-7) means exactly that moment regardless of the server's time zone. Accepts usage type objects from Get-CSUsageType on the pipeline. .PARAMETER StartDate Start of the period: a string such as '2026-09-01' or '2026-09-01 08:00:00', or a DateTime .PARAMETER EndDate End of the period: a string such as '2026-09-30', or a DateTime .PARAMETER Type Only records of this usage type ID (see Get-CSUsageType). Binds from a piped usage type's id. .PARAMETER UsageId Only records for this resource UUID. Must be used with -Type. .PARAMETER Account Filter by account name .PARAMETER AccountId Filter by account ID .PARAMETER DomainId Filter by domain ID .PARAMETER ProjectId Filter by project ID .PARAMETER IsRecursive With -DomainId, include records from subdomains .PARAMETER IncludeTags Include each resource's tags in the records .PARAMETER OldFormat Put internal database IDs in the description instead of UUIDs .PARAMETER Keyword Filter by keyword .PARAMETER Page Page number of results to return .PARAMETER PageSize Number of results per page .EXAMPLE Get-CSUsageRecord -StartDate '2026-09-01' -EndDate '2026-09-30' -Account 'engineering' -DomainId domain-uuid Gets one account's usage for September. .EXAMPLE Get-CSUsageRecord -StartDate (Get-Date).AddDays(-1) -EndDate (Get-Date) -Type 1 | Group-Object account | Select-Object Name, @{ n = 'Hours'; e = { ($_.Group | Measure-Object rawusage -Sum).Sum } } Totals the last 24 hours of running-VM hours (usage type 1) per account. .EXAMPLE Get-CSUsageRecord -StartDate '2026-09-01' -EndDate '2026-09-30' -Type 6 -UsageId vol-uuid Gets September's usage records for one volume (usage type 6). #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [object]$StartDate, [Parameter(Mandatory = $true)] [object]$EndDate, [Parameter(ValueFromPipelineByPropertyName = $true)] [Alias('Id', 'UsageTypeId')] [int]$Type, [string]$UsageId, [string]$Account, [string]$AccountId, [string]$DomainId, [string]$ProjectId, [switch]$IsRecursive, [switch]$IncludeTags, [switch]$OldFormat, [string]$Keyword, [int]$Page, [int]$PageSize ) process { if ($PSBoundParameters.ContainsKey('UsageId') -and -not $PSBoundParameters.ContainsKey('Type')) { throw 'UsageId can only be used together with -Type.' } $apiParams = @{ startdate = ConvertTo-CSDateParameter -Value $StartDate enddate = ConvertTo-CSDateParameter -Value $EndDate } Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{ Type = 'type'; UsageId = 'usageid'; Account = 'account'; AccountId = 'accountid'; DomainId = 'domainid' ProjectId = 'projectid'; IsRecursive = 'isrecursive'; IncludeTags = 'includetags'; OldFormat = 'oldformat' Keyword = 'keyword'; Page = 'page'; PageSize = 'pagesize' }) ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listUsageRecords' -Parameters $apiParams) -Command 'listUsageRecords' } } function Update-CSUsageRecord { <# .SYNOPSIS Generates usage records the scheduled usage job missed. .DESCRIPTION Wraps generateUsageRecords. CloudStack only generates records for periods where the scheduled usage job did not run or failed, so re-running this for a period that is already complete does nothing. Dates are whole days; a DateTime is sent as its date (yyyy-MM-dd). .PARAMETER StartDate First day to generate records for: a 'yyyy-MM-dd' string or a DateTime .PARAMETER EndDate Last day to generate records for: a 'yyyy-MM-dd' string or a DateTime .PARAMETER DomainId Only generate records for this domain .EXAMPLE Update-CSUsageRecord -StartDate '2026-09-01' -EndDate '2026-09-30' Fills in any usage records missing for September. .EXAMPLE Update-CSUsageRecord -StartDate (Get-Date).AddDays(-2) -EndDate (Get-Date).AddDays(-1) Catches up after the usage server was down for the last two days. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] param( [object]$StartDate, [object]$EndDate, [string]$DomainId ) $apiParams = @{} if ($PSBoundParameters.ContainsKey('StartDate')) { $apiParams['startdate'] = ConvertTo-CSDateParameter -Value $StartDate -Format 'yyyy-MM-dd' } if ($PSBoundParameters.ContainsKey('EndDate')) { $apiParams['enddate'] = ConvertTo-CSDateParameter -Value $EndDate -Format 'yyyy-MM-dd' } if ($PSBoundParameters.ContainsKey('DomainId')) { $apiParams['domainid'] = $DomainId } $period = if ($apiParams.startdate -or $apiParams.enddate) { "$($apiParams.startdate) to $($apiParams.enddate)" } else { 'all pending periods' } if ($PSCmdlet.ShouldProcess("usage records ($period)", 'Generate')) { ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'generateUsageRecords' -Parameters $apiParams) -Command 'generateUsageRecords' } } function Remove-CSRawUsageRecord { <# .SYNOPSIS Purges old raw usage records from the usage database. .DESCRIPTION Wraps removeRawUsageRecords, which deletes raw records older than -Interval days from the cloud_usage database to keep it small. Aggregated usage records already generated from them are kept, but the raw data cannot be reprocessed afterwards. .PARAMETER Interval Delete raw records older than this many days (must be greater than 0) .EXAMPLE Remove-CSRawUsageRecord -Interval 90 Deletes raw usage records older than 90 days after prompting for confirmation. .EXAMPLE Remove-CSRawUsageRecord -Interval 365 -WhatIf Shows what purging raw records older than a year would do, without doing it. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] param( [Parameter(Mandatory = $true)] [ValidateRange(1, [int]::MaxValue)] [int]$Interval ) if ($PSCmdlet.ShouldProcess("raw usage records older than $Interval days", 'Delete')) { ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'removeRawUsageRecords' -Parameters @{ interval = $Interval }) -Command 'removeRawUsageRecords' } } |