breadstix
breadstix

Reputation: 13

Inconsistent powershell script

I am using a script that performs a basic health check on average CPU and Memory Utilization and checks if a specific service is running or not. The output will be displayed as HTML. If the CPU/Memory utilization is greater than 89%, or if ther service is not running, the affected server will be displayed in red. The script works just fine except for some inconsistencies that the server, even when under utilized, will be in red.

Here is the powershell script I am using:

$ServerListFile = "C:\Scripts\HealthCheck\ServerList.txt"
$ServerList = Get-Content $ServerListFile -ErrorAction SilentlyContinue
$Date = Get-Date -Format M.d.yyyy
$Result = @()

foreach ($computername in $ServerList) {

    $AVGProc = Get-WmiObject -ComputerName $computername Win32_Processor |
        Measure-Object -Property LoadPercentage -Average |
        Select-Object Average
    $OS = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $computername |
        Select-Object @{Name = "MemoryUsage"; Expression = {"{0:N2}" -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize) }}
    $Service1 = Get-Service -ComputerName $computername -Name Service1
    $Service2 = Get-Service -ComputerName $computername -Name Service2

    $Result += [PSCustomObject] @{  
        ServerName = "$computername" 
        CPULoad    = "$($AVGProc.Average)%" 
        MemLoad    = "$($OS.MemoryUsage)%"
        Service1   = "$($Service1.Status)" 
        Service2   = "$($Service2.Status)"
    }

    $Outputreport = "<HTML><TITLE> Server Health Check </TITLE> 
                     <BODY background-color:peachpuff> 
                     <font color =""#99000"" face=""Microsoft Tai le""> 
                     <H2> Server Health Check </H2></font> 
                     <Table border=1 cellpadding=7 cellspacing=0> 
             <font face=""Calibri"">
                     <TR bgcolor=white align=center> 
                       <TD><B> Server Name </B></TD> 
                       <TD><B> Avrg.CPU  </B></TD> 
                       <TD><B> Memory  </B></TD>
                   <TD><B> Service1 </B></TD>
                       <TD><B> Service2</B></TD></TR>"

    foreach ($Entry in $Result) {
        if (($Entry.MemLoad -gt "89") -Or ($Entry.CPULoad -gt "89") -or ($Entry.Service1 -eq "Stopped") -or ($Entry.Service2 -eq "Stopped")) {
            $Outputreport += "<TR bgcolor=red>"
        } else { 
            $Outputreport += "<TR bgcolor=lightgreen>"
        }
        $Outputreport += "<TD>$($Entry.Servername)</TD><TD align=center>$($Entry.CPULoad)</TD><TD align=center>$($Entry.MemLoad)</TD><TD align=center>$($Entry.Service1)</TD><TD align=center>$($Entry.Service2)</TD></TR>" 
    }

    $Outputreport += "</Table></BODY></HTML>"
}

$Outputreport | Out-File C:\Scripts\HealthCheck\ServerHealthCheck\HealthCheck_$Date.htm

Thanks!

Upvotes: 1

Views: 179

Answers (1)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 175065

Don't use string comparisons when you're really interested in a numerical comparison - the ordinality of a string of digits is not equal to that of it's numerical counterpart. Consider the following comparison operations:

PS C:\> 9 -gt 89
False
PS C:\> "9" -gt "89"
True

First, change the result objects to carry the percentages as numbers instead:

$Result += [PSCustomObject] @{
    ServerName = "$computername" 
    CPULoad = $AVGProc.Average 
    MemLoad = $OS.MemoryUsage
    Service1 = "$($Service1.Status)" 
    Service2 = "$($Service2.Status)"
}

Then change the if statement to compare them as numbers:

if (($Entry.MemLoad -gt 89) -Or ($Entry.CPULoad -gt 89) -or ($Entry.Service1 -eq "Stopped") -or ($Entry.Service2 -eq "Stopped"))

And then finally, add the % sign in the final output:

 $Outputreport += "<TD>$($Entry.Servername)</TD><TD align=center>$($Entry.CPULoad)%</TD><TD align=center>$($Entry.MemLoad)%</TD><TD align=center>$($Entry.Service1)</TD><TD align=center>$($Entry.Service2)</TD></TR>" 

Upvotes: 3

Related Questions