Monday, October 23, 2023

Server Utilization Report - EMAIL Subscription

This PowerShell script, is designed to generate a server utilization report for a list of servers and send the report via email. Here is an overview of the script:

Summary:

  • The script starts with comments containing metadata information, including the file name, author, prerequisites, and copyright notice.

Parameters:

  • servers: An array of server names for which utilization reports will be generated and sent via email.
  • smtpServer: The SMTP server used for sending email.
  • fromEmail: The sender's email address.
  • toEmail: The recipient's email address.
  • subject: The subject line of the email.

Transcript Logging:

  • The script records a transcript of its execution to a log file specified by $logFilePath. The transcript is started using Start-Transcript.

Server List:

  • An array of server names ($servers) is defined.
  • You can provide list of servers in CSV file by giving CSV file path.

HTML Email Body:

  • The script builds an HTML email body in the variable $emailBody. This email body includes sections for each server's information, such as server name, disk utilization, CPU utilization, and memory utilization.

Functions:

  • The script defines three functions to retrieve server information:
    • Get-DiskDetails: Retrieves disk details (Drive, Volume Name, Size, Free Space).
    • Get-CPUUtilization: Retrieves CPU utilization information (Name and LoadPercentage).
    • Get-MemoryUtilization: Retrieves memory utilization information (TotalVisibleMemorySize, FreePhysicalMemory).

Server Information:

  • For each server in the $servers array, the script:
    • Retrieves disk utilization using Get-DiskDetails.
    • Retrieves CPU utilization using Get-CPUUtilization.
    • Retrieves memory utilization using Get-MemoryUtilization.

Email Sending:

  • After gathering server information, the script sends the email with the utilization report to two recipients:
    • The email parameters are set, including SMTP server, sender's email, recipient's email, subject, email body (HTML format), and other parameters.
    • Send-MailMessage is used to send the email to a team group and to an individual.

The email body is formatted in HTML and includes CSS styles for better presentation.

The script uses color coding to highlight high utilization percentages in red, making it easier to identify potential issues. It sends utilization reports for multiple servers to the specified email addresses.

Remember that this script should be run in a PowerShell environment with appropriate permissions to access remote servers and send emails through the specified SMTP server. Additionally, ensure that the required modules or components (e.g., the Send-MailMessage cmdlet) are available and properly configured on the system where the script is executed.


<#
File Name      : ServerUtilizationReport.ps1
Author         : Navinya Ambre
Prerequisite   : This script requires PowerShell and appropriate permissions to access remote servers.
Copyright 2023 by Navinya Ambre. All rights reserved.
 
.SYNOPSIS
This PowerShell script generates a utilization report for a list of servers and sends the report via email.
.DESCRIPTION
This script iterates through a list of servers, retrieves disk usage, CPU, and Memory information for each server, and sends the report via email.
The email contains separate sections for ServerName, Disk Utilization, CPU Utilization, and Memory Utilization.
 
.PARAMETER servers
An array of server names for which utilization reports will be generated and sent via email.
 
.PARAMETER smtpServer
The SMTP server used for sending email.
 
.PARAMETER fromEmail
The sender's email address.
 
.PARAMETER toEmail
The recipient's email address.
 
.PARAMETER subject
The subject line of the email.
#>
 
# Define the path for the log file in the D:\Scripts\ServerUtilizationReport directory.
$logFilePath = "D:\Scripts\ServerUtilizationReport\ServerUtilizationReportLog.txt"
 
# Start recording the transcript to the log file.
Start-Transcript -Path $logFilePath
 
# List of server names
$servers = @(
'server1',
'server2',
'server3'
)
 
