# PowerShell Systems Report | |
# Example usage: .\SystemsReport.ps1 .\list.txt | |
# Remember that list.txt is the file containing a list of Server names to run this against | |
#region Variables and Arguments | |
$users = "youremail@yourcompany.com" # List of users to email your report to (separate by comma) | |
$fromemail = "youremail@yourcompany.com" | |
$server = "yourmailserver.yourcompany.com" #enter your own SMTP server DNS name / IP address here | |
$list = $args[0] #This accepts the argument you add to your scheduled task for the list of servers. i.e. list.txt | |
$computers = get-content $list #grab the names of the servers/computers to check from the list.txt file. | |
# Set free disk space threshold below in percent (default at 10%) | |
$thresholdspace = 20 | |
[int]$EventNum = 3 | |
[int]$ProccessNumToFetch = 10 | |
$ListOfAttachments = @() | |
$Report = @() | |
$CurrentTime = Get-Date | |
#endregion | |
Function Create-PieChart() { | |
param([string]$FileName) | |
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | |
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization") | |
#Create our chart object | |
$Chart = New-object System.Windows.Forms.DataVisualization.Charting.Chart | |
$Chart.Width = 300 | |
$Chart.Height = 290 | |
$Chart.Left = 10 | |
$Chart.Top = 10 | |
#Create a chartarea to draw on and add this to the chart | |
$ChartArea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea | |
$Chart.ChartAreas.Add($ChartArea) | |
[void]$Chart.Series.Add("Data") | |
#Add a datapoint for each value specified in the arguments (args) | |
foreach ($value in $args[0]) { | |
Write-Host "Now processing chart value: " + $value | |
$datapoint = new-object System.Windows.Forms.DataVisualization.Charting.DataPoint(0, $value) | |
$datapoint.AxisLabel = "Value" + "(" + $value + " GB)" | |
$Chart.Series["Data"].Points.Add($datapoint) | |
} | |
$Chart.Series["Data"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Pie | |
$Chart.Series["Data"]["PieLabelStyle"] = "Outside" | |
$Chart.Series["Data"]["PieLineColor"] = "Black" | |
$Chart.Series["Data"]["PieDrawingStyle"] = "Concave" | |
($Chart.Series["Data"].Points.FindMaxByValue())["Exploded"] = $true | |
#Set the title of the Chart to the current date and time | |
$Title = new-object System.Windows.Forms.DataVisualization.Charting.Title | |
$Chart.Titles.Add($Title) | |
$Chart.Titles[0].Text = "RAM Usage Chart (Used/Free)" | |
#Save the chart to a file | |
$Chart.SaveImage($FileName + ".png","png") | |
} | |
Function Get-HostUptime { | |
param ([string]$ComputerName) | |
$Uptime = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $ComputerName | |
$LastBootUpTime = $Uptime.ConvertToDateTime($Uptime.LastBootUpTime) | |
$Time = (Get-Date) - $LastBootUpTime | |
Return '{0:00} Days, {1:00} Hours, {2:00} Minutes, {3:00} Seconds' -f $Time.Days, $Time.Hours, $Time.Minutes, $Time.Seconds | |
} | |
# Assemble the HTML Header and CSS for our Report | |
$HTMLHeader = @" | |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"> | |
<html><head><title>My Systems Report</title> | |
<style type="text/css"> | |
<!-- | |
body { | |
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; | |
} | |
#report { width: 835px; } | |
table{ | |
border-collapse: collapse; | |
border: none; | |
font: 10pt Verdana, Geneva, Arial, Helvetica, sans-serif; | |
color: black; | |
margin-bottom: 10px; | |
} | |
table td{ | |
font-size: 12px; | |
padding-left: 0px; | |
padding-right: 20px; | |
text-align: left; | |
} | |
table th { | |
font-size: 12px; | |
font-weight: bold; | |
padding-left: 0px; | |
padding-right: 20px; | |
text-align: left; | |
} | |
h2{ clear: both; font-size: 130%; } | |
h3{ | |
clear: both; | |
font-size: 115%; | |
margin-left: 20px; | |
margin-top: 30px; | |
} | |
p{ margin-left: 20px; font-size: 12px; } | |
table.list{ float: left; } | |
table.list td:nth-child(1){ | |
font-weight: bold; | |
border-right: 1px grey solid; | |
text-align: right; | |
} | |
table.list td:nth-child(2){ padding-left: 7px; } | |
table tr:nth-child(even) td:nth-child(even){ background: #CCCCCC; } | |
table tr:nth-child(odd) td:nth-child(odd){ background: #F2F2F2; } | |
table tr:nth-child(even) td:nth-child(odd){ background: #DDDDDD; } | |
table tr:nth-child(odd) td:nth-child(even){ background: #E5E5E5; } | |
div.column { width: 320px; float: left; } | |
div.first{ padding-right: 20px; border-right: 1px grey solid; } | |
div.second{ margin-left: 30px; } | |
table{ margin-left: 20px; } | |
--> | |
</style> | |
</head> | |
<body> | |
"@ | |
foreach ($computer in $computers) { | |
$DiskInfo= Get-WMIObject -ComputerName $computer Win32_LogicalDisk | Where-Object{$_.DriveType -eq 3} | Where-Object{ ($_.freespace/$_.Size)*100 -lt $thresholdspace} ` | |
| Select-Object SystemName, DriveType, VolumeName, Name, @{n='Size (GB)';e={"{0:n2}" -f ($_.size/1gb)}}, @{n='FreeSpace (GB)';e={"{0:n2}" -f ($_.freespace/1gb)}}, @{n='PercentFree';e={"{0:n2}" -f ($_.freespace/$_.size*100)}} | ConvertTo-HTML -fragment | |
#region System Info | |
$OS = (Get-WmiObject Win32_OperatingSystem -computername $computer).caption | |
$SystemInfo = Get-WmiObject -Class Win32_OperatingSystem -computername $computer | Select-Object Name, TotalVisibleMemorySize, FreePhysicalMemory | |
$TotalRAM = $SystemInfo.TotalVisibleMemorySize/1MB | |
$FreeRAM = $SystemInfo.FreePhysicalMemory/1MB | |
$UsedRAM = $TotalRAM - $FreeRAM | |
$RAMPercentFree = ($FreeRAM / $TotalRAM) * 100 | |
$TotalRAM = [Math]::Round($TotalRAM, 2) | |
$FreeRAM = [Math]::Round($FreeRAM, 2) | |
$UsedRAM = [Math]::Round($UsedRAM, 2) | |
$RAMPercentFree = [Math]::Round($RAMPercentFree, 2) | |
#endregion | |
$TopProcesses = Get-Process -ComputerName $computer | Sort WS -Descending | Select ProcessName, Id, WS -First $ProccessNumToFetch | ConvertTo-Html -Fragment | |
#region Services Report | |
$ServicesReport = @() | |
$Services = Get-WmiObject -Class Win32_Service -ComputerName $computer | Where {($_.StartMode -eq "Auto") -and ($_.State -eq "Stopped")} | |
foreach ($Service in $Services) { | |
$row = New-Object -Type PSObject -Property @{ | |
Name = $Service.Name | |
Status = $Service.State | |
StartMode = $Service.StartMode | |
} | |
$ServicesReport += $row | |
} | |
$ServicesReport = $ServicesReport | ConvertTo-Html -Fragment | |
#endregion | |
#region Event Logs Report | |
$SystemEventsReport = @() | |
$SystemEvents = Get-EventLog -ComputerName $computer -LogName System -EntryType Error,Warning -Newest $EventNum | |
foreach ($event in $SystemEvents) { | |
$row = New-Object -Type PSObject -Property @{ | |
TimeGenerated = $event.TimeGenerated | |
EntryType = $event.EntryType | |
Source = $event.Source | |
Message = $event.Message | |
} | |
$SystemEventsReport += $row | |
} | |
$SystemEventsReport = $SystemEventsReport | ConvertTo-Html -Fragment | |
$ApplicationEventsReport = @() | |
$ApplicationEvents = Get-EventLog -ComputerName $computer -LogName Application -EntryType Error,Warning -Newest $EventNum | |
foreach ($event in $ApplicationEvents) { | |
$row = New-Object -Type PSObject -Property @{ | |
TimeGenerated = $event.TimeGenerated | |
EntryType = $event.EntryType | |
Source = $event.Source | |
Message = $event.Message | |
} | |
$ApplicationEventsReport += $row | |
} | |
$ApplicationEventsReport = $ApplicationEventsReport | ConvertTo-Html -Fragment | |
#endregion | |
# Create the chart using our Chart Function | |
Create-PieChart -FileName ((Get-Location).Path + "\chart-$computer") $FreeRAM, $UsedRAM | |
$ListOfAttachments += "chart-$computer.png" | |
#region Uptime | |
# Fetch the Uptime of the current system using our Get-HostUptime Function. | |
$SystemUptime = Get-HostUptime -ComputerName $computer | |
#endregion | |
# Create HTML Report for the current System being looped through | |
$CurrentSystemHTML = @" | |
<hr noshade size=3 width="100%"> | |
<div id="report"> | |
<p><h2>$computer Report</p></h2> | |
<h3>System Info</h3> | |
<table class="list"> | |
<tr> | |
<td>System Uptime</td> | |
<td>$SystemUptime</td> | |
</tr> | |
<tr> | |
<td>OS</td> | |
<td>$OS</td> | |
</tr> | |
<tr> | |
<td>Total RAM (GB)</td> | |
<td>$TotalRAM</td> | |
</tr> | |
<tr> | |
<td>Free RAM (GB)</td> | |
<td>$FreeRAM</td> | |
</tr> | |
<tr> | |
<td>Percent free RAM</td> | |
<td>$RAMPercentFree</td> | |
</tr> | |
</table> | |
<IMG SRC="chart-$computer.png" ALT="$computer Chart"> | |
<h3>Disk Info</h3> | |
<p>Drive(s) listed below have less than $thresholdspace % free space. Drives above this threshold will not be listed.</p> | |
<table class="normal">$DiskInfo</table> | |
<br></br> | |
<div class="first column"> | |
<h3>System Processes - Top $ProccessNumToFetch Highest Memory Usage</h3> | |
<p>The following $ProccessNumToFetch processes are those consuming the highest amount of Working Set (WS) Memory (bytes) on $computer</p> | |
<table class="normal">$TopProcesses</table> | |
</div> | |
<div class="second column"> | |
<h3>System Services - Automatic Startup but not Running</h3> | |
<p>The following services are those which are set to Automatic startup type, yet are currently not running on $computer</p> | |
<table class="normal"> | |
$ServicesReport | |
</table> | |
</div> | |
<h3>Events Report - The last $EventNum System/Application Log Events that were Warnings or Errors</h3> | |
<p>The following is a list of the last $EventNum <b>System log</b> events that had an Event Type of either Warning or Error on $computer</p> | |
<table class="normal">$SystemEventsReport</table> | |
<p>The following is a list of the last $EventNum <b>Application log</b> events that had an Event Type of either Warning or Error on $computer</p> | |
<table class="normal">$ApplicationEventsReport</table> | |
"@ | |
# Add the current System HTML Report into the final HTML Report body | |
$HTMLMiddle += $CurrentSystemHTML | |
} | |
# Assemble the closing HTML for our report. | |
$HTMLEnd = @" | |
</div> | |
</body> | |
</html> | |
"@ | |
# Assemble the final report from all our HTML sections | |
$HTMLmessage = $HTMLHeader + $HTMLMiddle + $HTMLEnd | |
# Save the report out to a file in the current path | |
$HTMLmessage | Out-File ((Get-Location).Path + "\report.html") | |
# Email our report out | |
send-mailmessage -from $fromemail -to $users -subject "Systems Report" -Attachments $ListOfAttachments -BodyAsHTML -body $HTMLmessage -priority Normal -smtpServer $server | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment