StatuspagePS.psm1
function Invoke-StatuspageRestMethod { [CmdletBinding()] param ( [parameter(Mandatory)] [string] $page, [hashtable] $body, [ValidateSet('Get', 'Post', 'Patch', 'Delete')] [string] $method = 'Get', [int] $retryCount = 15, [int] $retrySecDelay = 15 ) if ($script:statuspageUrl -eq $null) { throw 'Unknown Statuspage url (run Set-StatuspageUrl)' } if ($script:statuspageHeaders -eq $null) { throw 'Unknown Statuspage headers (run Set-StatuspageHeaders)' } [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::TLS12 $retryAttempt = 0 $jsonBody = $body | ConvertTo-Json $uri = "$script:statuspageUrl/$page" do { try { (Invoke-RestMethod -Uri $uri -Headers $script:statuspageHeaders -Body $jsonBody -Method $method -ErrorAction Stop) $done = $true } catch { $errorMessage = $_.ErrorDetails.Message | ConvertFrom-Json | Select-Object -ExpandProperty error Write-Verbose "$($MyInvocation.MyCommand): retryAttempt=$retryAttempt/$retryCount errorMessage='$errorMessage' uri=$uri method=$method body=$jsonBody" -Verbose if ($retryAttempt -lt $retryCount) { Start-Sleep -Seconds $retrySecDelay $retryAttempt++ } else { throw $_ } } } while (-not $done) } function Convert-StatuspageComponent { [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline)] [object] $object ) begin { $components = @() } process { $components += [PSCustomObject] @{ PSTypeName = 'statuspageComponent' id = $object.id pageId = $object.page_id groupId = $object.group_id createdAt = $object.created_at updatedAt = $object.updated_at group = $object.group name = $object.name description = $object.description position = $object.position status = $object.status showcase = $object.showcase onlyShowIfDegraded = $object.only_show_if_degraded automationEmail = $object.automation_email } } end { $components } } function Convert-StatuspageIncident { [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline)] [object] $object ) begin { $incidents = @() } process { $incidents += [PSCustomObject] @{ PSTypeName = 'statuspageIncident' id = $object.id name = $object.name status = $object.status createdAt = $object.created_at updatedAt = $object.updated_at monitoringAt = $object.monitoring_at resolvedAt = $object.resolved_at impact = $object.impact shortlink = $object.shortlink scheduledFor = $object.scheduled_for scheduledUntil = $object.scheduled_until scheduledRemindPrior = $object.scheduled_remind_prior scheduledRemindedAt = $object.scheduled_reminded_at impactOverride = $object.impact_override scheduledAutoInProgress = $object.scheduled_auto_in_progress scheduledAutoCompleted = $object.scheduled_auto_completed metadata = $object.metadata startedAt = $object.started_at pageId = $object.page_id incidentUpdates = $object.incident_updates postmortemBody = $object.postmortem_body postmortemBodyLastUpdatedAt = $object.postmortem_body_last_updated_at postmortemIgnored = $object.postmortem_ignored postmortemPublishedAt = $object.postmortem_published_at postmortemNotifiedSubscribers = $object.postmortem_notified_subscribers postmortemNotifiedTwitter = $object.postmortem_notified_twitter components = ($object.components | Convert-StatuspageComponent) } } end { $incidents } } function Set-StatuspageUrl { [CmdletBinding()] param ( [Parameter(Mandatory)] [string] $pageId ) $script:statuspageUrl = "https://api.statuspage.io/v1/pages/$pageId" } function Set-StatuspageHeaders { [CmdletBinding()] param ( [Parameter(Mandatory)] [string] $apiKey ) $script:statuspageHeaders = @{ 'Authorization' = "OAuth $apiKey" 'Content-Type' = 'application/json' } } function Get-StatuspageComponent { [CmdletBinding(DefaultParameterSetName = 'NoneParameterSetName')] param ( [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByName')] [string] $name, [Parameter(Mandatory, ParameterSetName = 'ById')] [string] $id, [int] $retryCount = 15, [int] $retrySecDelay = 15 ) begin { $components = Invoke-StatuspageRestMethod -page components -Method Get -retryCount $retryCount -retrySecDelay $retrySecDelay | Convert-StatuspageComponent } process { if ($name) { $component = $components | Where-Object { $_.name -eq $name } if ($component) { $component } else { throw "Cannot find component with name $name" } } elseif ($id) { $component = $components | Where-Object { $_.id -eq $id } if ($component) { $component } else { throw "Cannot find component with id $id" } } else { $components } } } function New-StatuspageComponent { [CmdletBinding()] param ( [parameter(Mandatory, ValueFromPipeline)] [string] $name, [int] $retryCount = 15, [int] $retrySecDelay = 15 ) process { $body = @{ component = @{ name = $name } } Invoke-StatuspageRestMethod -page components -Method Post -retryCount $retryCount -retrySecDelay $retrySecDelay -Body $body | Convert-StatuspageComponent } } function New-StatuspageComponentGroup { [CmdletBinding()] param ( [parameter(Mandatory, ParameterSetName = 'ByObject')] [parameter(Mandatory, ParameterSetName = 'ById')] [string] $name, [parameter(Mandatory, ParameterSetName = 'ByObject')] [PSTypeName('statuspageComponent')] $component, [parameter(Mandatory, ParameterSetName = 'ById')] [string[]] $componentId, [int] $retryCount = 15, [int] $retrySecDelay = 15 ) if ($PsCmdlet.ParameterSetName -eq 'ByObject') { $thisComponentId = $component.id } elseif ($PsCmdlet.ParameterSetName -eq 'ById') { $thisComponentId = $componentId } $body = @{ component_group = @{ name = $name components = $thisComponentId } } Invoke-StatuspageRestMethod -page component-groups -Method Post -retryCount $retryCount -retrySecDelay $retrySecDelay -Body $body | Convert-StatuspageComponent } function Update-StatuspageComponent { [CmdletBinding()] param ( [parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByObject')] [PSTypeName('statuspageComponent')] $component, [parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ById')] [string[]] $componentId, [parameter(Mandatory, ParameterSetName = 'ByObject')] [parameter(Mandatory, ParameterSetName = 'ById')] [ValidateSet('operational', 'major_outage', 'degraded_performance', 'partial_outage', 'under_maintenance')] [string] $status, [int] $retryCount = 15, [int] $retrySecDelay = 15 ) begin { $body = @{ component = @{ status = $status } } } process { if ($PsCmdlet.ParameterSetName -eq 'ByObject') { $thisComponentId = $component.id } elseif ($PsCmdlet.ParameterSetName -eq 'ById') { $thisComponentId = $componentId } Invoke-StatuspageRestMethod -page "components/$thisComponentId" -method Patch -retryCount $retryCount -retrySecDelay $retrySecDelay -body $body | Convert-StatuspageComponent } } function Remove-StatuspageComponent { [CmdletBinding()] param ( [parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByObject')] [PSTypeName('statuspageComponent')] $component, [parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ById')] [string] $componentId, [int] $retryCount = 15, [int] $retrySecDelay = 15 ) process { if ($PsCmdlet.ParameterSetName -eq 'ByObject') { $thisComponent = $component } elseif ($PsCmdlet.ParameterSetName -eq 'ById') { $thisComponent = Get-StatuspageComponent -id $componentId } if ($thisComponent.group -eq $false) { Invoke-StatuspageRestMethod -page "components/$($thisComponent.id)" -Method Delete -retryCount $retryCount -retrySecDelay $retrySecDelay } } } function Get-StatuspageIncident { [CmdletBinding(DefaultParameterSetName = 'NoneParameterSetName')] param ( [parameter(ValueFromPipeline, ParameterSetName = 'ByComponent')] [PSTypeName('statuspageComponent')] $component, [parameter(ParameterSetName = 'ByQuery')] [string] $query, [parameter(ParameterSetName = 'ByComponent')] [parameter(ParameterSetName = 'ByQuery')] [string] $status, [parameter(ParameterSetName = 'ByComponent')] [switch] $queryComponentName, [int] $retryCount = 15, [int] $retrySecDelay = 15 ) process { $page = 'incidents' if ($queryComponentName) { $page += "?q=$($component.name)" } elseif ($query) { $page += "?q=$query" } $incidents = Invoke-StatuspageRestMethod -page $page -Method Get -retryCount $retryCount -retrySecDelay $retrySecDelay | Convert-StatuspageIncident if ($component) { $incidents = $incidents | Where-Object { $_.components.id -eq $component.id } } if ($status) { $incidents | Where-Object { $_.status -eq $status } } else { $incidents } } } function New-StatuspageIncident { [CmdletBinding()] param ( [parameter(Mandatory, ParameterSetName = 'ByObject')] [parameter(Mandatory, ParameterSetName = 'ById')] [string] $name, [parameter(Mandatory, ParameterSetName = 'ByObject')] [parameter(Mandatory, ParameterSetName = 'ById')] [string] $body, [parameter(Mandatory, ParameterSetName = 'ByObject')] [parameter(Mandatory, ParameterSetName = 'ById')] [ValidateSet('investigating', 'identified', 'monitoring', 'resolved', 'scheduled', 'in_progress', 'verifying', 'completed', 'update')] [string] $status, [parameter(Mandatory, ParameterSetName = 'ByObject')] [PSTypeName('statuspageComponent')] $component, [parameter(Mandatory, ParameterSetName = 'ById')] [string[]] $componentId, [parameter(ParameterSetName = 'ByObject')] [parameter(ParameterSetName = 'ById')] [ValidateSet('operational', 'major_outage', 'degraded_performance', 'partial_outage', 'under_maintenance')] [string] $componentStatus, [parameter(ParameterSetName = 'ByObject')] [parameter(ParameterSetName = 'ById')] [dateTime] $scheduledFor, [parameter(ParameterSetName = 'ByObject')] [parameter(ParameterSetName = 'ById')] [dateTime] $scheduledUntil, [parameter(ParameterSetName = 'ByObject')] [parameter(ParameterSetName = 'ById')] [switch] $deliverNotifications, [parameter(ParameterSetName = 'ByObject')] [parameter(ParameterSetName = 'ById')] [switch] $scheduledRemindPrior, [parameter(ParameterSetName = 'ByObject')] [parameter(ParameterSetName = 'ById')] [switch] $scheduledAutoCompleted, [parameter(ParameterSetName = 'ByObject')] [parameter(ParameterSetName = 'ById')] [switch] $scheduledAutoInProgress, [int] $retryCount = 15, [int] $retrySecDelay = 15 ) if ($PsCmdlet.ParameterSetName -eq 'ByObject') { $thisComponentId = $component.id } elseif ($PsCmdlet.ParameterSetName -eq 'ById') { $thisComponentId = $componentId } $thisIncident = @{ name = $name body = $body status = $status component_ids = $thisComponentId } if ($componentStatus) { $thisIncident.components = $thisComponentId | ForEach-Object { @{ $_ = $componentStatus } } } if ($status -in 'in_progress', 'scheduled') { if ($scheduledFor -eq $null -or $scheduledUntil -eq $null) { throw "status=$status require parameters `$scheduledFor and `$scheduledUntil" } else { $thisIncident.scheduled_for = $scheduledFor | Get-Date -Format "yyyy-MM-dd'T'HH:mm:00.000'Z'" $thisIncident.scheduled_until = $scheduledUntil | Get-Date -Format "yyyy-MM-dd'T'HH:mm:00.000'Z'" } } $thisIncident.scheduled_remind_prior = $scheduledRemindPrior.IsPresent $thisIncident.scheduled_auto_completed = $scheduledAutoCompleted.IsPresent $thisIncident.scheduled_auto_in_progress = $scheduledAutoInProgress.IsPresent $thisIncident.deliver_notifications = $deliverNotifications.IsPresent Invoke-StatuspageRestMethod -page incidents -method Post -retryCount $retryCount -retrySecDelay $retrySecDelay -body @{ incident = $thisIncident } | Convert-StatuspageIncident } function Update-StatuspageIncident { [CmdletBinding()] param ( [parameter(Mandatory, ParameterSetName = 'ByObject')] [PSTypeName('statuspageIncident')] $incident, [parameter(Mandatory, ParameterSetName = 'ById')] [string] $incidentId, [parameter(Mandatory, ParameterSetName = 'ByObject')] [parameter(Mandatory, ParameterSetName = 'ById')] [string] $body, [parameter(Mandatory, ParameterSetName = 'ByObject')] [parameter(Mandatory, ParameterSetName = 'ById')] [ValidateSet('investigating', 'identified', 'monitoring', 'resolved', 'scheduled', 'in_progress', 'verifying', 'completed', 'update')] [string] $status, [parameter(Mandatory, ParameterSetName = 'ByObject')] [PSTypeName('statuspageComponent')] $component, [parameter(Mandatory, ParameterSetName = 'ById')] [string[]] $componentId, [parameter(ParameterSetName = 'ByObject')] [parameter(ParameterSetName = 'ById')] [ValidateSet('operational', 'major_outage', 'degraded_performance', 'partial_outage', 'under_maintenance')] [string] $componentStatus, [int] $retryCount = 15, [int] $retrySecDelay = 15 ) if ($PsCmdlet.ParameterSetName -eq 'ByObject') { $thisComponentId = $component.id $thisIncidentId = $incident.id } elseif ($PsCmdlet.ParameterSetName -eq 'ById') { $thisComponentId = $componentId $thisIncidentId = $incidentId } $thisIncident = @{ body = $body status = $status component_ids = $thisComponentId } if ($componentStatus) { $thisIncident.components = $thisComponentId | ForEach-Object { @{ $_ = $componentStatus } } } Invoke-StatuspageRestMethod -page "incidents/$thisIncidentId" -method Patch -retryCount $retryCount -retrySecDelay $retrySecDelay -body @{ incident = $thisIncident } | Convert-StatuspageIncident } function Remove-StatuspageIncident { [CmdletBinding()] param ( [parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByObject')] [PSTypeName('statuspageIncident')] $incident, [parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ById')] [string] $incidentId, [int] $retryCount = 15, [int] $retrySecDelay = 15 ) process { if ($PsCmdlet.ParameterSetName -eq 'ByObject') { $thisIncidentId = $incident.id } elseif ($PsCmdlet.ParameterSetName -eq 'ById') { $thisIncidentId = $incidentId } Invoke-StatuspageRestMethod -page "incidents/$thisIncidentId" -Method Delete -retryCount $retryCount -retrySecDelay $retrySecDelay | Convert-StatuspageIncident } } |