# Initialize the email body with HTML headers
$emailBody = "<html lang='en'>
    <head>
        <meta charset='UTF-8'>
        <meta http-equiv='X-UA-Compatible' content='IE-edge'>
        <meta name='viewport' content='width=device-width, initial-scale=1.0'>
        <title>Utilization Reports</title>
        <style>
            body {
                font-family: Calibri, sans-serif, 'Gill Sans', 'Gill Sans MT', 'Trebuchet MS';
                background-color: whitesmoke;
            }
            .mainhead {
                margin: auto;
                width: 100%;
                text-align: center;
                font-size: xx-large;
                font-weight: bolder;
            }
            .subhead {
                margin: auto;
                width: 100%;
                text-align: left;
                font-size: large;
                font-weight: bold;
                color: DodgerBlue;
            }
            .ServerName {
                font-size: x-large;
                margin: 10px;
                text-align: left;
                padding: 10 0;
                color: DarkOrange; /* Changed color to DarkOrange */
            }
            table {
                margin: 10px auto;
                width: 70%;
            }
            .tableheader {
                background-color: black;
                color: white;
                padding: 10px;
                text-align: left;
                border-bottom-style: solid;
                border-bottom-color: darkgray;
            }
            td {
                background-color: white;
                border-bottom: 1px;
                border-bottom-style: solid;
                border-bottom-color: #404040;
            }
 
            .usage {
                background-color: SkyBlue;
                width: 70%;
                color: black;
            }
 
            span {
                color: black;
            }
 
            .td1 {
                background-color: #F0F0F0;
                font-size: 16px; /* Increase font size for output values */
            }
        </style>
    </head>
    <body>
        <div class='mainhead'>
            Utilization Report
        </div>
        <br>
"
 
