ITSolution4U - Er. Ashok Prajapati
MCA | Master of Science in Cyber Security
ITSolution4U Er. Ashok Prajapati +91 9824974641

๐Ÿ–ฅ️ How to Create an Automatic Server Monitoring Script Using PowerShell in 2026 - ITSolution4U

๐Ÿ–ฅ️ How to Create an Automatic Server Monitoring Script Using PowerShell in 2026

Monitor CPU, RAM, Disk Space and Windows Services with Automatic Email Alerts | ITSolution4U

๐Ÿ” Introduction

Server monitoring is an essential IT administration task. Windows Servers host business applications, databases, file servers, backup systems, and other critical services. If a server runs out of disk space, experiences high CPU usage, or stops an important service, it can affect business operations.

Instead of checking every server manually, IT administrators can create a PowerShell monitoring script that automatically checks server health and sends email alerts when defined thresholds are exceeded.

In this tutorial, you will learn how to:

  • ๐Ÿ–ฅ️ Monitor CPU usage.

  • ๐Ÿง  Monitor RAM utilization.

  • ๐Ÿ’พ Check free disk space.

  • ⚙️ Verify important Windows services.

  • ๐Ÿ“ง Send automatic email alerts.

  • ⏰ Run monitoring automatically using Windows Task Scheduler.

  • ๐Ÿ“ Maintain a monitoring log.

Environment: Windows Server 2016, 2019, 2022, or 2025 with Windows PowerShell 5.1. Test on your server version before production deployment.

๐Ÿงฐ 1. Prerequisites

Before creating the script, ensure you have:

  • Administrator access to the Windows Server.

  • Windows PowerShell 5.1.

  • An approved SMTP server or internal mail relay.

  • Permission to send monitoring emails.

  • Windows Task Scheduler access.

  • A dedicated folder for scripts and logs.

Create the monitoring folder by opening PowerShell as Administrator and running:

New-Item -Path "C:\ServerMonitor" -ItemType Directory -Force

๐Ÿ“ 2. Create the PowerShell Monitoring Script

Create a file named ServerMonitor.ps1 in C:\ServerMonitor.

Copy the following script into the file and update the configuration values before using it.

# ITSolution4U - Windows Server Monitoring Script
# PowerShell 5.1

$ErrorActionPreference = "Stop"

# -------- CONFIGURATION --------

$CpuThreshold     = 85
$MemoryThreshold  = 85
$DiskThreshold    = 15
$AlertCooldownMin = 30

# Update these service names for your server.
$ServicesToCheck = @(
    "LanmanServer",
    "W32Time"
)

$SmtpServer = "smtp.yourcompany.com"
$SmtpPort   = 587
$MailFrom   = "server-alerts@yourcompany.com"
$MailTo     = "it-admin@yourcompany.com"

$CredentialFile = "C:\ServerMonitor\smtp-credential.xml"
$LogFile        = "C:\ServerMonitor\monitor.log"
$StateFile      = "C:\ServerMonitor\last-alert.txt"

# -------- LOGGING --------

function Write-Log {
    param([string]$Message)

    $Line = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - $Message"
    Add-Content -Path $LogFile -Value $Line
}

$Alerts = @()

