I run the below scripts and Eventlog is blank on HTM File but on powershell
$ServerListFile = "D:\Scripts\ServerList.txt"
$ServerList = Get-Content $ServerListFile -ErrorAction SilentlyContinue
$Result = #()
ForEach($computername in $ServerList)
{
Get-Eventlog -LogName Security -Newest 2000 | Where-Object {$_.EventID -eq "4624"} | Select-Object #{Name ="Username"; Expression = {$_.ReplacementStrings[1]}}
$result += [PSCustomObject] #{
ServerName = "$computername"
EventLog = "$Username"
}
$Outputreport = "<HTML><TITLE> Decommission Validation Report </TITLE>
<BODY background-color:peachpuff>
<font color =""#99000"" face=""Microsoft Tai le"">
<H2> Decommission Validation Report </H2></font>
<Table border=1 cellpadding=0 cellspacing=0>
<TR bgcolor=gray align=center>
<TD><B>Server Name</B></TD>
<TD><B>EventLog</B></TD></TR>"
Foreach($Entry in $Result)
{
if((($Entry.Servername) -or ($Entry.EventLog)) -ge 80 )
{
$Outputreport += "<TR bgcolor=red>"
}
else
{
$Outputreport += "<TR>"
}
$Outputreport += "<TD>$($Entry.Servername)</TD></TD><TD align=center>$($Entry.Username)</TD></TR>"
}
$Outputreport += "</Table></BODY></HTML>"
}
$Outputreport | out-file D:\Scripts\Test.htm
Invoke-Expression D:\Scripts\Test.htm
I run the above scripts and Eventlog is blank on HTM File but on powershell
you arent capturing the get-eventlog return values
ForEach($computername in $ServerList)
{
$eventLog = Get-Eventlog -LogName Security -Newest 2000 | Where-Object {$_.EventID -eq "4624"} | Select-Object #{Name ="Username"; Expression = {$_.ReplacementStrings[1]}}
$result += [PSCustomObject] #{
ServerName = "$computername"
EventLog = "$eventLog.Username"
}
if what you want is an entry in result for each of the 2k event log items returned then do this:
ForEach($computername in $ServerList)
{
$eventLog = Get-Eventlog -LogName Security -Newest 2000 | Where-Object {$_.EventID -eq "4624"} | Select-Object #{Name ="Username"; Expression = {$_.ReplacementStrings[1]}}
foreach($item in $eventLog)
{
$result += [PSCustomObject] #{
ServerName = "$computername"
EventLog = "$eventLog.Username"
}
}
I incorporated the changes suggested by Dane Boulton and modified your code a bit to get what I believe is what you are looking for. I changed the Replacement strings entry to 5 because I believe you are looking for the user account logging in. I also modified the EventLog variable to reference $item.UserName. See how this works for you.
$ServerListFile = "D:\Scripts\ServerList.txt"
$ServerList = Get-Content $ServerListFile -ErrorAction SilentlyContinue
$Result = #()
ForEach($computername in $ServerList)
{
$eventLog = Get-Eventlog -LogName Security -Newest 2000 | Where-Object {$_.EventID -eq "4624"} | Select-Object #{Name ="Username"; Expression = {$_.ReplacementStrings[5]}}
foreach($item in $eventLog)
{
$result += [PSCustomObject] #{
ServerName = $computername
UserName = $item.Username
}
}
$Outputreport = "<HTML><TITLE> Decommission Validation Report </TITLE>
<BODY background-color:peachpuff>
<font color =""#99000"" face=""Microsoft Tai le"">
<H2> Decommission Validation Report </H2></font>
<Table border=1 cellpadding=0 cellspacing=0>
<TR bgcolor=gray align=center>
<TD><B>Server Name</B></TD>
<TD><B>UserName</B></TD></TR>"
Foreach($Entry in $Result)
{
if((($Entry.Servername) -or ($Entry.UserName)) -ge 80 )
{
$Outputreport += "<TR bgcolor=red>"
}
else
{
$Outputreport += "<TR>"
}
$Outputreport += "<TD>$($Entry.Servername)</TD></TD><TD align=center>$($Entry.UserName)</TD></TR>"
}
$Outputreport += "</Table></BODY></HTML>"
}
$Outputreport | out-file D:\Scripts\Test.htm
Invoke-Expression D:\Scripts\Test.htm
Related
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.
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
I have prepared server health report via PowerShell. My script is working fine but I am getting some random value in the bottom when I receive email via script, also I am not able to add body in my send-mailmessage command. When I do so script generates exception.
Here is my PS code:
<#
.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 5 |
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=gwmi -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 15) -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 15)
{
$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>Hello</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 -subject "Server Health Report" -BodyAsHtml "$out"
}
catch [exception]
{
write-host ("Cannot send mail, since argument is null or empty")
}
}
Below is my attached output and that * and 1121 is that random number:
Utilization of Server Resources
Server Name CPUUtilization Memory Utilization CDrive
xxxxxxxx 3.25% 29.26% 22.11%
xxxxxxxx 18.80% 52.15% 57.49%
xxxxxxxx 27.76% 27.51% 71.91%
*
1121
I have changed the $out variable and added property attribute in it and that worked. Here's my edited $out command
$out=$Outputreport | ConvertTo-Html -Property Servername,CPUUtilization,MemLoad,CDrive -Head $Outputreport
I have the below PowerShell script which shows the remote servers CPU/Disk/Memory health check.
It is not giving the output in HTML format and I am sending it to my email id with SMTP option. It is all working fine.
Current Output:
Along with the HTML output I want this output to be saved in a CSV file as well so that I can load it into Teradata using MLOAD.
Please help me to get output in a CSV file.
How can we load the data in CSV file to Teradata, can this be done using powershell or batch?
Code:
$ServerListFile = "C:\Users\HOSDUM01\Desktop\Auto\Server_health_check\list.txt"
$ServerList = Get-Content $ServerListFile -ErrorAction SilentlyContinue
$Result = #()
ForEach ($computername in $ServerList) {
$AVGProc = Get-WmiObject -computername $computername win32_processor |
Measure-Object -property LoadPercentage -Average | Select Average
$OS = gwmi -Class win32_operatingsystem -computername $computername |
Select-Object #{Name = "MemoryUsage"; Expression = {“{0:N2}” -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory) * 100) / $_.TotalVisibleMemorySize) }}
$vol = Get-WmiObject -Class win32_Volume -ComputerName $computername -Filter "DriveLetter = 'C:'" |
Select-object #{Name = "C PercentFree"; Expression = {“{0:N2}” -f (($_.FreeSpace / $_.Capacity) * 100) } }
$vol2 = Get-WmiObject -Class win32_Volume -ComputerName $computername -Filter "DriveLetter = 'E:'" |
Select-object #{Name = "E PercentFree"; Expression = {“{0:N2}” -f (($_.FreeSpace / $_.Capacity) * 100) } }
$vol3 = Get-WmiObject -Class win32_Volume -ComputerName $computername -Filter "DriveLetter = 'F:'" |
Select-object #{Name = "F PercentFree"; Expression = {“{0:N2}” -f (($_.FreeSpace / $_.Capacity) * 100) } }
$result += [PSCustomObject] #{
ServerName = "$computername"
CPULoad = "$($AVGProc.Average)%"
MemLoad = "$($OS.MemoryUsage)%"
CDrive = "$($vol.'C PercentFree')%"
EDrive = "$($vol2.'E PercentFree')%"
FDrive = "$($vol3.'F PercentFree')%"
}
$Outputreport = "<HTML><TITLE> Server Health Report </TITLE>
<BODY background-color:peachpuff>
<font color =""#99000"" face=""Microsoft Tai le"">
<H2> Server Health Report </H2></font>
<Table border=1 cellpadding=0 cellspacing=0>
<TR bgcolor=Cyan align=center>
<TD><B>EP_Server_Name</B></TD>
<TD><B>CPU_Utilizied</B></TD>
<TD><B>Memory_Utilized</B></TD>
<TD><B>C_Drive_Free_Percentage</B></TD>
<TD><B>E_Drive_Free_Percentage</B></TD>
<TD><B>F_Drive_Free_Percentage</B></TD></TR>"
Foreach ($Entry in $Result) {
if (($Entry.CpuLoad) -ge "80" -or ($Entry.memload) -ge "80" -or ($Entry.Cdrive) -le "20" -or ($Entry.Edrive) -le "20" -or ($Entry.Fdrive) -le "20") {
$Outputreport += "<TR bgcolor=red>"
}
else {
$Outputreport += "<TR bgcolor=green>"
}
$Outputreport += "<TD>$($Entry.Servername)</TD><TD align=center>$($Entry.CPULoad)</TD><TD align=center>$($Entry.MemLoad)</TD><TD align=center>$($Entry.Cdrive)</TD><TD align=center>$($Entry.Edrive)</TD><TD align=center>$($Entry.Fdrive)</TD></TR>"
}
$Outputreport += "</Table></BODY></HTML>"
}
$Outputreport | out-file C:\Users\HOSDUM01\Desktop\Auto\Server_health_check\Test.htm
#Invoke-Expression C:\Users\HOSDUM01\Desktop\Auto\Server_health_check\Test.htm
##Send email functionality from below line, use it if you want
$smtpServer = "Random"
$smtpFrom = "test#test.com"
$smtpTo = "test#test.com"
$messageSubject = "Servers Health report"
$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true
$message.Body = "<head><pre>$style</pre></head>"
$message.Body += Get-Content C:\Users\HOSDUM01\Desktop\Auto\Server_health_check\test.htm
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($message)
As $result already contains the info you want in the csv, it can just be piped to Export-Csv
Simply add this line at the end of your script:
$result | Export-Csv -Path C:\folder\health_check.csv -NoTypeInformation
Not used Teradata but there was already a question on csv import: How to load data from a csv file into a table using Teradata Studio
All you need to do is, append to your script:
$Result | Export-Csv "C:\Users\HOSDUM01\Desktop\Auto\Server_health_check\Test.csv" -NoType
or whatever path you'd like to store the file
EDIT Reworked the script out of interrest.
Streamlined path usage
Inserted function DriveFreePercent and removed intermediate (unneccessary) variables.
moved the html creation outside of the foreach
Sample Csv file
"ServerName","CPULoad","MemLoad","CDrive","EDrive","FDrive"
"HP-G1610","4","32,61","94,56","",""
## Q:\Test\2018\05\31\SO_50617742.ps1
$BaseDir = "C:\Users\HOSDUM01\Desktop\Auto\Server_health_check\"
$ServerListFile = Join-Path $BaseDir "Server_list.txt"
$ReportHtm = Join-Path $BaseDir "Server_Test.htm"
$ReportCsv = Join-Path $BaseDir "Server_Test.csv"
function DriveFreePercent {
param ([string]$ComputerName,
[string]$DriveLetter)
Get-WmiObject -Class win32_Volume -ComputerName $ComputerName -Filter "DriveLetter = '$($DriveLetter):'" |
ForEach {"{0:N2}" -f (($_.FreeSpace / $_.Capacity)*100) }
}
$ServerList = Get-Content $ServerListFile -ErrorAction SilentlyContinue
$Result = #()
ForEach($computername in $ServerList) {
$Result += [PSCustomObject] #{
ServerName = "$computername"
CPULoad = ("{0}" -f (Get-WmiObject -ComputerName $computername win32_processor|Measure LoadPercentage -Average).Average)
MemLoad = (gwmi -Class win32_operatingsystem -ComputerName $computername |
ForEach{"{0:N2}" -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/$_.TotalVisibleMemorySize)})
CDrive = (DriveFreePercent $ComputerName C)
EDrive = (DriveFreePercent $ComputerName E)
FDrive = (DriveFreePercent $ComputerName F)
}
}
$Outputreport = "<HTML><TITLE> Server Health Report </TITLE>
<BODY background-color:peachpuff>
<font color =""#99000"" face=""Microsoft Tai le"">
<H2> Server Health Report </H2></font>
<Table border=1 cellpadding=0 cellspacing=0>
<TR bgcolor=Cyan align=center>
<TD><B>EP_Server_Name</B></TD>
<TD><B>CPULOAD</B></TD>
<TD><B>MemLoad</B></TD>
<TD><B>C_Free</B></TD>
<TD><B>E_Free</B></TD>
<TD><B>F_Free</B></TD></TR>"
Foreach($Entry in $Result) {
if( ($Entry.CpuLoad) -ge "80" -or
($Entry.Memload) -ge "80" -or
($Entry.Cdrive) -le "20" -or
($Entry.Edrive) -le "20" -or
($Entry.Fdrive) -le "20") {
$Outputreport += "<TR bgcolor=red>"
} else {
$Outputreport += "<TR bgcolor=green>"
}
$Outputreport += "<TD>$($Entry.Servername)</TD>"
$Outputreport += "<TD align=center>$($Entry.CPULoad)%</TD>"
$Outputreport += "<TD align=center>$($Entry.MemLoad)%</TD>"
$Outputreport += "<TD align=center>$($Entry.Cdrive)%</TD>"
$Outputreport += "<TD align=center>$($Entry.Edrive)%</TD>"
$Outputreport += "<TD align=center>$($Entry.Fdrive)%</TD></TR>"
$Outputreport += "</Table></BODY></HTML>"
}
$Outputreport | Out-File $ReportHtm
$Result | Export-Csv $ReportCsv -NoTypeInformation
#Invoke-Expression $ReportHtm
#gc $ReportCsv
##Send email functionality from below line, use it if you want
$smtpServer = "Random"
$smtpFrom = "test#test.com"
$smtpTo = "test#test.com"
$messageSubject = "Servers Health report"
$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true
$message.Body = "<head><pre>$style</pre></head>"
$message.Body += $Outputreport
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
#$smtp.Send($message)
$result = #()
for ($i=1; $i -lt 5; $i++) {
$result += [PSCustomObject] #{
ServerName = "$i"
CPULoad = "$($AVGProc.Average)%"
MemLoad = "$($OS.MemoryUsage)%"
CDrive = "$($vol.'C PercentFree')%"
EDrive = "$($vol2.'E PercentFree')%"
FDrive = "$($vol3.'F PercentFree')%"
}
}
$result | ConvertTo-Csv
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!
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>"
Could you help me combine these three scripts to a format that's like this
ComputerName CPUUsageAverage MemoryUsage C PercentFree
xxx 12 50% 30%
The way I execute this is:
Get-content '.\servers.txt' | Get-CPUusageAverage
Here are the scripts:
CPU
Function Get-CPUusageAverage
{
$input|Foreach-Object{Get-WmiObject -computername $_ win32_processor | Measure-Object -property LoadPercentage -Average | Select Average}
}
Memory
Function get-MemoryUsage
{
$input|Foreach-Object{
gwmi -Class win32_operatingsystem -computername $_ |
Select-Object #{Name = "MemoryUsage"; Expression = { “{0:N2}” -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize) }
}
}
}
C PercentFree
Function get-CPercentFree
{
$input|ForEach-Object{
Get-WmiObject -Class win32_Volume -ComputerName $_ -Filter "DriveLetter = 'C:'" |
Select-object #{Name = "C PercentFree"; Expression = { “{0:N2}” -f (($_.FreeSpace / $_.Capacity)*100) } }
}
}
First I would avoid using $input. You can just combine the queries into single function that then outputs a pscustomobject with the data for each computer e.g.:
function Get-ComputerStats {
param(
[Parameter(Mandatory=$true, Position=0,
ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[ValidateNotNull()]
[string[]]$ComputerName
)
process {
foreach ($c in $ComputerName) {
$avg = Get-WmiObject win32_processor -computername $c |
Measure-Object -property LoadPercentage -Average |
Foreach {$_.Average}
$mem = Get-WmiObject win32_operatingsystem -ComputerName $c |
Foreach {"{0:N2}" -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize)}
$free = Get-WmiObject Win32_Volume -ComputerName $c -Filter "DriveLetter = 'C:'" |
Foreach {"{0:N2}" -f (($_.FreeSpace / $_.Capacity)*100)}
new-object psobject -prop #{ # Work on PowerShell V2 and below
# [pscustomobject] [ordered] #{ # Only if on PowerShell V3
ComputerName = $c
AverageCpu = $avg
MemoryUsage = $mem
PercentFree = $free
}
}
}
cat '.\servers.txt' | Get-ComputerStats | Format-Table
How about:
cat '.\servers.txt' | % {select -property #{'n'='CPUUsageAverage';'e'={$_ | Get-CPUUsageAverage}},#{'n'='Memory Usage';'e'={$_ | Get-MemoryUsage}},#{'n'=C PercentFree';'e'={$_ | Get-CPercentFree}}}
Apologies above my previous post (Edited this), here's a script I am using to get the average of CPU, Mem, and C Drive free space which generate to an HTML file
$ServerListFile = "D:\serverList.txt"
$ServerList = Get-Content $ServerListFile -ErrorAction SilentlyContinue
$Result = #()
ForEach($computername in $ServerList)
{
$AVGProc = Get-WmiObject -computername $computername win32_processor |
Measure-Object -property LoadPercentage -Average | Select Average
$OS = gwmi -Class win32_operatingsystem -computername $computername |
Select-Object #{Name = "MemoryUsage"; Expression = {“{0:N2}” -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize) }}
$vol = Get-WmiObject -Class win32_Volume -ComputerName $computername -Filter "DriveLetter = 'C:'" |
Select-object #{Name = "C PercentFree"; Expression = {“{0:N2}” -f (($_.FreeSpace / $_.Capacity)*100) } }
$result += [PSCustomObject] #{
ServerName = "$computername"
CPULoad = "$($AVGProc.Average)%"
MemLoad = "$($OS.MemoryUsage)%"
CDrive = "$($vol.'C PercentFree')%"
}
$Outputreport = "<HTML><TITLE> Server Health Report </TITLE>
<BODY background-color:peachpuff>
<font color =""#99000"" face=""Microsoft Tai le"">
<H2> Server Health Report </H2></font>
<Table border=1 cellpadding=0 cellspacing=0>
<TR bgcolor=gray align=center>
<TD><B>Server Name</B></TD>
<TD><B>Avrg.CPU Utilization</B></TD>
<TD><B>Memory Utilization</B></TD>
<TD><B>Drive C Free Space</B></TD>
</TR>"
Foreach($Entry in $Result)
{
if(($Entry.CpuLoad) -or ($Entry.memload) -ge "80")
{
$Outputreport += "<TR bgcolor=white>"
}
else
{
$Outputreport += "<TR>"
}
$Outputreport += "<TD>$($Entry.Servername)</TD><TD align=center>$($Entry.CPULoad)</TD><TD align=center>$($Entry.MemLoad)</TD><TD align=center>$($Entry.CDrive)</TD></TR>"
}
$Outputreport += "</Table></BODY></HTML>"
}
$Outputreport | out-file "D:\Result $(Get-Date -Format yyy-mm-dd-hhmm).htm"