# Loop through each server and generate a report
foreach ($server in $servers) {
    $computer = $server
 
    # Function to get disk details
    function Get-DiskDetails {
        [CmdletBinding()]
        $cimSessionOptions = New-CimSessionOption -Protocol Default
        $query = "SELECT DeviceID, VolumeName, Size, FreeSpace FROM Win32_LogicalDisk WHERE DriveType = 3"
        $cimsession = New-CimSession -Name $Computer -ComputerName $Computer -SessionOption $cimSessionOptions
        Get-CimInstance -Query $query -CimSession $cimsession
    }
 
    # Function to get CPU utilization
    function Get-CPUUtilization {
        $cimSessionOptions = New-CimSessionOption -Protocol Default
        $query = "SELECT Name, LoadPercentage FROM Win32_Processor"
        $cimsession = New-CimSession -Name $Computer -ComputerName $Computer -SessionOption $cimSessionOptions
        Get-CimInstance -Query $query -CimSession $cimsession
    }
 
    # Function to get Memory utilization
    function Get-MemoryUtilization {
        $cimSessionOptions = New-CimSessionOption -Protocol Default
        $query = "SELECT TotalVisibleMemorySize, FreePhysicalMemory FROM Win32_OperatingSystem"
        $cimsession = New-CimSession -Name $Computer -ComputerName $Computer -SessionOption $cimSessionOptions
        Get-CimInstance -Query $query -CimSession $cimsession
    }
 
    $newHtmlFragment = [System.Collections.ArrayList]::new()
 
    # ServerName
    $newHtmlFragment += @"
        <div class='ServerName'>Server: $computer</div>
"@
 
    # Disk Utilization
    $disks = Get-DiskDetails -Computer $computer
    $diskinfo = @()
    foreach ($disk in $disks) {
        [int]$percentUsage = (($disk.Size - $disk.FreeSpace) / $disk.Size) * 100
        $usageColor = if ($percentUsage -gt 85) { 'red' } else { 'black' }
 
        $bars = "<div style='background-color: DodgerBlue; height: 10px; width: $percentUsage%'></div>"
        $diskinfo += [PSCustomObject]@{
            Drive       = $disk.DeviceID
            'Volume Name' = $disk.VolumeName
            Size        = "{0:N2}" -f ($disk.Size/1gb) + " GB"
            'Free Space'  = "{0:N2}" -f ($disk.FreeSpace/1gb) + " GB"
            'Used Space'  = "{0:N2}" -f (($disk.Size - $disk.FreeSpace)/1gb) + " GB"
            '% Used'     = "$percentUsage%"
            ProgressBar = $bars
            UsageColor   = $usageColor
        }
    }
 
    $newHtmlFragment += @"
        <div class='subhead'>Disk Utilization</div>
        <table>
            <tr class='tableheader'>
                <th>Drive</th>
                <th>Volume Name</th>
                <th>Size</th>
                <th>Free Space</th>
                <th>Used Space</th>
                <th>% Used</th>
            </tr>
"@
 
    foreach ($disk in $diskinfo) {
        $newHtmlFragment += @"
            <tr>
                <td class='td1'>$($disk.Drive)</td>
                <td class='td1'>$($disk.'Volume Name')</td>
                <td class='td1'>$($disk.Size)</td>
                <td class='td1'>$($disk.'Free Space')</td>
                <td class='td1' style='color: $($disk.UsageColor)'>$($disk.'Used Space')</td>
                <td class='td1' style='color: $($disk.UsageColor)'>$($disk.'% Used')</td>
            </tr>
"@
    }
 
    $newHtmlFragment += "</table>"
    # CPU Utilization


    $cpuUtilization = Get-CPUUtilization -Computer $computer
    $cpuLoadPercentage = $cpuUtilization.LoadPercentage
    $cpuUsageColor = if ($cpuLoadPercentage -gt 85) { 'red' } else { 'black' }
    $newHtmlFragment += @"
        <div class='subhead'>CPU Utilization</div>
        <table>
            <tr class='tableheader'>
                <th>CPU Name</th>
                <th>CPU Load Percentage</th>
            </tr>
            <tr>
                <td class='td1'>$($cpuUtilization.Name)</td>
                <td class='td1' style='color: $($cpuUsageColor)'>$($cpuUtilization.LoadPercentage)%</td>
            </tr>
        </table>
"@
    # Memory Utilization
    $memoryUtilization = Get-MemoryUtilization -Computer $computer
    $memoryUtilizationPercentage = [math]::Round((1 - ($memoryUtilization.FreePhysicalMemory / $memoryUtilization.TotalVisibleMemorySize)) * 100, 2)
    $memoryUsageColor = if ($memoryUtilizationPercentage -gt 85) { 'red' } else { 'black' }
    $newHtmlFragment += @"
        <div class='subhead'>Memory Utilization</div>
        <table>
            <tr class='tableheader'>
                <th>Total Visible Memory Size</th>
                <th>Free Physical Memory</th>
                <th>Memory Utilization</th>
            </tr>
            <tr>
                <td class='td1'>$($memoryUtilization.TotalVisibleMemorySize) KB</td>
                <td class='td1'>$($memoryUtilization.FreePhysicalMemory) KB</td>
                <td class='td1' style='color: $($memoryUsageColor)'>$($memoryUtilizationPercentage)%</td>
            </tr>
        </table>
"@
    $emailBody += $newHtmlFragment
}
# Complete the HTML email body
$emailBody += "
    </body>
</html>
"
# Send the email to team
$smtpServer = "your SMTP server IP or name"
$smtpPort = "SMTP Port number"
$fromEmail = "ServerUtilizationReport@yourdomain"
$toEmail = "your teams email ID"
$subject = "[IMPORTANT] Server Utilization Report"
$body = $emailBody
$mailParams = @{
    UseSsl = $false
    SmtpServer = $smtpServer
    SmtpPort = $smtpPort
    From = $fromEmail
    To = $toEmail
    Subject = $subject
    Body = $body
    BodyAsHtml = $true
}

Send-MailMessage @mailParams



Please consider this an open forum for sharing your thoughts, modifications, and suggestions regarding the script. Your input and feedback are highly encouraged and valued.

No comments:

Post a Comment