Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@wightsci
Last active February 22, 2020 17:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wightsci/31ba6213c905bfdff92f106416301098 to your computer and use it in GitHub Desktop.
Save wightsci/31ba6213c905bfdff92f106416301098 to your computer and use it in GitHub Desktop.
<#
.SYNOPSIS
Creates an HTML report of the state of Windows Services.
.DESCRIPTION
Creates an HTML report of the state of Windows Services. Styles services in
unexpected states.
.PARAMETER ReportFile
The report file to create.
.PARAMETER Title
The Title for the report.
.PARAMETER View
Determines whether the report is displayed in a browser.
.EXAMPLE
ServiceReport.ps1 -ReportFile ServiceReport.html
This is the simplest use of the script, creating a report file ServiceReport.html .
.EXAMPLE
ServiceReport.ps1 -ReportFile ServiceReport.html -Title 'Services Report'
In this example text for the title and H1 tag of the report is provided.
.EXAMPLE
ServiceReport.ps1 -ReportFile ServiceReport.html -Title 'Services Report' -View
This is the same as the previous example, except that the report file is launched in
the default HTML viewer, most likely a web browser.
.NOTES
The report includes a count of the number of services for each StartType, navigation
from StartType to StartType and a timestamp indicating when the script was run.
.INPUTS
None. The script does not accept data on the pipeline.
.OUTPUTS
HTML Report file. The script does not output data to the pipeline.
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True)]
[string]$ReportFile,
[string]$Title = "Service Status Report",
[switch]$View
)
# Get service information
$services = Get-Service | Group-Object -Property StartType -AsHashTable -AsString
# Remove existing report file, if present
if (Test-Path $ReportFile) {
Remove-Item $ReportFile
}
# CSS style
$style = @"
<style>
body {
font-family: 'Segoe Ui',Arial, Helvetica, sans-serif
}
table {
table-layout: fixed;
width: 100%;
white-space: nowrap;
}
/* Column widths are based on these cells */
.col-ServiceName {
width: 20%;
}
.col-DisplayName {
width: 70%;
}
.col-Status {
width: 10%;
}
td {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
th {
background: darkblue;
color: white;
}
td, th {
text-align: left;
padding: 5px 10px;
}
tr:nth-child(even) {
background: lightblue;
}
.back-red {
background-color: red;
color: white
}
.back-green {
background-color: darkgreen;
color: white;
}
.nav {
padding-bottom: 5pt;
font-size: small;
}
</style>
"@
# Start HTML body
$body = $style
$body += "<h1>$title</h1>"
$body += "<div>Run at: $((Get-Date).toString('yyyy-MM-dd HH:mm:ss'))</div>"
# Prepare navigation HTML
Foreach ($startType in $services.Keys) {
if ($nav) {
$nav += " | "
}
$nav += "<a href=`"#$startType`">$($startType)</a>"
}
$nav = "<div class=`"nav`"> [ $nav ] </div>"
# Create individual tables
Foreach ($startType in $services.Keys) {
# Create header
$header = "<h3><a name=`"$startType`">$($startType)</a> - ($($services.($startType).Count))</h3> $nav"
# Create table
[xml]$table = $services.($startType) | Select-Object ServiceName,Status,DisplayName | ConvertTo-Html -Fragment
# Style the header row to control column widths
$table.SelectNodes("table/tr/th") | Foreach-Object { $_.setAttribute("class","col-$($_.'#text')") }
# Style based on StartType
switch ($startType) {
'Automatic' { $table.SelectNodes("table/tr/td[2][text()='Stopped']").setAttribute("class","back-red") }
'Manual' { $table.SelectNodes("table/tr/td[2][text()='Running']").setAttribute("class","back-green") }
}
$body += $header
$body += $table.OuterXml
}
# Create HTML file
ConvertTo-Html -Body "$body" -Title $title | Out-File $ReportFile
# View file if requested
if ($View.IsPresent) {
Invoke-Item $ReportFile
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment