#Requires -Version 5.1 <# JbTecWiz Support Centre -- generated fix script Fault : Previous Versions is empty or shadow copies keep disappearing Fix : Size the shadow storage for the rate of change Source: https://jbtecwiz.com/support/srv-sto-shadow Run as : Elevated PowerShell Expect : 30 minutes Risk : medium Reversible : yes WHEN THIS IS THE RIGHT FIX Copies are missing or only the newest survives. HOW TO UNDO IT vssadmin resize shadowstorage with the previous value; existing copies beyond the new limit will be discarded. This script walks the fix one step at a time and asks before each one. Steps with no command are things you do yourself -- it prints those and waits. Run with -DryRun to print without executing. -------------------------------------------------------------------- NO WARRANTY - USE AT YOUR OWN RISK This script is provided by JbTecWiz as-is and with no warranty of any kind, express or implied. You run it entirely at your own risk. JbTecWiz accepts no liability for any loss or damage arising from its use, including but not limited to data loss, downtime, or configuration changes that turn out to be wrong for your system. You are responsible for reading this script before running it, for satisfying yourself that it suits the machine in front of you, and for having a working backup first. Some steps cannot be undone. -------------------------------------------------------------------- #> [CmdletBinding()] param( # Print every step and command without running anything. [switch]$DryRun, # Do not ask before each step. Read the script first if you use this. [switch]$Unattended ) $ErrorActionPreference = 'Stop' $script:Failed = 0 function Write-Rule { param([string]$Text) Write-Host '' Write-Host ('-' * 70) -ForegroundColor DarkGray if ($Text) { Write-Host $Text -ForegroundColor Cyan } } function Show-Prose { param([string]$Text, [string]$Colour = "Gray") if (-not $Text) { return } $words = $Text -split "\s+"; $line = " " foreach ($w in $words) { if (($line.Length + $w.Length) -gt 74) { Write-Host $line -ForegroundColor $Colour; $line = " " } $line += "$w " } if ($line.Trim()) { Write-Host $line -ForegroundColor $Colour } } function Invoke-Step { param( [int]$Number, [string]$Do, [string]$Why, [scriptblock]$Command, [switch]$Manual, [string]$Shell = "powershell" ) Write-Rule " Step $Number of 6" Show-Prose $Do "White" if ($Why) { Write-Host ""; Show-Prose $Why "DarkGray" } if ($Manual) { Write-Host '' Write-Host ' -> Do this yourself, then press Enter to carry on.' -ForegroundColor Yellow if (-not $Unattended -and -not $DryRun) { [void](Read-Host) } return } Write-Host '' foreach ($l in ($Command.ToString().Trim() -split "`n")) { Write-Host (" " + $l.Trim()) -ForegroundColor Green } Write-Host '' if ($DryRun) { Write-Host " (dry run -- not executed)" -ForegroundColor DarkGray; return } if (-not $Unattended) { $a = Read-Host " Run this step? [Y]es / [S]kip / [Q]uit" if ($a -match "^[Qq]") { Write-Host " Stopped at your request."; exit 0 } if ($a -match "^[Ss]") { Write-Host " Skipped." -ForegroundColor DarkGray; return } } try { & $Command } catch { $script:Failed++ Write-Host (" Step $Number failed: " + $_.Exception.Message) -ForegroundColor Red Show-Prose "The rest of the fix may depend on this. Read the write-up before carrying on." "Red" if (-not $Unattended) { $c = Read-Host " Carry on anyway? [y/N]" if ($c -notmatch "^[Yy]") { exit 1 } } } } Write-Rule Write-Host ' Previous Versions is empty or shadow copies keep disappearing' -ForegroundColor White Write-Host ' Size the shadow storage for the rate of change' -ForegroundColor Cyan Write-Host '' Write-Host ' Risk: medium Reversible 30 minutes' Write-Host '' Show-Prose 'No warranty. Use at your own risk - JbTecWiz accepts no liability. Read it before you run it, and have a backup.' 'DarkYellow' Write-Rule if (-not $Unattended -and -not $DryRun) { $go = Read-Host ' Ready? [y/N]' if ($go -notmatch "^[Yy]") { Write-Host " Nothing was changed."; exit 0 } } Invoke-Step -Number 1 -Do 'See what exists and what the storage allocation is.' -Command { vssadmin list shadows vssadmin list shadowstorage } Invoke-Step -Number 2 -Do 'The used space against the maximum tells you immediately whether it is being trimmed. A used figure equal to the maximum means older copies are being discarded to make room.' -Why 'This is the whole fault in one number, and it is why the setting is worth checking before anything else. The snapshots are not failing -- they are succeeding and evicting each other.' -Manual Invoke-Step -Number 3 -Do 'Put the shadow storage on a different volume from the data where possible, which removes the contention entirely.' -Command { vssadmin add shadowstorage /for=E: /on=F: /maxsize=200GB } Invoke-Step -Number 4 -Do 'Or raise the allocation on the same volume.' -Command { vssadmin resize shadowstorage /for=E: /on=E: /maxsize=20% } Invoke-Step -Number 5 -Do 'Check the schedule is sensible. Two snapshots a day on a file server is typical; more than that consumes storage quickly for little benefit.' -Command { Get-ScheduledTask | Where-Object TaskName -like '*ShadowCopy*' | Format-Table TaskName,State } Invoke-Step -Number 6 -Do 'State plainly to whoever asks: shadow copies are not a backup. They live on the same volume as the data and are lost with it.' -Why 'This gets treated as a backup remarkably often. A ransomware event or a failed array takes the snapshots with the data, which is exactly when people discover the distinction.' -Manual Write-Rule " Confirm it worked" Show-Prose 'Multiple shadow copies exist across several days and used space is below the maximum.' 'White' Write-Host '' if (-not $DryRun) { vssadmin list shadows | Select-String 'creation time' | Select-Object -First 10 vssadmin list shadowstorage } Write-Rule if ($script:Failed -gt 0) { Write-Host (" Finished with " + $script:Failed + " failed step(s).") -ForegroundColor Yellow Show-Prose 'Read the full write-up at https://jbtecwiz.com/support/srv-sto-shadow' 'Yellow' } else { Write-Host ' Finished.' -ForegroundColor Green } Write-Host '' Show-Prose 'To undo: vssadmin resize shadowstorage with the previous value; existing copies beyond the new limit will be discarded.' 'DarkGray' Write-Rule