Skip to content

WSUS Report — PowerShell

Automate WSUS reporting: HTML, multilingual email (EN/FR/ES), KPIs (up-to-date / need updates / errors), and scheduled execution (Task Scheduler).

Buy via PayPal Contact


Key features

  • Outputs: report.html (responsive)
  • Multilingual email: EN / FR / ES
  • KPIs: Up-to-date, Need updates, Errors (optional D-1/D-7 deltas)
  • Deployment: manual run or Windows Task Scheduler

Screenshots


How it works (overview)

  1. Connects to the WSUS API
  2. Computes indicators
  3. Renders HTML + CSV
  4. Sends a multilingual email with attachments

EXCERPT — The full script is available for purchase.

This excerpt is intentionally non-functional and shows only structure & style.


EXCERPT — The full script is available for purchase.

This excerpt is intentionally non-functional and shows only structure & style.

<#
  Wsus-Reports_Universal_multilingual_email.ps1
  Rapport HTML WSUS multilingue (FR / EN / ES) avec auto-détection de langue.
  - Auto WSUS (Registre) + override -Server/-UseSSL/-Port
  - Module UpdateServices ou fallback DLL
  - JS ES5, perfs ExplainDays, CSV groupes, nettoyage MaxKeep
  - libellés HTML + messages console + parsing anciens rapports (FR/EN/ES)
#>

param(
  # --- Langue ---
  [string]$Lang = 'en',              # 'auto' | 'fr' | 'en' | 'es'

  # --- Connexion WSUS (laisser vides pour autodétection locale) ---
  [string]$Server,
  [Nullable[bool]]$UseSSL,
  [int]$Port,

  # --- Options globales ---
  [int]   $StaleDays = 30,
  [string]$OutDir    = 'C:\WSUS-Reports',
  [switch]$OpenWhenDone,
  [switch]$ExportCsv,
  [int]   $MaxKeep   = 3,

  # --- Onglet "Mises a jour recentes" ---
  [int]   $DaysRecent = 30,
  [int]   $MaxRecentUpdates = 30,
  [bool]  $ApprovedOnly = $true,
  [bool]  $IncludeSuperseded = $false,

  # --- Onglet "Pourquoi ces postes ?" ---
  [int]   $ExplainTop = 15,
  [bool]  $ExplainApprovedOnly = $false,
  [bool]  $ExplainIncludeSuperseded = $true,
  [int]   $ExplainDays = 120,

  # --- Onglet Upgrades ---
  [bool]  $AddUpgradesTab = $true,
  [bool]  $UpgradesApprovedOnly = $false,

  # --- Email (SMTP uniquement) ---
  [ValidateSet('None','SMTP')]
  [string]$MailMode = 'None',

  [string]$MailFrom,
  [string]$MailTo,
  [string]$MailCc,
  [string]$MailBcc,
  [string]$MailSubject,
  [string]$MailBodyHtml,

  # SMTP
  [string]$SmtpServer,
  [int]$SmtpPort = 25,
  [bool]$SmtpUseSsl = $false,
  [string]$SmtpUser,
  [securestring]$SmtpPassword
)

# --- BLOC CONFIG EMAIL (centralisé, SMTP relay) ---
$EmailConfig = @{
  Enabled       = $true
  MailMode      = 'SMTP'
  MailFrom      = 'xxx@xxx.xx'
  MailTo        = 'xxx@xxx.xx'
  MailCc        = ''
  MailBcc       = ''
  MailSubject   = 'WSUS Report'
  MailBodyHtml  = ''

  SmtpServer    = 'xxx'
  SmtpPort      = 25
  SmtpUseSsl    = $true
  SmtpUser      = 'xxx@xxx.xx'
  SmtpPasswordPath = ''
}

# --- MERGE CONFIG -> VARIABLES si pas déjà passées en paramètre ---
if ($EmailConfig.Enabled) {
  if ($MailMode -eq 'None') { $MailMode = $EmailConfig.MailMode }
  foreach($k in 'MailFrom','MailTo','MailCc','MailBcc','MailSubject','MailBodyHtml','SmtpServer','SmtpPort','SmtpUseSsl','SmtpUser'){
    if(-not $PSBoundParameters.ContainsKey($k) -and $EmailConfig[$k] -ne $null){
      Set-Variable -Name $k -Value $EmailConfig[$k] -Scope Script
    }
  }
  if(-not $SmtpPassword -and $EmailConfig.SmtpPasswordPath -and (Test-Path $EmailConfig.SmtpPasswordPath)){
    $SmtpPassword = Get-Content $EmailConfig.SmtpPasswordPath | ConvertTo-SecureString
  }
}

# ---------- i18n ----------
function Resolve-Lang([string]$l){
  if([string]::IsNullOrWhiteSpace($l) -or $l -eq 'auto'){
    try { $l = [System.Globalization.CultureInfo]::CurrentUICulture.TwoLetterISOLanguageName } catch { $l = 'en' }
  }
  switch ($l.ToLower()){
    'fr' { 'fr' }
    'es' { 'es' }
    default { 'en' }
  }
}
$Lang = Resolve-Lang $Lang

function BoolStr([bool]$b){
  switch ($Lang){
    'fr' { if($b){'Oui'}else{'Non'} }
    'es' { if($b){'Sí'}else{'No'} }
    default { if($b){'Yes'}else{'No'} }
  }
}