Windows Service Status Report
Solution 1:
As commented, your current code sends an email for every service from the list on every computer from the array of computernames.
I would suggest gathering all info needed as an array of objects and use ConvertTo-Html on that data to create a nice HTML table from it.
Using a Here-String as body HTML template, you can set the style to color the table the way you want.
Since both the -Name
and -ComputerName
parameters of Get-Service
can take an array of names, your code can be condensed like below:
$machines = 'XXX', 'YYY' # array of computernames to check
$services = 'WSearch','SENS' # array of services to check
$result = Get-Service -Name $services -ComputerName $machines |
Where-Object { $_.Status -match '(Start|Stop)pending' } |
# output objects to be collected in $result
Select-Object @{Name = 'Server name'; Expression = {$_.MachineName}},
@{Name = 'Service name'; Expression = {$_.Name}},
@{Name = 'Service Start Type'; Expression = {$_.StartType}},
@{Name = 'Service Status'; Expression = {$_.Status}}
# only send an email if there is something to alert (found services in 'StartPending' and/or 'StopPending' state)
# the @() is needed to force $result to be an array even if it has only one item
if (@($result).Count) {
# convert the resulting array of objects into a HTML table
$table = ($result | Sort-Object 'Server name' | ConvertTo-Html -Fragment) -join [environment]::NewLine
# create a HTML template for the email using a Here-String
$htmlTemplate = @"
<html><head>
<style>
body, table {font-family: sans-serif; font-size: 10pt; color: #000000;}
table {border: 1px solid white; border-collapse: collapse;}
th {border: 1px solid white; background: #0000af; padding: 3px; color: #ffffff;}
td {border: 1px solid white; padding: 3px; color: #000000;}
</style>
</head><body>
Pending services.<br />
@@TABLE@@
<br />
</body></html>
"@
# create a Hashtable to splat the parameters to Send-MailMessage
$mailParams = @{
From = '[email protected]'
To = '[email protected]'
Subject = 'Services not running {0:yyyy-MM-dd}' -f (Get-Date)
SmtpServer = 'ABC.com'
Body = $htmlTemplate -replace '@@TABLE@@', $table
BodyAsHtml = $true
}
# send the email
Send-MailMessage @mailParams
}
else {
Write-Host "No services found that were in StartPending or StopPending state. No email was sent." -ForegroundColor Green
}
If, as you commented, you would like to show all but two of the possible service states (ContinuePending, Paused, PausePending, Running, StartPending, Stopped, StopPending
)
for all services on a collection of servers,
you could change the above to:
$machines = 'XXX', 'YYY' # array of computernames to check
$result = Get-Service -ComputerName $machines |
Where-Object { $_.Status -notmatch 'Running|Stopped' } |
# output objects to be collected in $result
Select-Object @{Name = 'Server name'; Expression = {$_.MachineName}},
@{Name = 'Service name'; Expression = {$_.Name}},
@{Name = 'Service Start Type'; Expression = {$_.StartType}},
@{Name = 'Service Status'; Expression = {$_.Status}}