try {
    # -------- CPU MONITORING --------

    $CpuValues = Get-CimInstance Win32_Processor |
        Select-Object -ExpandProperty LoadPercentage

    $CpuUsage = [math]::Round(
        ($CpuValues | Measure-Object -Average).Average, 1
    )

    if ($CpuUsage -ge $CpuThreshold) {
        $Alerts += "High CPU usage: $CpuUsage%"
    }

    # -------- MEMORY MONITORING --------

    $OS = Get-CimInstance Win32_OperatingSystem

    $TotalMemory = [double]$OS.TotalVisibleMemorySize
    $FreeMemory  = [double]$OS.FreePhysicalMemory

    if ($TotalMemory -gt 0) {
        $MemoryUsage = [math]::Round(
            (($TotalMemory - $FreeMemory) / $TotalMemory) * 100, 1
        )

        if ($MemoryUsage -ge $MemoryThreshold) {
            $Alerts += "High memory usage: $MemoryUsage%"
        }
    }

    # -------- DISK MONITORING --------

    $Disks = Get-CimInstance Win32_LogicalDisk `
        -Filter "DriveType=3"

    foreach ($Disk in $Disks) {
        if ($Disk.Size -gt 0) {
            $FreePercent = [math]::Round(
                ($Disk.FreeSpace / $Disk.Size) * 100, 1
            )

            if ($FreePercent -lt $DiskThreshold) {
                $Alerts += "Low disk space on $($Disk.DeviceID): $FreePercent% free"
            }
        }
    }

    # -------- SERVICE MONITORING --------

    foreach ($ServiceName in $ServicesToCheck) {
        $Service = Get-Service -Name $ServiceName `
            -ErrorAction SilentlyContinue

        if ($null -eq $Service) {
            $Alerts += "Required service not found: $ServiceName"
        }
        elseif ($Service.Status -ne "Running") {
            $Alerts += "Service is not running: $ServiceName"
        }
    }

    Write-Log "Check completed. CPU=$CpuUsage%; Memory=$MemoryUsage%"

    # -------- EMAIL ALERT WITH COOLDOWN --------

    if ($Alerts.Count -gt 0) {
        $SendAlert = $true

        if (Test-Path $StateFile) {
            $LastAlertText = Get-Content $StateFile -Raw

            try {
                $LastAlert = [datetime]::Parse($LastAlertText)

                if (((Get-Date) - $LastAlert).TotalMinutes `
                    -lt $AlertCooldownMin) {
                    $SendAlert = $false
                }
            }
            catch {
                Write-Log "Could not read alert cooldown state."
            }
        }

        if ($SendAlert) {
            if (-not (Test-Path $CredentialFile)) {
                throw "SMTP credential file is missing."
            }

            $Credential = Import-Clixml -Path $CredentialFile

            $Subject = "Server Health Alert - $env:COMPUTERNAME"

            $Body = @"
Server Monitoring Alert
Server: $env:COMPUTERNAME
Time: $(Get-Date)

Issues detected:
$($Alerts -join "`r`n")

Please investigate the server health and take appropriate action.
"@

            $Mail = New-Object System.Net.Mail.MailMessage
            $Mail.From = $MailFrom
            $Mail.To.Add($MailTo)
            $Mail.Subject = $Subject
            $Mail.Body = $Body

            $SMTP = New-Object System.Net.Mail.SmtpClient(
                $SmtpServer, $SmtpPort
            )

            $SMTP.EnableSsl = $true
            $SMTP.Credentials = $Credential.GetNetworkCredential()

            try {
                $SMTP.Send($Mail)

                Set-Content -Path $StateFile `
                    -Value (Get-Date).ToString("o")

                Write-Log "Email alert sent successfully."
            }
            finally {
                $Mail.Dispose()
                $SMTP.Dispose()
            }
        }
        else {
            Write-Log "Alert suppressed by cooldown period."
        }
    }
    else {
        Write-Log "No threshold alerts detected."
    }
}
catch {
    Write-Log "ERROR: $($_.Exception.Message)"
    throw
}

How does the script work?

ComponentPurpose
CPU monitoringAlerts at or above 85% usage
RAM monitoringAlerts at or above 85% usage
Disk monitoringAlerts when free space falls below 15%
Service monitoringChecks configured Windows services
SMTP emailSends alerts to the IT administrator
CooldownLimits repeated alert emails to one per 30 minutes
Log fileRecords checks, alerts, and errors

Note: The cooldown is global, so one alert can temporarily suppress another alert during the same period. This starter script does not send recovery notifications and does not replace a dedicated monitoring platform.

๐Ÿ“ง 3. Configure SMTP Credentials Securely

Do not put an email password directly into the script.

For an organization with an approved SMTP server, update the SMTP settings to match its requirements. If authentication is required, run this one-time command under the same Windows account that will run the scheduled task:

Get-Credential |
    Export-Clixml -Path "C:\ServerMonitor\smtp-credential.xml"

Enter the authorized SMTP username and password in the credential prompt.

Important security considerations:

  • Protect the credential file with Windows NTFS permissions.

  • The exported credential is normally protected using Windows DPAPI and is tied to the exporting user and computer.

  • Run the scheduled task under that same account.

  • If your mail provider requires OAuth or does not support basic SMTP authentication, use an approved relay or supported authentication method instead.

  • Confirm that the SMTP port and outbound firewall rules are permitted.

