Need to monitor Server Resources Utilization for 30 minutes and send mail in Powershell

亡梦爱人 提交于 2021-02-10 06:14:41

问题


I have developed PowerShell script which monitors server performance like average CPU utilization, Memory and Cdrive and if any of the resource crosses the threshold it will trigger mail. My script is running fine but I want to monitor it for 30 minutes and if in 30 minutes it cross threshold only then it will trigger the mail.

<#
    .SYNOPSIS
    Script for the detailed server health report

    .DESCRIPTION
    The script accepts parameter from CSV file by which we can get details and
    all information related to health status of the server.The script generates all the 
    information in a CSv file.

#>
    [CmdletBinding(SupportsShouldProcess=$True)]

    param(
        [Parameter(Position=0,mandatory=$true)]
        [string]$Servercsv
    )
    begin{
        Write-Host "Running"
    }
    process{

         # Path for the CSV file that contains all the Print Server information.
        $ServerDetails=import-csv $Servercsv
        $result=@()
        $Outputreport = $null

         foreach($server in $ServerDetails){

         try{    

             #sysinfo variable contains complete systeminfo like manufacturer name, physical memory,servername 

             $cpu=Get-WMIObject  -ComputerName $server.servers win32_processor| select __Server, @{name="CPUUtilization" ;expression ={“{0:N2}” -f (get-counter -Counter "\Processor(_Total)\% Processor Time" -SampleInterval 1 -MaxSamples 6 |
                select -ExpandProperty countersamples | select -ExpandProperty cookedvalue | Measure-Object -Average).average}}

             $disks =Get-WmiObject -Class win32_Volume -ComputerName $server.servers -Filter "DriveLetter = 'C:'" |
                Select-object @{Name = "PercentFree"; Expression = {“{0:N2}” -f  (($_.FreeSpace / $_.Capacity)*100) } }


             $os=Get-WmiObject -Class win32_operatingsystem -computername $server.servers |
                Select-Object @{Name = "MemoryUsage"; Expression = {“{0:N2}” -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize) }}

        $result += [PSCustomObject] @{  
            ServerName ="$($server.servers)" 
            CPUUtilization = $cpu.CPUUtilization.ToString()
            CDrive = $disks.PercentFree
            MemLoad = $OS.MemoryUsage

            }
            }

            catch{
         "error communicating with $($server.servers), skipping to next"
         }
         }

    $Outputreport = "<HTML><TITLE> Utilization of Server Resources</TITLE>
                     <BODY background-color:peachpuff>
                     <font color =""#99000"" face=""arial"">
                     <H3> Utilization of Server Resources</H3></font>
                     <Table border=2 cellpadding=1 cellspacing=5>
                     <TR bgcolor=gray align=center>
                       <TD><B>Server Name</B></TD>
                       <TD><B>CPUUtilization</B></TD>
                       <TD><B>Memory Utilization</B></TD>
                       <TD><B>CDrive</B></TD></TR>"


    Foreach($Entry in $Result){

    if(([decimal]$Entry.CPUUtilization -ge 25) -or ([decimal]$Entry.MemLoad -ge 50) -or (([decimal]$Entry.CDrive) -le 60) )
    {
    $Outputreport += "<TR>"

     $Outputreport += "<TD><B>$($Entry.Servername)</B></TD>"
     if([decimal]$Entry.CPUUtilization -ge 25)
        {

        $Outputreport += "<TD align=center style=color:red;>$($Entry.CPUUtilization+'%')</TD>"
        }
        else {
        $Outputreport += "<TD align=center style=color:White;>$($Entry.CPUUtilization+'%')</TD>"
        }


        if([decimal]$Entry.MemLoad -ge 50)
        {

        $Outputreport += "<TD align=center style=color:red;>$($Entry.MemLoad+'%')</TD>"
        }
        else{
         $Outputreport += "<TD align=center style=color:White;>$($Entry.MemLoad+'%')</TD>"
         }



       if(([decimal]$Entry.CDrive) -le 60)
       { 

        $Outputreport += "<TD align=center style=color:red;>$($Entry.Cdrive+'%')</TD>"
        }
        else{ $Outputreport += "<TD align=center style=color:White;>$($Entry.Cdrive+'%')</TD>"}


         #$Outputreport += "<TD>$($Entry.Servername)</TD>"


         #$Outputreport += "<TD>$($Entry.Servername)</TD>"

        $Outputreport+="</TR>"

           }



     }

     $Outputreport += "</Table><p>Regards,<br>Rujhaan Bhatia</p></BODY></HTML>" 
      $out=$Outputreport | ConvertTo-Html -Head $Outputreport
     #Send an email about the Load

        # $smtp is the outgoing mail server 
        $smtp= "smtphost.redmond.corp.microsoft.com"

        try{
        send-mailmessage -SmtpServer $smtp -from v-rubhat@microsoft.com -to v-rubhat@microsoft.com,v-ketr@microsoft.com  -subject "Retail Servers Health Report"  -BodyAsHtml "$out" 
        }
        catch [exception]
        {
        write-host ("Cannot send mail, since argument is null or empty")
        }


    }

Please do suggest me if any changes are required in any of the command as well.


回答1:


This should give you an idea on how to run jobs in the background and check for 30 minutes. If at any time the cpu, mem or disk is greater than threhold, send email.

function SendEmail {
  param($server, $cpu, $mem, $disk) 

  #Code goes here to send email
}

$cpuThreshold = 99
$memThreshold = 99
$diskThreshold = 100

$jobHash = @{}
$serverHash = @{}

$serverList = @("localhost")

foreach($server in $serverList) {
    $cpu = Start-Job -ComputerName $server  -ScriptBlock { Get-Counter "\processor(_Total)\% Processor Time" -Continuous }
    $mem = Start-Job -ComputerName $server -ScriptBlock { Get-Counter -Counter "\Processor(_Total)\% Processor Time" -Continuous }
    $disk = Start-Job -ComputerName $server -ScriptBlock { Get-Counter -Counter "\LogicalDisk(C:)\% Free Space" -Continuous }

    $serverHash.Add("cpu", $cpu)
    $serverHash.Add("mem", $mem)
    $serverHash.Add("disk", $disk)

    $jobHash.Add($server, $serverHash)
}

Start-Sleep 10
$totalLoops = 0

while ($totalLoops -le 360) {

    foreach($server in $jobHash.Keys) {
        $cpu = (Receive-Job $jobHash[$server].cpu | % { (($_.readings.split(':'))[1]).Replace("`n","") } | measure -Maximum).Maximum
        $mem = (Receive-Job $jobHash[$server].mem | % { (($_.readings.split(':'))[1]).Replace("`n","") } | measure -Maximum).Maximum
        $disk = (Receive-Job $jobHash[$server].disk | % { (($_.readings.split(':'))[2]).Replace("`n","") } | measure -Maximum).Maximum

        if ($Cpu -gt $cpuThreshold -or $mem -gt $memThreshold -or $disk -gt $diskThreshold) {
            Send-Email $server $cpu $mem $disk
        }
        Write-Output "CPU: $($cpu), Mem: $($mem), disk util: $($disk)"
    }
    Start-Sleep 1
    $totalLoops ++
}

Get-Job | Remove-Job

Hopefully this answers the question on how to create jobs in the background to check for status.

I would, however, check the max number of jobs you can have at any given time.

Documentation on Get-Counter



来源:https://stackoverflow.com/questions/60049690/need-to-monitor-server-resources-utilization-for-30-minutes-and-send-mail-in-pow

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!