Skip to content

Instantly share code, notes, and snippets.

@rayterrill
Last active September 22, 2017 14:56
Show Gist options
  • Save rayterrill/a79b7d2eabb0ae1f778bfbdcad15e712 to your computer and use it in GitHub Desktop.
Save rayterrill/a79b7d2eabb0ae1f778bfbdcad15e712 to your computer and use it in GitHub Desktop.
Updates Slack and a CachetHQ Dashboard with Office365 Service Statuses
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