Automazione di Windows Update in W10 e WS2016

In determinati scenari può essere utile creare un’automazione per gli aggiornamenti di windows in modo da eseguire manualmente l’operazione in modo rapido o per creare script che eseguano il processo di aggiornamento.

A seconda degli scenari è possibile automatizzare il processo di aggiornamento del sistema in modi diversi.

Metodo 1: Avvio diretto della funzionalità Windows Update delle Impostazioni di Windows

E’ possibile aprire direttamente la funzionalità Windows Update e avviare la ricerca degli aggiornamenti tramite il seguente comando:

explorer ms-settings:windowsupdate-action

Metodo 2: Avvio di Windows Update a riga di comando in modalità interattiva

Nei sistemi operativi server è presente lo script WUA_SearchDownloadInstall.vbs che permette di eseguire a riga di comando Windows Update.

Lo script è memorizzato in una posizione diversa a seconda della localizzazione del sistema operativo:

  • nei sistemi operativi server installati in lingua inglese si trova in C:\Windows\System32\en-US
  • nei sistemi operativi server installati in lingua italiana si trova in C:\Windows\System32\it-IT

Per avviare lo script in un sistema operativo server installato il lingua italiana è possibile utilizzare il seguente comando che dovrà essere avviato con privilegi amministrativi:

cscript %SystemRoot%\System32\it-IT\WUA_SearchDownloadInstall.vbs

Lo script chiederà come e se procedere all’aggiornamento in modo interattivo.

Ovviamente è possibile prendere spunto da questo script per creare uno script che esegue l’installazione in modo automatizzato e non interattivo. Scott Vintinner, ad esempio, ha reso disponibile nel suo repository su GitHub https://gist.github.com/flakshack un esempio di script ispirato a WUA_SearchDownloadInstall.vbs e disponibili al seguente flakshack / WUA_SearchDownloadInstall.vbs.

Metodo 3: Automazione di Windows Update tramite PowerShell

Michal Gajda (Microsoft MVP per Cloud and Datacenter Management) ha reso disponibile sul TechNet ScriptCenter il Windows Update PowerShell Module attualmente alla versione 1.5.1.11.

Il Windows Update PowerShell Module è anche disponibile sulla PowerShell Gallery al seguente PSWindowsUpdate dove attualmente è disponibile la versione 1.5.2.2.

Prima di utilizzare il modulo è necessario abilitare il download per altri prodotti Microsoft nelle Opzioni avanzate di Windows Update per evitare l’errore “Can’t find registered service Microsoft Update. Use Get-WUServiceManager to get registered service” durante l’esecuzione del cmdlet Get-WUInstall. In alternativa è possibile eseguire tale impostazione tramite PowerShell tramite il cmdlet Add-WUServiceManager del Windows Update PowerShell Module:

Add-WUServiceManager -ServiceID 7971f918-a847-4430-9279-4a52d1efe18d

Il motivo della necessità di configurare tale impostazione è stato spiegato nel seguente post https://www.petri.com/manage-windows-updates-with-powershell-module:

“When applying updates, I prefer connecting to the Microsoft Update servers. Using these instead of the standard Windows Update servers allows installing updates to Office and other Microsoft products in addition to the normal Windows updates. Unfortunately, trying to connect to the Microsoft Update servers using the PSWindowsUpdate module from a fresh Windows installation will produce an error”

“The reason for this error is because Windows is registered to use only the standard Windows Update servers by default. To use the Microsoft Update servers, the Microsoft Update Service must be registered on the computer. In the GUI, this is done by selecting the checkbox for Give me updates for other Microsoft products when I update Windows from the Control Panel – Windows Update – Change Settings applet”

“In the PSWindowsUpdate module, the same process is completed by using the Add-WUServiceManager cmdlet with the ServiceID for the Microsoft Update service specified. Type Add-WUServiceManager -ServiceID 7971f918-a847-4430-9279-4a52d1efe18d and press Enter. When prompted, confirm registering the service by typing Y and pressing Enter one more time.”

Grazie al Windows Update PowerShell Module è possibile automatizzate in modo completo l’esecuzione degli aggiornamenti, di seguito alcuni esempi di operazioni che è possibile eseguire:

Elenco degli aggiornamenti disponibili:

Get-WUInstall –MicrosoftUpdate –ListOnly

Installazione interattiva degli aggiornamenti:

Get-WUInstall –MicrosoftUpdate

Installazione degli aggiornamenti con riavvio del sistema se necessario:

Get-WUInstall –MicrosoftUpdate –AcceptAll –AutoReboot

Volendo schedulare il check e l’installazione degli aggiornamenti è possibile creare, ad esempio, nella cartella C:\Scripts il file InstallWindowsUpdates.cmd che avvierà la procedura di aggiornamento del sistema mediante l’esecuzione di uno script PowerShell InstallWindowsUpdates.ps1.

Nell’ esempio seguente lo script InstallWindowsUpdates.ps1 importerà il Windows Update PowerShell Module da una cartella memorizzata in C:\Scripts, eseguirà un log su file delle operazioni eseguite e ne consentirà l’invio tramite mail.

Di seguito il contento del file InstallWindowsUpdates.cmd:

%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy RemoteSigned C:\Scripts\InstallWindowsUpdates.ps1

Di seguito il contento del file InstallWindowsUpdates.ps1:

# *** Impostazioni ***
$modulePSWindowsUpdate = “C:\Scripts\PS-Modules\PSWindowsUpdate-1.5.1.11\PSWindowsUpdate”

$logFilePath = “Path dei file di logs“
$logFileNameSuffix = “LogInstallUpdates”
$logFilesRetained = 10

$sendLogByMail = $TRUE
$smtpServer = “Nome o IP Server SMTP“
$mailFrom = “Indirizzo mail from“
$mailTo = “Indirizzo mail to“
# ********************

# *** Creazione Log Path e impostazione Log File Name
$logFileNameBase = $logFilePath + “\” + $logFileNameSuffix
$logFile = $logFileNameBase + “-” + (Get-Date).ToString(“yyyy-MM-dd-HH-mm-ss”) + “.txt”
if (!(Test-Path $logFilePath)){
New-Item $logFilePath -type directory
}

# Ricerca e installazione aggiornamenti
(Get-Date).ToString(“yyyy-MM-dd HH:mm:ss”) + ” Ricerca aggiornamenti da installare” | Out-File $logFile -append

Import-Module $modulePSWindowsUpdate
Get-WUInstall –MicrosoftUpdate –AcceptAll | Out-File $logFile -append

# Invio Log File
If ($sendLogByMail){
$mailSubject = “Installazione aggiornamenti computer ” + $env:computername
$mailBody = Get-Content $logFile | Out-String

Send-MailMessage -To $mailTo -Subject $mailSubject -From $mailFrom -Body $mailBody -SmtpServer $smtpServer -Encoding Default
(Get-Date).ToString(“yyyy-MM-dd HH:mm:ss”) + ” Invio log tramite mail eseguito” | Out-File $logFile -append
}

# Eliminazione log file obsoleti
$logFiles = Get-ChildItem $logFilePath –PipelineVariable item | Where {$item.psIsContainer -eq $false -and $item.FullName -like ($logFileNameBase + “*”)} | Sort FullName
If ($logFiles.Count -gt $logFilesRetained){
For ($i = 1; $i -le $logFiles.Count – $logFilesRetained; $i++) {
(Get-Date).ToString(“yyyy-MM-dd HH:mm:ss”) + ” Eliminazione log file ” + $logFiles[$i-1].FullName | Out-File $logFile -append
Remove-Item $logFiles[$i-1].FullName | Out-File $logFile -append
}
}