Public/Get-PagerArchiveMessage.ps1
|
function Get-PagerArchiveMessage { <# .SYNOPSIS Searches messages, newest first. .DESCRIPTION Returns messages with what the detail view shows (R63a): the full text, priority, sent time, capcode, alias, agency, group, job number, event category, parsed fields, location, flags and each client's receive time. Filters combine (R33): a message must match every filter given, and a filter given several values matches any of them. Pages to ignored aliases are left out unless -IncludeIgnored is given (R27). With no filter it returns every message. Messages are fetched a page at a time, only as the pipeline asks for more, so -First 10 or Select-Object -First 10 stops after the first page. -Skip leaves out the newest matches first. There's no -IncludeTotalCount: count with Measure-Object or @(...).Count. Aliases and capcodes piped in are combined into one search. .EXAMPLE Get-PagerArchiveMessage -Capcode 0100001 -Priority Emergency SentAt Priority Alias Text ------ -------- ----- ---- 20/10/2026 9:14:03 am Emergency Station 1 EX0000031 HSF1 SHED FIRE @ 3 FICTION ST, MADEUPTON #TV1 The table shows SentAt in your time zone; the object's SentAt is the [datetimeoffset] the server sent. .EXAMPLE Get-PagerArchiveMessage -First 1 | Format-List Shows what the browser's detail view shows: the full text, the parsed fields, the location, the flags and each client's receive time, with times in your time zone. .EXAMPLE Get-PagerArchiveAlias -Name 'Station*' | Get-PagerArchiveMessage -After (Get-Date).AddDays(-7) .EXAMPLE Get-PagerArchiveMessage -Text 'SHED FIRE' -First 20 | Export-Csv -Path fires.csv .EXAMPLE '0100001', '0100002' | ForEach-Object -Process { [pscustomobject]@{ Capcode = $_ } } | Get-PagerArchiveMessage -First 10 Capcodes piped in as objects with a Capcode property. .EXAMPLE Get-PagerArchiveMessage -Unaliased -After (Get-Date).AddDays(-1) | Group-Object -Property Capcode Capcodes with no alias that paged in the last day. .EXAMPLE Get-PagerArchiveMessage -Capcode 0100001 -Skip 20 -First 20 The second 20 messages to one capcode, newest first. .EXAMPLE (Get-PagerArchiveMessage -JobNumber EX0000031 | Measure-Object).Count How many messages a job has. .INPUTS System.Management.Automation.PSObject. Objects with a Capcode property (such as PagerArchive.Message), or with a Name property (such as PagerArchive.Alias), whose value is taken as an alias name. .OUTPUTS PagerArchive.Message. Id, SentAt, Capcode, Alias, Agency, Priority (Emergency, Non-emergency, Admin or None), Text (as a pager shows it, in full), RawText (as received, with the priority marker), Group, JobNumber, EventType, Category, Description, Address, Locality, GridRef, Units, Fields (other parsed fields), Location (Longitude, Latitude, Approximate, Source), ParseFailed, AddressUnsplit, LocationMismatch, Heartbeat, Ignored and Receptions (Client, ReceivedAt). .LINK Get-PagerArchiveAlias .LINK about_PagerArchive #> [CmdletBinding()] [OutputType('PagerArchive.Message')] param( # Text the message, or one of its parsed fields, contains # (case-insensitive). Default: any. No wildcards. [Parameter(Position = 0)] [ValidateNotNullOrEmpty()] [string] $Text, # Capcodes (1 to 7 digits). Default: any. No wildcards. [Parameter(ValueFromPipelineByPropertyName)] [ValidatePattern('^[0-9]{1,7}$')] [string[]] $Capcode, # Alias names. Accepts wildcards, matched case-insensitively; a name # without wildcards matches exactly. Default: any. [Parameter(ValueFromPipelineByPropertyName)] [Alias('Name')] [SupportsWildcards()] [ValidateNotNullOrEmpty()] [string[]] $Alias, # Agency names. Accepts wildcards, matched case-insensitively. # Default: any. [SupportsWildcards()] [ValidateNotNullOrEmpty()] [string[]] $Agency, # Paging groups. Accepts wildcards, matched case-insensitively. # Default: any. [SupportsWildcards()] [ValidateNotNullOrEmpty()] [string[]] $Group, # Priorities. Default: any. [ValidateSet('Emergency', 'Non-emergency', 'Admin', 'None')] [string[]] $Priority, # Event categories, as the network profile names them, or Other. # Default: any. No wildcards. [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete) $null = $commandName, $parameterName try { (Invoke-PaApi -Method GET -Path '/api/v1/meta').categories | Where-Object -FilterScript { $_ -like "$wordToComplete*" } | ForEach-Object -Process { [System.Management.Automation.CompletionResult]::new("'$_'", $_, 'ParameterValue', $_) } } catch { $null = $_ } })] [ValidateNotNullOrEmpty()] [string[]] $Category, # Job numbers. Default: any. No wildcards. [ValidateNotNullOrEmpty()] [string[]] $JobNumber, # Only messages sent at or after this time. Default: no limit. [datetimeoffset] $After, # Only messages sent before this time. Default: no limit. [datetimeoffset] $Before, # Only messages to capcodes with no alias. Off by default. [switch] $Unaliased, # Include pages to ignored aliases. Off by default. [switch] $IncludeIgnored, # Only messages with any of these flags. Default: any. [ValidateSet('ParseFailed', 'AddressUnsplit', 'LocationMismatch')] [string[]] $Flag, # Returns only this many messages, fetching no more pages than that # needs. Default: every message. [PSDefaultValue(Help = 'every message')] [uint64] $First, # Leaves out this many matching messages, newest first, before # returning any. Default: none. [PSDefaultValue(Help = 'none')] [uint64] $Skip ) begin { $capcodes = [System.Collections.Generic.List[string]]::new() $aliases = [System.Collections.Generic.List[string]]::new() } process { foreach ($c in $Capcode) { $capcodes.Add($c) } foreach ($a in $Alias) { $aliases.Add($a) } } end { # Every piped alias and capcode, in one search (A55). $filter = @{ Text = $Text Capcode = @($capcodes) Alias = @($aliases) Agency = $Agency Group = $Group Priority = $Priority Category = $Category JobNumber = $JobNumber Unaliased = $Unaliased IncludeIgnored = $IncludeIgnored Flag = $Flag } $filter = New-PaMessageFilter @filter $check = $filter.Check $query = $filter.Query $query.from = if ($PSBoundParameters.ContainsKey('After')) { $After.ToString('o') } else { $null } $query.to = if ($PSBoundParameters.ContainsKey('Before')) { $Before.ToString('o') } else { $null } $query.receptions = 'true' $query.limit = 200 $query.before = $null # Our own -First and -Skip, not SupportsPaging, so there's no # -IncludeTotalCount (guidelines section 3). $first = if ($PSBoundParameters.ContainsKey('First')) { $First } else { [uint64]::MaxValue } $skip = $Skip $written = [uint64]0 $seen = [uint64]0 try { while ($written -lt $first) { $wanted = ([double]$first - $written) + [math]::Max(0, [double]$skip - $seen) $query.limit = [int][math]::Min(200.0, [math]::Max(1.0, $wanted)) $page = Invoke-PaApi -Method GET -Path '/api/v1/messages' -Query $query foreach ($row in $page.messages) { $message = ConvertTo-PaMessage -Row $row if (-not (Test-PaMessageFilter -Message $message -Check $check)) { continue } $seen++ if ($seen -le $skip) { continue } $message $written++ if ($written -ge $first) { break } } if (-not $page.PSObject.Properties['next'] -or -not $page.next) { break } $query.before = $page.next } } catch { $PSCmdlet.ThrowTerminatingError((Copy-PaErrorRecord -ErrorRecord $_)) } } } |