How to monitor CPU, RAM, and Disk Space on a Windows Server with PowerShell and get Email alerts

Configurare noua (How To)

Situatie

Solutie

Step 1: Create the monitoring script

powershell
New-Item -Path "C:\Scripts" -ItemType Directory -Force
notepad C:\Scripts\Monitor-Resources.ps1

Step 2: Write the resource-checking logic

Add the following to the file:

powershell
# --- Threshold settings ---
$thresholdCPU  = 85   # percent
$thresholdRAM  = 85   # percent
$thresholdDisk = 90   # percent used

# --- Email settings ---
$smtpServer = "smtp.office365.com"
$smtpPort   = 587
$from       = "server-alerts@yourdomain.com"
$to         = "admin@yourdomain.com"
$smtpUser   = "server-alerts@yourdomain.com"
$smtpPass   = ConvertTo-SecureString "APP_PASSWORD_HERE" -AsPlainText -Force
$cred       = New-Object System.Management.Automation.PSCredential($smtpUser, $smtpPass)

$alerts = @()

# --- Check CPU ---
$cpu = (Get-Counter '\Processor(_Total)\% Processor Time' -SampleInterval 2 -MaxSamples 3 |
        Select-Object -ExpandProperty CounterSamples |
        Measure-Object -Property CookedValue -Average).Average

if ($cpu -gt $thresholdCPU) {
    $alerts += "CPU at $([math]::Round($cpu,1))% (threshold: $thresholdCPU%)"
}

# --- Check RAM ---
$os = Get-CimInstance Win32_OperatingSystem
$ramUsedPercent = [math]::Round((($os.TotalVisibleMemorySize - $os.FreePhysicalMemory) / $os.TotalVisibleMemorySize) * 100, 1)

if ($ramUsedPercent -gt $thresholdRAM) {
    $alerts += "RAM at $ramUsedPercent% (threshold: $thresholdRAM%)"
}

# --- Check disk space ---
$disks = Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3"
foreach ($disk in $disks) {
    $usedPercent = [math]::Round((($disk.Size - $disk.FreeSpace) / $disk.Size) * 100, 1)
    if ($usedPercent -gt $thresholdDisk) {
        $alerts += "Disk $($disk.DeviceID) at $usedPercent% used (threshold: $thresholdDisk%)"
    }
}

# --- Send alert if issues were found ---
if ($alerts.Count -gt 0) {
    $body = "Alerts detected on server $env:COMPUTERNAME at $(Get-Date):`n`n" + ($alerts -join "`n")

    Send-MailMessage -From $from -To $to -Subject "[ALERT] Critical resources on $env:COMPUTERNAME" `
        -Body $body -SmtpServer $smtpServer -Port $smtpPort -UseSsl `
        -Credential $cred
}

Step 3: Test the script manually

powershell
powershell.exe -ExecutionPolicy Bypass -File "C:\Scripts\Monitor-Resources.ps1"

Check whether any errors appear when sending the email (usually related to SMTP authentication or the provider’s security policies).

Step 4: Create a scheduled task to run it periodically

Open PowerShell as administrator and run:

powershell
$action = New-ScheduledTaskAction -Execute "powershell.exe" `
    -Argument '-NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\Monitor-Resources.ps1"'

$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) `
    -RepetitionInterval (New-TimeSpan -Minutes 15) `
    -RepetitionDuration (New-TimeSpan -Days 3650)

Register-ScheduledTask -TaskName "MonitorServerResources" `
    -Action $action -Trigger $trigger -RunLevel Highest `
    -User "SYSTEM"

This task will run the script every 15 minutes, using the system account (no logged-in user required).

Step 5: Verify the scheduled task

powershell
Get-ScheduledTask -TaskName "MonitorServerResources" | Get-ScheduledTaskInfo

Confirm that LastRunTime and NextRunTime look correct.

Step 6 (optional): Add a local alert log

Add this before the email-sending block:

powershell
if ($alerts.Count -gt 0) {
    $body | Out-File -Append -FilePath "C:\Scripts\alerts-log.txt"
}

This keeps a local history, useful for retroactive analysis.

Additional recommendations

  • For Gmail, use an “App Password”, not your regular account password
  • Adjust the thresholds ($thresholdCPU, $thresholdRAM, $thresholdDisk) based on the specific server
  • To avoid alert spam, you can add a “cooldown” logic so alerts aren’t resent more than once per hour.

Tip solutie

Permanent

Voteaza

(16 din 29 persoane apreciaza acest articol)

Despre Autor

Leave A Comment?