Last active
September 22, 2017 14:56
-
-
Save rayterrill/a79b7d2eabb0ae1f778bfbdcad15e712 to your computer and use it in GitHub Desktop.
Updates Slack and a CachetHQ Dashboard with Office365 Service Statuses
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
param( | |
[Parameter(Mandatory=$True)][System.Management.Automation.CredentialAttribute()]$cred, | |
[Parameter(Mandatory=$True)]$cachetToken, | |
[Parameter(Mandatory=$True)]$slackWebhookURL | |
) | |
$DebugPreference = 'Continue' | |
Import-Module O365ServiceCommunications | |
$cachetBaseURL = 'https://status.yourdomain.com' | |
$session = New-SCSession -Credential $cred -Local en-US | |
#statusID 1 = operational, 3 = partial outage | |
function Update-CachetStatus($appID, $statusID) { | |
$headers = @{} | |
$headers.Add("X-Cachet-Token",$cachetToken) | |
$statusJSON = '{ "status" : ' + $statusID + ' }' | |
$res = Invoke-WebRequest "$($cachetBaseURL)/api/v1/components/$($appID)" -UseBasicParsing -ContentType "application/json" -Method PUT -Body $statusJSON -Headers $headers | |
} | |
function Get-365SystemsInOutage() { | |
#get all open incidents | |
$outages = get-SCEvent -SCSession $session -EventTypes Incident | |
return $outages | |
} | |
function Get-AppIDfromName($name) { | |
#get the cachet app id for the item in outage | |
$urlencodeName = [uri]::EscapeDataString($name) | |
$url = "$($cachetBaseURL)/api/v1/components/?name=$($urlencodeName)" | |
$res = Invoke-WebRequest $url -UseBasicParsing | |
$data = $res.Content | ConvertFrom-JsonNewtonSoft | |
$appID = $data.data.id | |
return $appID | |
} | |
function Get-IncidentTitle($message) { | |
#use regex to find the title | |
$regexTitle = "^Title: (.+)" | |
$message -match $regexTitle | Out-Null | |
$outageTitle = $($Matches[0]) | |
return $outageTitle | |
} | |
function Get-IncidentUserimpact($message) { | |
#use regex to find the user impact | |
$regexUserImpact = "User Impact: (.+)" | |
$message -match $regexUserImpact | Out-Null | |
$outageUserImpact = $Matches[0] | |
return $outageUserImpact | |
} | |
function Update-Cachet($url, $json, $method) { | |
$headers = @{} | |
$headers.Add("X-Cachet-Token",'PPywmI0QUDiITJWc22Hg') | |
$res = Invoke-WebRequest $url -UseBasicParsing -ContentType "application/json" -Method $method -Body $json -Headers $headers | |
} | |
function Update-SystemsWithIssues() { | |
Write-Debug "----- Update-SystemsWithIssues -----" | |
$outages = Get-365SystemsInOutage | |
#get the existing incidents | |
$incidents = Invoke-WebRequest "$($cachetBaseURL)/api/v1/incidents" -UseBasicParsing | |
$incidentData = ($incidents.Content | ConvertFrom-JsonNewtonSoft).data | |
foreach ($o in $outages) { | |
$incidentID = $o.ID | |
$matchingIncident = $incidentData | Where-Object {$_.Name -Like "$($incidentID)*"} | |
#get appid from the outage | |
$appID = Get-AppIDfromName -Name $o.affectedservicehealthstatus.servicename | |
#get the last message from the outage | |
$lastMessage = $o.messages.length-1 | |
$incidentTitle = Get-IncidentTitle -Message $o.messages[$lastMessage].messagetext | |
$incidentFinalTitle = "$($o.ID) - $($incidentTitle)" | |
$incidentUserImpact = Get-IncidentUserimpact -Message $o.messages[$lastMessage].messagetext | |
if (-not $o.EndTime) { | |
#outage is still going on | |
if ($matchingIncident) { | |
#see if the title and user impact match - if they don't, we need to update our incident | |
if ($matchingIncident.name -eq $incidentFinalTitle -AND $matchingIncident.message -eq $incidentUserImpact) { | |
Write-Debug "$($o.ID) - Incident title and user impact is the same. Not updating..." | |
} else { | |
Write-Debug "$($o.ID) - Updating incident title and user impact..." | |
$JSON = '{ "status" : 2, "name" : "' + $incidentFinalTitle + '", "message" : "' + $incidentUserImpact + '", "visible" : 1, "component_id" : ' + $appID + ', "component_status" : 3 }' | |
Update-Cachet -URL "$($cachetBaseURL)/api/v1/incidents/$($matchingIncident.ID)" -Json $JSON -Method Put | |
} | |
} else { | |
Write-Debug "$($o.ID) - Incident does not exist. Needs to be created." | |
$JSON = '{ "status" : 2, "name" : "' + $incidentFinalTitle + '", "message" : "' + $incidentUserImpact + '", "visible" : 1, "component_id" : ' + $appID + ', "component_status" : 3 }' | |
Update-Cachet -URL "$($cachetBaseURL)/api/v1/incidents" -Json $JSON -Method Post | |
#update Slack | |
$body = @{ text = "$($o.affectedservicehealthstatus.servicename) has transitioned to Partial Outage." } | |
Invoke-WebRequest -Method Post -Body (ConvertTo-Json $body) -Uri $slackWebhookURL -UseBasicParsing | |
} | |
} else { | |
#outage has ended | |
if ($matchingIncident) { | |
Write-Debug "$($o.ID) - Incident exists and is over. Check to see if it needs to be updated to close the incident" | |
if ($matchingIncident.name -eq $incidentFinalTitle -AND $matchingIncident.message -eq $incidentUserImpact -AND $matchingIncident.status -eq '4') { | |
Write-Debug "--- Incident is already updated. Not updating." | |
} else { | |
Write-Debug "--- Updating status..." | |
$JSON = '{ "status" : 4, "name" : "' + $incidentFinalTitle + '", "message" : "' + $incidentUserImpact + '", "visible" : 1, "component_id" : ' + $appID + ', "component_status" : 1 }' | |
Update-Cachet -URL "$($cachetBaseURL)/api/v1/incidents/$($matchingIncident.ID)" -Json $JSON -Method Put | |
#update Slack | |
$body = @{ text = "$($o.affectedservicehealthstatus.servicename) has transitioned from Partial Outage to Operational." } | |
Invoke-WebRequest -Method Post -Body (ConvertTo-Json $body) -Uri $slackWebhookURL -UseBasicParsing | |
} | |
} | |
} | |
} | |
} | |
Update-SystemsWithIssues |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment