Share via

Help on my Code

Power Shell 1 Reputation point
2022-05-13T09:20:38.37+00:00

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.namet $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 for business | Windows Server | User experience | PowerShell
0 comments No comments

4 answers

Sort by: Most helpful
  1. Rich Matheisen 48,116 Reputation points
    2022-05-13T19:51:05.863+00:00

    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.

    Was this answer helpful?

    1 person found this answer helpful.
    0 comments No comments

  2. Rich Matheisen 48,116 Reputation points
    2022-05-20T21:10:52.393+00:00

    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)
    

    Was this answer helpful?

    0 comments No comments

  3. Power Shell 1 Reputation point
    2022-05-20T16:22:21.21+00:00

    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.namet $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)

    Was this answer helpful?


  4. Newbie Jones 1,411 Reputation points
    2022-05-13T13:40:20.733+00:00

    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.

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.