question

PowerShell-6856 avatar image
0 Votes"
PowerShell-6856 asked RichMatheisen-8856 answered

Help on my Code

Hi All,

Below scrip is created to check list of windows services running or stopped. If any one services in list is stopped send an email. If all services are running i don't want to send any email. In below script is working fine send an email notification if any services are stopped, but if all services are running fine also i'm getting blank email.
Kindly advice or share the working script.

TIA

Call Function


servicestatus $EVServerList $EVServicesList

$EVServerList = Get-Content "C:\LMSupport\Monitor\qaserver.txt"
$EVServicesList = Get-Content "C:\LMSupport\Monitor\qaservices.txt"

$report = "C:\Monitor\Report.htm"

$smtphost = "My smtp host is given here"
$from = "From Email ID given here"
$to = "To Email ID given here"

$checkrep = Test-Path "C:\Monitor\Report.htm"

If ($checkrep -like "True")

{
Remove-Item "C:\Monitor\Report.htm"
}
New-Item "C:\Monitor\Report.htm" -type file

ADD HTML Content


Add-Content $report "<html>"
Add-Content $report "<head>"
Add-Content $report "<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>"
Add-Content $report '<title>3DExperience Service Status Report</title>'
Add-Content $report "</head>"
Add-Content $report "<body>"
add-content $report "<table width='100%'>"
add-content $report "<tr bgcolor='Lavender'>"
add-content $report "<td colspan='7' height='25' align='center'>"
add-content $report "<font face='tahoma' color='#003399' size='4'><strong>Service Status Report</strong></font>"
add-content $report "</td>"
add-content $report "</tr>"
add-content $report "</table>"
add-content $report "<table width='100%'>"
Add-Content $report "<tr bgcolor='IndianRed'>"
Add-Content $report "<td width='10%' align='center'><B>Server Name</B></td>"
Add-Content $report "<td width='50%' align='center'><B>Service Name</B></td>"
Add-Content $report "<td width='10%' align='center'><B>Status</B></td>"
Add-Content $report "</tr>"


Get Services Status



Function servicestatus ($serverlist, $serviceslist)

{
foreach ($machineName in $serverlist)
{
foreach ($service in $serviceslist)
{
$serviceStatus = get-service -ComputerName $machineName -Name $service
while ($serviceStatus.status -ne "Running")
{
Start-Service $service
Start-Sleep -seconds 3
$serviceStatus.Refresh()
if ($serviceStatus.Status -eq 'Running')
{
Write-Host $machineName t $serviceStatus.name t $serviceStatus.status -ForegroundColor Green
$svcName = $serviceStatus.name
$svcState = $serviceStatus.status
Add-Content $report "<tr>"
Add-Content $report "<td bgcolor= 'GainsBoro' align=center> <B> $machineName</B></td>"
Add-Content $report "<td bgcolor= 'GainsBoro' align=center> <B>$svcName</B></td>"
Add-Content $report "<td bgcolor= 'Aquamarine' align=center><B>$svcState</B></td>"
Add-Content $report "</tr>"
}
}
}
}
}

Close HTMl Tables


Add-content $report "</table>"
Add-Content $report "</body>"
Add-Content $report "</html>"

Send Email

$subject = "Service Monitor Alert"
$body = Get-Content "C:\Monitor\Report.htm"
$smtp= New-Object System.Net.Mail.SmtpClient $smtphost
$msg = New-Object System.Net.Mail.MailMessage $from, $to, $subject, $body
$msg.isBodyhtml = $true
$smtp.send($msg)

windows-server-powershell
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

NewbieJones-6218 avatar image
0 Votes"
NewbieJones-6218 answered

Please use the code sample features to upload code (101010).

Can you also indent your code, so its easier to see where loops start and finish, and what code is linked to a particular if\where statement.

The answer will be in your while\if statements. The Send Email section will always run in your current script. It needs to be encapsulated in an if.

Initially I would have just said if ($report=null) but they way your code is structured, $report will always have at least the boiler plate HTML.

A quick fix would be to initialise a variable called $reportneeded as $false at the top of your function and just before "Start-Service $service" change it to $true.

This is assuming that if it ever gets to this command then a service was not started, so the email is needed.

You can then put the send email into an if statement - (if $reportneeded=$true)

Just my personal preference. HTML reports are nice, but this type of information is much easier presented in a CSV file.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

RichMatheisen-8856 avatar image
1 Vote"
RichMatheisen-8856 answered

How can that work? You're calling the function "servicestatus" with two undefined variables ($EVServerList and $EVServicesList)! You populate those two variables after you call the function.

Try adding another variable to your script, right at the top:

 $ShouldSendEmail = $false

And then, add one line below the "while" on line 53:

 $ShouldSendMail = $true

And one more line just after you call the "servicestatus" function:

 if (-not $ShouldSendEmail){ return }

Now the only time am email will be sent is if you encountered a service that wasn't in the "running" state.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

PowerShell-6856 avatar image
0 Votes"
PowerShell-6856 answered RichMatheisen-8856 commented

Hi RichMatheisen-8856
As per your advice i've modified the script as below, but still output is not as per my expectation.
Pls help I'm checking list of services where if any one service in services.txt file is stopped only i should get email. If all services are running i dont want to get email.

$EVServerList = Get-Content "C:\Monitor\server.txt"
$EVServicesList = Get-Content "C:\Monitor\services.txt"

