Hai bisogno di mantenere 14 giorni di versioni con Windows Server Backup 2022, ma i backup tendono a sovrascriversi? In questa guida pratica ti mostro come ottenere una retention reale a 14 giorni con uno script PowerShell e due attività pianificate, senza acquistare nuovi strumenti.
Panoramica del problema
Steeve effettua backup giornalieri con Windows Server Backup (WSB) 2022. Usando una cartella di rete o un disco non dedicato, ha visto che i salvataggi si sovrascrivono e non ha trovato un’impostazione per conservare 14 copie. È un comportamento ricorrente quando:
- la destinazione è una cartella di rete (share SMB) usata da un job pianificato;
- si usa un disco non dedicato e WSB gestisce lo spazio cancellando autonomamente versioni più vecchie quando lo spazio si esaurisce;
- si utilizza la modalità “una volta al giorno” verso la stessa destinazione, riusando il catalogo esistente.
Perché accade? Con share o dischi non dedicati WSB non offre un controllo puntuale del “numero di versioni da conservare”. Sui dischi dedicati, WSB mantiene più versioni finché c’è spazio; su share di rete e dischi non dedicati può riutilizzare il contenuto preesistente, e quando lo spazio scarseggia elimina i punti più vecchi.
Obiettivo della soluzione
Ottenere una retention certa di 14 giorni anche su share o dischi non dedicati, senza rinunciare a WSB. Lo faremo con due componenti:
- Script di backup: ogni esecuzione salva su una sottocartella distinta (timbrata con data/ora) quando la destinazione è una cartella di rete. In alternativa, su un disco locale non dedicato useremo WSB normalmente e affiancheremo un comando di “purge”.
- Script di pulizia: rimuove i backup più vecchi di 14 giorni (oppure mantiene solo gli ultimi N eseguiti).
Attenzione importante
- Local path vs. network path:
-backupTarget:accetta la radice di un volume locale (es.E:) oppure un percorso UNC di rete (es.\\filesrv\wsb$\). Non puoi indicare una sottocartella locale comeC:\Backups\2025-10-25. La tecnica della cartella “con timestamp” si applica quindi alle condivisioni di rete (puoi usare\\filesrv\share\2025-10-25), non a percorsi locali. - Non destinare mai i backup alla stessa unità che stai proteggendo.
- Esegui gli script e le attività con un account di servizio che abbia permessi di lettura/scrittura sulla share e privilegi amministrativi sul server.
Architettura della soluzione
Lo schema logico è semplice:
- Cartella base sulla share (es.
\\filesrv01\CompanyBackups\SRV-APP01). - Ogni giorno, lo script crea una sottocartella data-ora (es.
2025-10-25_230000) e avviawbadminverso quella sottocartella. WSB genererà al suo interno la strutturaWindowsImageBackup<ComputerName>. - Uno script di pulizia cancella le sottocartelle più vecchie di 14 giorni (o mantiene le ultime 14 esecuzioni).
- Operazioni pianificate avviano i due script secondo orari stabiliti.
Prerequisiti
- Windows Server 2022 con Windows Server Backup installato (funzionalità “Backup di Windows Server”).
- Una condivisione di rete con spazio adeguato (o un disco locale non dedicato separato dal sistema, es.
E:). - Un account di servizio (dominio o locale) con: Log on as a batch job, diritti amministrativi sul server e accesso in scrittura alla share.
Script di backup
Versione per cartella di rete con sottocartella timbrata:
# Backup-Wsb-Network.ps1
param(
[Parameter(Mandatory=$true)]
[string]$ShareBase, # es: \\filesrv01\CompanyBackups\SRV-APP01
[string[]]$IncludeVolumes = @("C:"), # oppure vuoto e usare -AllCritical
[switch]$AllCritical,
[switch]$SystemState,
[string]$LogPath = "C:\Logs\WSB"
)
--- Preparazione ---
$stamp = Get-Date -Format 'yyyy-MM-dd_HHmmss'
$targetPath = Join-Path -Path $ShareBase -ChildPath $stamp
New-Item -ItemType Directory -Path $targetPath -Force | Out-Null
New-Item -ItemType Directory -Path $LogPath -Force | Out-Null
$logFile = Join-Path $LogPath "Backup-$stamp.log"
Start-Transcript -Path $logFile -Append | Out-Null
try {
$args = @("start","backup","-backupTarget:`"$targetPath`"","-quiet")
if ($AllCritical) {
$args += "-allCritical"
} elseif ($IncludeVolumes.Count -gt 0) {
$args += "-include:" + ($IncludeVolumes -join ",")
}
if ($SystemState) { $args += "-systemState" }
Per evitare il truncate dei log applicativi (Exchange/SQL), valuta: $args += "-vssCopy"
```
Write-Host "Esecuzione: wbadmin $($args -join ' ')"
$p = Start-Process -FilePath "wbadmin.exe" -ArgumentList $args -Wait -NoNewWindow -PassThru
if ($p.ExitCode -ne 0) { throw "wbadmin ha restituito ExitCode $($p.ExitCode)" }
```
} catch {
Write-Error $_
exit 1
} finally {
Stop-Transcript | Out-Null
}
Note operative:
- Esegui l’attività pianificata come account di servizio con accesso alla share; in questo modo non servono parametri
-user/-passwordnello script. - Se devi usare credenziali dedicate per la share, puoi registrarle in modo sicuro sul server con
cmdkey /add:filesrv01 /user:DOMINIO\account /pass:. - Se fai più run al giorno, il timestamp con
HHmmssevita collisioni.
Variante per disco locale non dedicato
Quando la destinazione è un volume locale (es. E:), WSB non accetta sottocartelle. Usa quindi un backup standard e affianca la pulizia per numero di versioni con wbadmin delete backup.
# Backup-Wsb-Local.ps1
param(
[Parameter(Mandatory=$true)]
[string]$TargetVolume, # es: E:
[string[]]$IncludeVolumes = @("C:"),
[switch]$AllCritical,
[switch]$SystemState,
[string]$LogPath = "C:\Logs\WSB"
)
$stamp = Get-Date -Format 'yyyy-MM-dd_HHmmss'
New-Item -ItemType Directory -Path $LogPath -Force | Out-Null
$logFile = Join-Path $LogPath "Backup-$stamp.log"
Start-Transcript -Path $logFile -Append | Out-Null
try {
$args = @("start","backup","-backupTarget:$TargetVolume","-quiet")
if ($AllCritical) { $args += "-allCritical" } elseif ($IncludeVolumes.Count -gt 0) { $args += "-include:" + ($IncludeVolumes -join ",") }
if ($SystemState) { $args += "-systemState" }
```
Write-Host "Esecuzione: wbadmin $($args -join ' ')"
$p = Start-Process -FilePath "wbadmin.exe" -ArgumentList $args -Wait -NoNewWindow -PassThru
if ($p.ExitCode -ne 0) { throw "wbadmin ha restituito ExitCode $($p.ExitCode)" }
```
} catch {
Write-Error $_
exit 1
} finally {
Stop-Transcript | Out-Null
}
Script di pulizia (retention a 14 giorni)
Per share di rete con sottocartelle datate:
# Cleanup-Wsb-Network.ps1
param(
[Parameter(Mandatory=$true)]
[string]$ShareBase, # es: \\filesrv01\CompanyBackups\SRV-APP01
[int]$DaysToKeep = 14,
[switch]$WhatIf
)
$cutoff = (Get-Date).AddDays(-$DaysToKeep)
Cancella solo cartelle che NON sono vuote e più vecchie della soglia
$oldFolders = Get-ChildItem -Directory $ShareBase -ErrorAction Stop |
Where-Object { $_.LastWriteTime -lt $cutoff }
foreach ($folder in $oldFolders) {
if ($WhatIf) {
Write-Host "[WhatIf] Eliminerei: $($folder.FullName)"
} else {
Write-Host "Elimino: $($folder.FullName)"
Remove-Item -LiteralPath $folder.FullName -Recurse -Force -ErrorAction Stop
}
}
Se preferisci mantenere semplicemente le ultime 14 esecuzioni (indipendentemente dai giorni):
# Mantieni solo le ultime 14 cartelle per data di modifica
param(
[Parameter(Mandatory=$true)]
[string]$ShareBase,
[int]$KeepLast = 14,
[switch]$WhatIf
)
$ordered = Get-ChildItem -Directory $ShareBase | Sort-Object LastWriteTime -Descending
$toDelete = $ordered | Select-Object -Skip $KeepLast
foreach ($folder in $toDelete) {
if ($WhatIf) { Write-Host "[WhatIf] Eliminerei: $($folder.FullName)" }
else { Remove-Item -LiteralPath $folder.FullName -Recurse -Force }
}
Per volume locale (nessuna sottocartella):
# Cleanup-Wsb-KeepVersions.ps1
param(
[Parameter(Mandatory=$true)]
[string]$TargetVolume = "E:", # Volume destinazione del backup
[int]$KeepVersions = 14
)
Rimuove le versioni oltre la quattordicesima
$cmd = "delete","backup","-backupTarget:$TargetVolume","-keepVersions:$KeepVersions","-quiet"
Write-Host "Esecuzione: wbadmin $($cmd -join ' ')"
Start-Process -FilePath "wbadmin.exe" -ArgumentList $cmd -Wait -NoNewWindow
Pianificazione con Utilità di pianificazione (Task Scheduler)
Attività: backup giornaliero
- Apri Utilità di pianificazione → Crea attività….
- Scheda Generale:
- Nome: WSB – Backup giornaliero
- Esegui indipendentemente dalla connessione (se laptop) e Esegui con i privilegi più elevati.
- Configura per: Windows Server 2022.
- Account: l’account di servizio creato.
- Scheda Trigger: Nuovo → Ogni giorno, orario desiderato (es. 23:00).
- Scheda Azioni:
- Programma/Script:
powershell.exe - Aggiungi argomenti:
- Per share:
-NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\Backup-Wsb-Network.ps1" -ShareBase "\\filesrv01\CompanyBackups\SRV-APP01" -AllCritical - Per volume locale:
-NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\Backup-Wsb-Local.ps1" -TargetVolume E: -AllCritical
- Per share:
- Avvia in:
C:\Scripts(cartella in cui risiedono gli script).
- Programma/Script:
- Scheda Condizioni: deseleziona sospensione se server “always on”.
- Scheda Impostazioni: abilita “Esegui il task il prima possibile se viene mancata l’esecuzione pianificata”.
Attività: pulizia retention
- Crea una seconda attività: WSB – Retention 14 giorni.
- Trigger: giornaliero alle 05:00 (o settimanale se preferisci).
- Azioni:
- Per share:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\Cleanup-Wsb-Network.ps1" -ShareBase "\\filesrv01\CompanyBackups\SRV-APP01" -DaysToKeep 14 - Per volume locale:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\Cleanup-Wsb-KeepVersions.ps1" -TargetVolume E: -KeepVersions 14
- Per share:
Verifica dei risultati
- Su share: controlla che in
\\filesrv01\CompanyBackups\SRV-APP01ci siano sottocartelle per ogni esecuzione (es.2025-10-25_230000), ciascuna conWindowsImageBackup<Server>. - Su volume locale: verifica le versioni disponibili con:
wbadmin get versions -backupTarget:E: - Controlla il Visualizzatore eventi → Applicazioni e servizi → Microsoft → Windows → Backup → Operativo per conferme/suggerimenti di errore.
- Esamina i log in
C:\Logs\WSBcreati dagli script (Transcript PowerShell).
Dimensionare la retention: quanta capacità serve?
WSB fa incrementali a livello blocco dopo il primo run. Come ordine di grandezza:
- Primo giorno: full (dimensione prossima al totale dei dati selezionati).
- Giorni successivi: solo blocchi cambiati. Il rapporto varia in base alla variazione quotidiana (per molti server applicativi 2–10%).
Per 14 giorni, una stima prudenziale è: Spazio ≈ 1×Full + 13×(Δ giornaliero). Esempio: full 500 GB e delta 5% (25 GB/giorno) → 500 + 13×25 = 825 GB. Aggiungi un margine 20–30% per sicurezza.
Note integrative utili (riassunto)
| Tema | Dettagli pratici |
|---|---|
| Disco dedicato | Se inizializzi un disco dedicato con WSB, il tool mantiene automaticamente più versioni finché c’è spazio; non serve lo script di pulizia, ma non controlli il numero esatto di copie. |
| Comandi alternativi | wbadmin delete backup -keepVersions:14 -backupTarget:<dest> -quiet rimuove le versioni oltre la quattordicesima. Inseriscilo in uno script e pianificalo, soprattutto quando la destinazione è un volume locale. |
| Altre opzioni | Per retention avanzata (GFS, cifratura, test automatici, report), considera soluzioni terze come Azure Backup, Veeam, Hornet/Altaro, ecc., che includono motori di copia e purge nativi. |
| VSS Full vs Copy | -vssFull può comportare il truncate dei log applicativi; se integri con altri backup applicativi, usa -vssCopy per non alterare lo stato dei log. |
| System State | Puoi aggiungere -systemState per proteggere AD, registry, driver, ecc. Valuta l’impatto di spazio/tempo e la frequenza (anche settimanale). |
| Compatibilità percorsi | Sui percorsi locali è richiesta la radice del volume (es. E:). Le sottocartelle sono supportate solo sui percorsi UNC (es. \\server\share\2025-10-25). |
| Fusi orari & locali | Evita %date% dei file batch (dipende dal locale). In PowerShell usa Get-Date -Format 'yyyy-MM-dd_HHmmss' per nomi consistenti e ordinabili. |
Troubleshooting rapido
- Permessi share: errori di accesso → verifica NTFS e condivisione (lettura/scrittura) per l’account di servizio; se necessario registra credenziali con
cmdkey. - Target non valido: “Sintassi del nome file o directory non corretta” → stai usando una sottocartella locale; passa a
E:oppure usa una share UNC. - Spazio insufficiente: pianifica la pulizia prima del backup o aumenta la capacità. Verifica dimensioni con
wbadmin get versionse occupazione della share. - Verifica riuscita: gli eventi 4xx nel log Microsoft-Windows-Backup/Operativo indicano esiti e dettagli di eventuali errori.
FAQ
Posso combinare copia giornaliera e full settimanale?
WSB non espone policy GFS. La combinazione più semplice è mantenere il job giornaliero e cambiare solo la retention (es. 14 giorni) con lo script di pulizia; per GFS nativo valuta un software di backup dedicato.
Faccio due backup al giorno: come regolo la retention?
Usa la variante “mantieni ultime N esecuzioni” (ad esempio 28 per due settimane × due run/dì) oppure mantieni per giorni ma con timestamp a minuti/secondi.
Come includo più volumi?
Passa -include:C:,D:,E: oppure usa -allCritical per proteggere i volumi necessari all’avvio e al ripristino bare-metal.
Come ripristino?
Apri WSB → Ripristina, indica il percorso della share e scegli data/ora. In alternativa usa wbadmin start recovery con i parametri opportuni.
Risultato
Implementando lo script di backup e lo script di pulizia più le due attività pianificate, Steeve ha confermato che i backup non si sovrascrivono più e che le copie più vecchie vengono eliminate automaticamente dopo 14 giorni. Il risultato è una retention stabile e verificabile con gli strumenti nativi di Windows Server Backup 2022, senza costi aggiuntivi.
Esempi di invocazione (pronti all’uso)
Backup su share con allCritical:
powershell.exe -NoProfile -ExecutionPolicy Bypass ^
-File "C:\Scripts\Backup-Wsb-Network.ps1" ^
-ShareBase "\\filesrv01\CompanyBackups\SRV-APP01" -AllCritical
Pulizia giornaliera > 14 giorni:
powershell.exe -NoProfile -ExecutionPolicy Bypass ^
-File "C:\Scripts\Cleanup-Wsb-Network.ps1" ^
-ShareBase "\\filesrv01\CompanyBackups\SRV-APP01" -DaysToKeep 14
Backup su volume E: e purge per versioni:
powershell.exe -NoProfile -ExecutionPolicy Bypass ^
-File "C:\Scripts\Backup-Wsb-Local.ps1" -TargetVolume E: -AllCritical
powershell.exe -NoProfile -ExecutionPolicy Bypass ^
-File "C:\Scripts\Cleanup-Wsb-KeepVersions.ps1" -TargetVolume E: -KeepVersions 14
Checklist finale
- Script salvati in
C:\Scriptse testati manualmente (PowerShell come amministratore). - Account di servizio con diritti adeguati e accesso alla share.
- Due attività pianificate create, con Run with highest privileges e log attivo.
- Cartella base su share: sottocartelle per data generate correttamente.
- Pulizia: sottocartelle oltre 14 giorni rimosse.
- Spazio: capacità pianificata con margine.
In sintesi: Windows Server Backup non espone un selettore “conserva N versioni” su share o dischi non dedicati. L’approccio combinato script di backup + script di pulizia + attività pianificate consente di raggiungere la retention a 14 giorni in modo affidabile e controllabile. Se un domani serviranno regole GFS, reporting e test di restore automatici, potrai migrare facilmente a una piattaforma di backup dedicata mantenendo lo stesso layout logico di destinazioni.
Con questa configurazione, la policy richiesta da Steeve è rispettata: i backup si susseguono senza sovrascriversi e i più vecchi vengono rimossi dopo 14 giorni.
