Public/Get-CitrixAppUsagePeak.ps1
<#
.SYNOPSIS Retrieves peak application usage data from a Citrix Delivery Controller using the OData API. .DESCRIPTION The Get-CitrixAppUsagePeak function queries application activity data from a specified Citrix Delivery Controller. It analyzes the peak concurrent usage per application within a defined date range and returns the highest usage count along with the corresponding date. The function uses Citrix Monitor OData endpoints for `ApplicationActivitySummaries` and `Applications`, and maps application IDs to their published names. The results are grouped, analyzed, and returned sorted by peak usage in descending order. .PARAMETER DeliveryController The name or FQDN of the Citrix Delivery Controller to query. This parameter is mandatory. .PARAMETER StartDate The beginning date of the range to analyze application activity. Defaults to 30 days prior to today. .PARAMETER EndDate The end date of the range to analyze application activity. Defaults to today. .EXAMPLE # Run a default usage analysis for the past 30 days Get-CitrixAppUsagePeak -DeliveryController "ddc001" .EXAMPLE # Analyze usage data for a specific month Get-CitrixAppUsagePeak -DeliveryController "ddc001" -StartDate "2025-03-01" -EndDate "2025-03-31" .NOTES Requires access to the Citrix Monitor OData v3 API with appropriate permissions. Uses default credentials for authentication. #> function Get-CitrixAppUsagePeak { [CmdletBinding()] [OutputType('PSCustomObject')] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [string]$DeliveryController, [Parameter()] [DateTime]$StartDate = (Get-Date).AddDays(-30).Date, [Parameter()] [DateTime]$EndDate = (Get-Date).Date ) # Helper function for REST queries function Invoke-CitrixODataQuery { param ($Uri) try { return Invoke-RestMethod -Uri $Uri -UseDefaultCredentials -ErrorAction Stop } catch { Write-LogEntry -Message "Failed to retrieve: $Uri" return $null } } $baseUri = "http://$DeliveryController/Citrix/Monitor/OData/v3/Data" $dateFilter = "`$filter=(SummaryDate ge DateTime'$($StartDate.ToString("s"))') and (SummaryDate le DateTime'$($EndDate.ToString("s"))')" # REST URIs $activityUri = "$baseUri/ApplicationActivitySummaries?`$format=json&$dateFilter" $appsUri = "$baseUri/Applications?`$format=json&`$select=Id,PublishedName" # Fetch data $activityData = Invoke-CitrixODataQuery -Uri $activityUri $appsData = Invoke-CitrixODataQuery -Uri $appsUri if (-not $activityData -or -not $appsData) { Write-LogEntry -Message "No data retrieved from $DeliveryController" return } # Map ApplicationId -> PublishedName using a hashtable for fast lookup $appLookup = @{} foreach ($app in $appsData.value) { $appLookup[$app.Id] = $app.PublishedName } $deployedState = if ($DeliveryController -match "VAUS") { "DR" } else { "Prod" } # Process and group results $result = $activityData.value | ForEach-Object { [PSCustomObject]@{ AppName = $appLookup[$_.ApplicationId] ModifiedDate = (Get-Date $_.ModifiedDate -Format 'MM/dd/yyyy') PeakConcurrentInstanceCount = $_.PeakConcurrentInstanceCount } } | Group-Object AppName | ForEach-Object { $maxPeak = ($_.Group | Measure-Object -Property PeakConcurrentInstanceCount -Maximum).Maximum $maxDate = ($_.Group | Where-Object { $_.PeakConcurrentInstanceCount -eq $maxPeak } | Select-Object -ExpandProperty ModifiedDate -First 1) [PSCustomObject]@{ AppName = $_.Name MaxPeakConcurrent = $maxPeak DateForMaxPeakConcurrent = $maxDate Deployed = $deployedState } } return $result | Sort-Object -Property MaxPeakConcurrent -Descending } |