๐Ÿงช 4. Test the Script Manually

Open PowerShell under the account that will run the monitoring job and execute:

Set-Location "C:\ServerMonitor"

.\ServerMonitor.ps1

Review the monitoring log:

Get-Content "C:\ServerMonitor\monitor.log" -Tail 30

Test with appropriate thresholds in a non-production environment, or use a controlled test that does not interrupt business services. Verify that the script records results and that email delivery works before scheduling it.

⏰ 5. Schedule Automatic Monitoring

Windows Task Scheduler can run the script at a recurring interval.

  1. Open Task Scheduler.

  2. Select Create Task.

  3. Enter the name ITSolution4U Server Monitoring.

  4. Configure the task to run under the account that has the required permissions and SMTP credential access.

  5. Under Triggers, create a daily trigger and set it to repeat every 5 minutes for an appropriate duration.

  6. Under Actions, choose Start a program.

  7. Enter the program:

powershell.exe
  1. Enter the arguments:

-NoProfile -NonInteractive -File "C:\ServerMonitor\ServerMonitor.ps1"
  1. Save the task and run it manually once to verify the result.

  2. Check Last Run Result, Task Scheduler history, and the monitoring log.

Avoid overlapping task executions. Configure the task to avoid starting a new instance while a previous instance is still running.

๐Ÿ›ก️ 6. Recommended Monitoring Thresholds

These are starting points, not universal standards. Adjust them according to the workload and baseline of each server.

MetricExample thresholdRecommended action
CPU utilization85% or higherInvestigate sustained load
RAM utilization85% or higherReview memory pressure
Free disk spaceBelow 15%Review growth and capacity
Critical serviceNot runningCheck service and dependencies
Email deliveryFailedReview SMTP configuration and logs

For critical production servers, consider separate warning and critical thresholds, per-alert cooldowns, recovery notifications, and an independent monitoring channel.

๐Ÿ“ˆ 7. Further Improvements

After validating the basic script, you can extend it with:

  • ๐Ÿ“Š Daily server health reports in CSV or HTML.

  • ๐Ÿ–ฅ️ Monitoring multiple Windows servers.

  • ๐Ÿ’พ Backup job and backup repository checks.

  • ๐ŸŒ Network connectivity and latency checks.

  • ๐Ÿ”” Microsoft Teams or other approved notification integrations.

  • ๐Ÿ“… Weekly or monthly health summaries.

  • ๐Ÿ“‰ CPU, RAM, disk, and service status history.

  • ๐Ÿ” Centralized logging and role-based access controls.

For larger environments, compare this custom script with established monitoring platforms such as Zabbix, PRTG, or Prometheus-based solutions. A script is useful for simple automation, but a monitoring platform generally offers stronger dashboards, history, escalation, and centralized management.

❓ Frequently Asked Questions

Can this script run without a logged-in administrator?

Yes, when Task Scheduler is configured with a suitable service or user account and the necessary permissions.

Will it send an email every five minutes?

No. The example uses a 30-minute global cooldown when alerts are detected. It can still send repeated notifications if an issue persists beyond the cooldown.

Can I monitor a Linux server?

This particular script is designed for Windows Server. Linux monitoring would require a different script or monitoring agent.

Does it monitor antivirus, backups, or event logs?

Not in its current form. Those checks can be added separately after validating the core monitoring workflow.

✅ Conclusion

A PowerShell server monitoring script can automate basic checks for CPU usage, memory utilization, disk capacity, and Windows services. By combining the script with SMTP email alerts and Windows Task Scheduler, IT administrators can detect selected server issues sooner and reduce repetitive manual checks.

Always test the script, secure its credentials, and verify alert delivery before using it in a production environment.


๐ŸŒ ITSolution4U — Learn | Solve | Grow

๐ŸŒ Website: https://www.itsolution4u.in
๐Ÿ“ง Email: info@itsolution4u.in
๐Ÿ“ž Contact: +91 9824974641
๐Ÿ“ฑ Social media: @ITSolution4U

Hashtags:
#PowerShell #ServerMonitoring #WindowsServer #ITAutomation #SystemAdministrator #ServerManagement #EmailAlerts #ITSolution4U