$report = "C:\Monitor\Report.htm"

$smtphost = "My smtp host is given here"
$from = "From Email ID given here"
$to = "To Email ID given here"

$checkrep = Test-Path "C:\Monitor\Report.htm"

If ($checkrep -like "True")

{
Remove-Item "C:\Monitor\Report.htm"
}

New-Item "C:\Monitor\Report.htm" -type file

Add-content $report "<table width='100%'>"
Add-Content $report "<tr bgcolor='IndianRed'>"
Add-Content $report "<td width='10%' align='center'><B>Server Name</B></td>"
Add-Content $report "<td width='50%' align='center'><B>Service Name</B></td>"
Add-Content $report "<td width='10%' align='center'><B>Status</B></td>"
Add-Content $report "</tr>"

Function servicestatus ($serverlist, $serviceslist)

{
foreach ($machineName in $serverlist)
{
foreach ($service in $serviceslist)
{
$serviceStatus = get-service -ComputerName $machineName -Name $service
if ($serviceStatus.status -ne "Running")
{
Write-Host $machineName t $serviceStatus.name t $serviceStatus.status -ForegroundColor Red
$svcName = $serviceStatus.name
$svcState = $serviceStatus.status
Add-Content $report "<tr>"
Add-Content $report "<td bgcolor= 'GainsBoro' align=center> <B> $machineName</B></td>"
Add-Content $report "<td bgcolor= 'GainsBoro' align=center> <B>$svcName</B></td>"
Add-Content $report "<td bgcolor= 'Red' align=center><B>$svcState</B></td>"
Add-Content $report "</tr>"
}
}
}
}

$ShouldSendEmail = $false
servicestatus $EVServerList $EVServicesList
if (-not $ShouldSendEmail){ return }

Add-content $report "</table>"
Add-Content $report "</body>"
Add-Content $report "</html>"

$subject = "Service Monitor Alert"
$body = Get-Content "C:\Monitor\Report.htm"
$smtp= New-Object System.Net.Mail.SmtpClient $smtphost
$msg = New-Object System.Net.Mail.MailMessage $from, $to, $subject, $body
$msg.isBodyhtml = $true
$smtp.send($msg)

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Is there a reason why you aren't using the "Code Sample" editor when you post code?

Did you really mean to insert the letter "t" between those variables and have that literal "t" be part of the output?

 Write-Host $machineName t $serviceStatus.name t $serviceStatus.status -ForegroundColor Red


That's just one of the many fun things the default editor does to code!

How about indentation? Does the code you're writing all squeeze up against the left margin of your editor?

0 Votes 0 ·
RichMatheisen-8856 avatar image
0 Votes"
RichMatheisen-8856 answered

Your "servicestatus" function never returns any indication of finding a non-running service.

 $EVServerList = Get-Content "C:\Monitor\server.txt"
 $EVServicesList = Get-Content "C:\Monitor\services.txt"
    
 $report = "C:\Monitor\Report.htm"
    
 $smtphost = "My smtp host is given here"
 $from = "From Email ID given here"
 $to = "To Email ID given here"
    
 $checkrep = Test-Path "C:\Monitor\Report.htm"
    
 If ($checkrep -like "True")
 {
     Remove-Item "C:\Monitor\Report.htm"
 }
    
 New-Item "C:\Monitor\Report.htm" -type file
    
 Add-Content $report "<table width='100%'>"
 Add-Content $report "<tr bgcolor='IndianRed'>"
 Add-Content $report "<td width='10%' align='center'><B>Server Name</B></td>"
 Add-Content $report "<td width='50%' align='center'><B>Service Name</B></td>"
 Add-Content $report "<td width='10%' align='center'><B>Status</B></td>"
 Add-Content $report "</tr>"
    
 Function servicestatus ($serverlist, $serviceslist)
 {
     $notrunning = $false
     foreach ($machineName in $serverlist) {
         foreach ($service in $serviceslist) {
             $serviceStatus = Get-Service -ComputerName $machineName -Name $service
             if ($serviceStatus.status -ne "Running") {
                 $notrunning = $true
                 Write-Host $machineName `t $serviceStatus.name `t $serviceStatus.status -ForegroundColor Red
                 $svcName = $serviceStatus.name
                 $svcState = $serviceStatus.status
                 Add-Content $report "<tr>"
                 Add-Content $report "<td bgcolor= 'GainsBoro' align=center> <B> $machineName</B></td>"
                 Add-Content $report "<td bgcolor= 'GainsBoro' align=center> <B>$svcName</B></td>"
                 Add-Content $report "<td bgcolor= 'Red' align=center><B>$svcState</B></td>"
                 Add-Content $report "</tr>"
             }
         }
     }
     $notrunning
 }
    
 $ShouldSendEmail = $false
 $ShouldSendEMail = servicestatus $EVServerList $EVServicesList
 if (-not $ShouldSendEmail) { return }   # servicestatus returns $false if everything was found to be running
    
 Add-Content $report "</table>"
 Add-Content $report "</body>"
 Add-Content $report "</html>"
    
 $subject = "Service Monitor Alert"
 $body = Get-Content "C:\Monitor\Report.htm"
 $smtp = New-Object System.Net.Mail.SmtpClient $smtphost
 $msg = New-Object System.Net.Mail.MailMessage $from, $to, $subject, $body
 $msg.isBodyhtml = $true
 $smtp.send($msg)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.