Public/Get-SonarrUpcomingEpisodes.ps1
|
function Get-SonarrUpcomingEpisodes { <# .SYNOPSIS Retrieves upcoming episodes from the Sonarr calendar. .DESCRIPTION Queries the Sonarr calendar endpoint (GET /api/v3/calendar) and returns the episodes airing between StartDate and EndDate. Dates are converted to UTC and sent in ISO 8601 format with milliseconds (yyyy-MM-ddTHH:mm:ss.fffZ), which is what the Sonarr calendar endpoint expects. .PARAMETER StartDate The start of the period to query. Defaults to the current date and time. .PARAMETER EndDate The end of the period to query. Defaults to the current date and time plus 7 days. .PARAMETER IncludeUnmonitored Include episodes of series/seasons that are not monitored. By default only monitored episodes are returned (unmonitored=false). .EXAMPLE Get-SonarrUpcomingEpisodes Returns monitored episodes airing in the next 7 days. .EXAMPLE Get-SonarrUpcomingEpisodes -StartDate (Get-Date).Date -EndDate (Get-Date).Date.AddMonths(1) Returns monitored episodes airing between midnight today and the same time next month. .EXAMPLE Get-SonarrUpcomingEpisodes -EndDate (Get-Date).AddDays(30) -IncludeUnmonitored Returns all episodes airing in the next 30 days, including unmonitored ones. .EXAMPLE Get-SonarrUpcomingEpisodes | Select-Object airDate, seriesTitle, seasonNumber, episodeNumber, title | Sort-Object airDate Returns the next 7 days as a readable schedule including the name of each series. .NOTES By default the calendar endpoint returns episode objects only; they identify the series by seriesId, not by name. #> [CmdletBinding()] param( [Parameter(Mandatory = $false)] [DateTime]$StartDate = (Get-Date), [Parameter(Mandatory = $false)] [DateTime]$EndDate = (Get-Date).AddDays(7), [Parameter(Mandatory = $false)] [Switch]$IncludeUnmonitored ) #################################################################################################### #Region Import configuration try { Import-Configuration -ErrorAction Stop } catch { throw $_ } #EndRegion #################################################################################################### #Region Validate the date range if($EndDate -lt $StartDate) { throw "EndDate ($EndDate) must not be earlier than StartDate ($StartDate)." } #EndRegion #################################################################################################### #Region Define the parameters try { # Sonarr expects UTC timestamps in the form 2026-06-27T23:00:00.000Z. InvariantCulture is used # to guarantee the ':' time separator regardless of the culture of the calling session. $Format = 'yyyy-MM-ddTHH:mm:ss.fffZ' $Culture = [System.Globalization.CultureInfo]::InvariantCulture $Params = @{ start = $StartDate.ToUniversalTime().ToString($Format, $Culture) end = $EndDate.ToUniversalTime().ToString($Format, $Culture) includeSeries = 'true' unmonitored = 'false' } if($IncludeUnmonitored) { $Params['unmonitored'] = 'true' } } catch { throw $_ } #EndRegion #################################################################################################### #Region make the main request try { $Data = Invoke-SonarrRequest -Path '/calendar' -Method GET -Params $Params -ErrorAction Stop if($Data) { # Surface the title as a flat property and drop the embedded series object, which is # ~1.5KB per episode and makes the output unwieldy to read. $Data = $Data | Select-Object -Property @{ Name = 'seriesTitle'; Expression = { $_.series.title } }, * -ExcludeProperty series return $Data } else { Write-Verbose -Message 'No upcoming episodes found in the specified period.' return } } catch { throw $_ } #EndRegion } |