Statusimo.psm1
function Get-StatusimoData { [cmdletbinding()] param( [string] $FolderPath ) if ($FolderPath -ne '' -and (Test-Path -LiteralPath $FolderPath)) { $Files = Get-ChildItem -LiteralPath $FolderPath foreach ($File in $Files) { $Output = Get-Content -LiteralPath $File.FullName -Raw | ConvertFrom-Json $Output | Add-Member -Name 'FullName' -Value $File.FullName -MemberType NoteProperty -Force $Output } } } function New-StatusimoEvent { [alias('New-StatusimoIncident')] [cmdletbinding()] param( [DateTime] $Date = (Get-Date), [string] $Service, [ValidateSet('Operational', 'Partial Degradation', 'Down')][string] $Status, [string] $Title, [string] $Overview, [alias('IncidentsPath', 'EventsPath')][string] $FolderPath ) $FileNameService = $Service -replace '[^a-zA-Z]', '_' $FileNameData = $Date.ToString("yyyy-MM-dd_HH_MM_ss") $FileNameEnd = Get-FileName -Extension 'json' -TemporaryFileOnly $FileName = $FileNameService + '_' + $FileNameData + '_' + $FileNameEnd $FilePath = [IO.Path]::Combine($FolderPath, $FileName) if ($Maintenance) { } else { $Incident = [ordered] @{ Date = $Date Service = $Service Status = $Status Title = $Title Overview = $Overview } $Output = $Incident | ConvertTo-Json $Output | Set-Content -LiteralPath $FilePath } } function New-StatusimoMaintenance { [cmdletbinding()] param( [DateTime] $DateStart, [DateTime] $DateEnd, [string] $Service, [ValidateSet('Operational', 'Partial Degradation', 'Down')][string] $Status, [string] $Title, [string] $Overview, [string] $FolderPath ) $FileNameService = $Service -replace '[^a-zA-Z]', '_' $FileNameData = $DateStart.ToString("yyyy-MM-dd_HH_MM_ss") $FileNameEnd = Get-FileName -Extension 'json' -TemporaryFileOnly $FileName = $FileNameService + '_' + $FileNameData + '_' + $FileNameEnd $FilePath = [IO.Path]::Combine($FolderPath, $FileName) $Maintenance = [ordered] @{ DateStart = $DateStart DateEnd = $DateEnd Service = $Service Status = $Status Title = $Title Overview = $Overview } $Output = $Maintenance | ConvertTo-Json $Output | Set-Content -LiteralPath $FilePath } function New-StatusimoPage { [cmdletbinding()] param( [string] $FilePath, [alias('Incident', 'Incidents', 'IncidentPath')][string] $IncidentsPath, [alias('Maintenance', 'MaintenancePath')][string] $MaintenancesPath ) $DynamicHTML = New-HTML -TitleText 'Services Status' ` -HideLogos:$true ` -UseCssLinks:$true ` -UseStyleLinks:$true { $Today = Get-Date $Incidents = Get-StatusimoData -FolderPath $IncidentsPath | Sort-Object -Property Date, Title -Descending $Maintenances = Get-StatusimoData -FolderPath $MaintenancesPath | Sort-Object -Property DateEnd, DateStart, Title -Descending $IncidentTypes = $Incidents.Service | Sort-Object -Unique New-HTMLColumn -Invisible { $Statuses = foreach ($Type in $IncidentTypes) { $Incidents | Where-Object { $_.Service -eq $Type } | Select-Object -First 1 -ExpandProperty Status } if ($Statuses -notcontains 'Partial Degradation' -and $Statuses -notcontains 'Down') { New-HTMLToast -Icon Information -Color Blue -TextHeader 'Information' -Text 'Everything is running smoothly!' } else { New-HTMLToast -Icon Exclamation -Color Orange -TextHeader 'Warning' -Text "Some systems are affected. We're hard at work fixing." } } New-HTMLHeading -Heading h1 -HeadingText 'Current Status' -Type 'central' New-HTMLColumn -Columns 1 -Invisible { New-HTMLStatus { foreach ($Type in $IncidentTypes) { $IncidentStatus = $Incidents | Where-Object { $_.Service -eq $Type } | Select-Object -First 1 if ($IncidentStatus.Status -eq 'Operational') { $Icon = 'Good' $Percentage = '100%' } elseif ($IncidentStatus.Status -eq 'Partial Degradation') { $Icon = 'Bad' $Percentage = '30%' } elseif ($IncidentStatus.Status -eq 'Down') { $Icon = 'Dead' $Percentage = '0%' } New-HTMLStatusItem -ServiceName $IncidentStatus.Service -ServiceStatus $IncidentStatus.Status -Icon $Icon -Percentage $Percentage } } } New-HTMLHeading -Heading h1 -HeadingText 'Scheduled Maintenance' -Type 'central' New-HTMLColumn -Invisible { foreach ($Maintenance in $Maintenances) { $Title = "$($Maintenance.Title) ($($Maintenance.DateStart) - $($Maintenance.DateEnd))" if ($Today -ge $Maintenance.DateStart -and $Today -le $Maintenance.DateEnd) { New-HTMLToast -Icon Exclamation -Color Orange -TextHeader $Title -Text $Maintenance.Overview } elseif ($Today -le $Maintenance.DateStart) { New-HTMLToast -Icon Information -Color Blue -TextHeader $Title -Text $Maintenance.Overview } else { New-HTMLToast -Icon Success -Color Green -TextHeader $Title -Text $Maintenance.Overview } } } New-HTMLHeading -Heading h1 -HeadingText 'Incidents per day' -Type 'central' New-HTMLColumn -Columns 1 -Invisible { $Data = foreach ($Element in 30..0) { $Date = (Get-Date).AddDays(-$Element).Date $IncidentsPerDay = $Incidents | Where-Object { ($_.Status -eq 'Partial Degradation' -or $_.Status -eq 'Down') -and $_.Date.Date -eq $Date } Get-ObjectCount -Object $IncidentsPerDay } $DataName = "Incidents" $DataCategories = foreach ($Element in 30..0) { (Get-Date).AddDays(-$Element).ToShortDateString() } New-HTMLChart ` -Data $Data ` -DataNames $DataName ` -DataCategories $DataCategories ` -Type 'line' ` -TitleText '' ` -TitleAlignment 'left' ` -LineColor 'Blue' -Horizontal $false -Positioning central } New-HTMLHeading -Heading h1 -HeadingText 'Timeline' -Type 'central' New-HTMLColumn -Columns 1 -Invisible { New-HTMLTimeline { foreach ($Incident in $Incidents) { New-HTMLTimelineItem -HeadingText $Incident.Title -Text $Incident.Overview -Date $Incident.Date } } } } [string] $DynamicHTMLPath = Save-HTML -HTML $DynamicHTML -FilePath $FilePath } function Remove-StatusimoMaintenance { [cmdletbinding()] param( [alias('Maintenance', 'MaintenancePath')][string] $MaintenancesPath, [int] $DaysOld ) $DateOld = (Get-Date).AddDays($DaysOld) $Maintenances = Get-StatusimoData -FolderPath $MaintenancesPath | Where-Object { $_.DateEnd -lt $DateOld } foreach ($Maintenance in $Maintenances) { Remove-Item -LiteralPath $Maintenance.FullName -Confirm:$false } } Export-ModuleMember ` -Function @('New-StatusimoEvent','New-StatusimoMaintenance','New-StatusimoPage','Remove-StatusimoMaintenance') ` -Alias @('New-StatusimoIncident') |