site1.erralert.com

← Disk & storage

Synology NAS disk health (DSM API) powershell

Logs into a Synology DSM 7 NAS via its HTTP API, reads each disk's health/status/temperature, and posts a summary. Use a dedicated read-only DSM account for `$User` (not your admin login). The login + cookie session avoids embedding long-lived API keys.

Placeholders only. Before running, replace YOUR_URL with your capture endpoint's POST URL . (Open this page from your capture object to have these auto-filled.)
# synology-disk-health.ps1 — DSM 7 disk health summary via HTTP API.
# Run from any Windows box that can reach the NAS on its DSM port (default 5001 HTTPS).

$Url          = "YOUR_URL/synology"
$NasUrl       = "https://nas.local:5001"
$User         = "monitor"
$Pass         = "your-readonly-password"
$SessionName  = "alerts_monitor"

# --- DSM session login ------------------------------------------------------
$Auth = Invoke-RestMethod -Method Get -SkipCertificateCheck `
  -Uri "$NasUrl/webapi/auth.cgi?api=SYNO.API.Auth&version=6&method=login&account=$User&passwd=$Pass&session=$SessionName&format=cookie"
if (-not $Auth.success) {
  $Body = (@{ nas_host = $NasUrl; error = "login failed (code $($Auth.error.code))" }) | ConvertTo-Json -Compress
  Invoke-RestMethod -Uri $Url -Method Post -Body $Body -ContentType "application/json" -TimeoutSec 15 | Out-Null
  exit 1
}
$Sid = $Auth.data.sid

try {
  # --- Read storage info -------------------------------------------------
  $StorageResp = Invoke-RestMethod -Method Get -SkipCertificateCheck `
    -Uri "$NasUrl/webapi/entry.cgi?api=SYNO.Storage.CGI.Storage&version=1&method=load_info&_sid=$Sid"
  if (-not $StorageResp.success) {
    throw "load_info failed (code $($StorageResp.error.code))"
  }

  $Disks         = @{}
  $AnyUnhealthy  = $false
  $MaxTemp       = 0
  foreach ($d in $StorageResp.data.disks) {
    $temp = if ($null -ne $d.temp) { [int]$d.temp } else { 0 }
    if ($temp -gt $MaxTemp) { $MaxTemp = $temp }
    $Disks[$d.id] = @{
      name   = "$($d.name)"
      model  = "$($d.model)"
      status = "$($d.status)"
      temp_c = $temp
    }
    if ($d.status -ne 'normal') { $AnyUnhealthy = $true }
  }

  $Body = (@{
    nas_host       = $NasUrl
    disk_count     = $Disks.Count
    disks          = $Disks
    any_unhealthy  = $AnyUnhealthy
    max_temp_c     = $MaxTemp
  }) | ConvertTo-Json -Compress -Depth 5

  Invoke-RestMethod -Uri $Url -Method Post -Body $Body `
    -ContentType "application/json" -TimeoutSec 15 | Out-Null
} finally {
  # Always log out so DSM doesn't accumulate sessions.
  Invoke-RestMethod -Method Get -SkipCertificateCheck `
    -Uri "$NasUrl/webapi/auth.cgi?api=SYNO.API.Auth&version=6&method=logout&session=$SessionName&_sid=$Sid" | Out-Null
}

Recommended pairing

Add a capture.value check to this capture object.
json_path = any_unhealthy, op = ==, threshold = true (severity: crit). For temperature: json_path = max_temp_c, op = >, threshold = 50.

What is the filename?

synology-disk-health.ps1 — this is the suggested name for the downloaded file. Rename freely if you prefer.