Almost every backup on Windows is taken from a shadow copy rather than from the live volume. The Volume Shadow Copy Service freezes the applications that hold open files, takes a point-in-time copy of the volume, then thaws them. When a backup job fails with nothing useful in its own log, the failure usually happened inside that handshake, and vssadmin is the built-in tool that shows you where.
It is also the tool most often used wrongly. Admins run vssadmin list writers, see the word “Failed” against six components, restart services at random, and never notice that the number in square brackets in front of that word is the actual diagnosis. They shrink shadow storage to reclaim disk space and silently destroy every restore point on the volume. They try to delete a snapshot a backup product created and get an error that reads like a permissions problem but is not.
This page covers what each of those outputs really says, which half of vssadmin Microsoft still documents, and the places where the tool will quietly do something other than what you meant.
Applies to: Windows 10 / 11, Windows Server 2016 / 2019 / 2022 / 2025
Quick answer
Three read-only commands answer almost every question. Run them in this order from an elevated prompt: the writers tell you whether the handshake works, the shadows tell you what exists, and the storage tells you whether there is room for the next one.
rem 1. is any component refusing to take part in a snapshot
vssadmin list writers
rem 2. what snapshots exist right now, and on which volume
vssadmin list shadows
rem 3. how much room the shadow copy area has left before old copies get dropped
vssadmin list shadowstorage
If the first command prints nothing but a banner, no writer is registered, which is a different and much bigger problem than a writer in a failed state. If it prints components with a bracketed number of 6 or higher, read the state table below before you restart anything.
Before the first example
Five things, all of which apply to every example on this page.
1. An elevated prompt. Microsoft’s own walkthroughs run vssadmin “from an elevated command prompt”, and the read-only subcommands are no exception. Open one with Win+X then “Terminal (Admin)”, or elevate from a normal prompt with the first line below. The second line prints a match only when the token really is elevated.
powershell -Command "Start-Process cmd -Verb RunAs"
rem S-1-16-12288 is the High Mandatory Level SID, present only in an elevated token
whoami /groups | findstr /c:"S-1-16-12288"
2. Confirm the service is running. The Volume Shadow Copy service is set to Manual by default and is started on demand, so “Stopped” is normal. Disabled is not, and a disabled VSS service makes every command below return nothing useful.
rem StartType Disabled is the fault; Manual with Stopped is the normal resting state
sc query VSS
sc qc VSS | findstr /c:"START_TYPE"
3. Find out which subcommands your build actually has. This matters more here than for most tools, because the set differs between editions and Microsoft’s current reference no longer lists all of them. The tool prints its own list, and that list is the only authoritative answer for the machine in front of you.
rem the definitive list for THIS machine; compare it against the table in the next section
vssadmin /?
rem and confirm you are running the real binary and not something earlier in PATH
where vssadmin
4. A place to keep output. Several examples save output so you can compare before and after. Create the folder first so no example references a path that does not exist.
md C:\vss-check 2>nul
vssadmin list shadowstorage > C:\vss-check\storage-before.txt
5. Two conventions used throughout. The examples are written for a file server called SRV-FILE-02 with a single data volume on C:. And every loop is shown in its interactive form with a single percent sign, as in %a; inside a .bat file the same loop needs %%a.
resize shadowstorage can delete every shadow copy on a volume, and delete shadows is irreversible. Run the writing examples on a lab machine, and read the current values first so you can put them back.
What vssadmin does, and the half Microsoft still documents
There is no single syntax line. vssadmin is a dispatcher: a verb, a noun, then switches. What is unusual is the documentation. Microsoft’s current reference page lists four subcommands and marks all four “Client and Server”. The archived Windows Server reference lists ten. The six that vanished were never withdrawn in an announcement; they simply stopped being carried forward.
| Subcommand | What it does | Where it is documented |
|---|---|---|
list writers | Lists the subscribed shadow copy writers and the state of each. | Current reference |
list shadows | Lists existing shadow copies, grouped by shadow copy set. | Current reference |
delete shadows | Deletes shadow copies. Client-accessible ones only. | Current reference |
resize shadowstorage | Changes the maximum size of a shadow copy storage association. | Current reference |
list shadowstorage | Lists the shadow copy storage associations and their three sizes. | Archived Server reference only |
list volumes | Lists volumes eligible for shadow copies. | Archived Server reference only |
list providers | Lists the registered shadow copy providers. | Archived Server reference only |
create shadow | Creates a shadow copy of a volume. | Archived Server reference only |
add shadowstorage | Adds a storage association for a volume. | Archived Server reference only |
delete shadowstorage | Deletes a storage association. | Archived Server reference only |
vssadmin /? is the answer. Check there before scripting any of the bottom six.
The three switches that appear across several subcommands are worth learning once.
| Switch | Meaning | Used by |
|---|---|---|
/for=<volume> | The volume being protected, the one whose data is snapshotted. | list shadows, list shadowstorage, delete shadows, resize shadowstorage |
/on=<volume> | The volume where the shadow copy data is stored. Often the same volume, not always. | list shadowstorage, resize shadowstorage |
/shadow=<id> | One specific shadow copy, by the GUID that list shadows printed. | list shadows, delete shadows |
Keeping /for and /on straight is the whole trick with shadow storage. A volume can hold its own shadow copies or somebody else’s, and the sizes reported belong to the storage volume, not to the protected one.
Reading list writers: the number in brackets is the diagnosis
Each writer is a five-line block. The capture below is reproduced from Microsoft’s own troubleshooting article on VSS writers reporting as failed inside a virtual machine, with only the line spacing normalised.
vssadmin 1.1 - Volume Shadow Copy Service administrative command-line tool
(C) Copyright 2001 Microsoft Corp.
Writer name: 'System Writer'
Writer Id: {e8132975-6f93-4464-a53e-1050253ae220}
Writer Instance Id: {0df8b3f5-59ee-4185-983c-f35f16488e17}
State: [9] Failed
Last error: No error
Writer name: 'COM+ REGDB Writer'
Writer Id: {542da469-d3e1-473c-9f4f-7847f01fc64f}
Writer Instance Id: {4a28f97d-5076-4171-b9ac-a0cabd925645}
State: [9] Failed
Last error: No error
Writer name: 'MSDEWriter'
Writer Id: {f8544ac1-0611-4fa5-b04b-f7ee00b03277}
Writer Instance Id: {ecabb5e5-6526-42b4-b008-e74a7ce9edaa}
State: [1] Stable
Last error: No error
Writer name: 'Registry Writer'
Writer Id: {afbab4a2-367d-4d15-a586-71dbb18f8485}
Writer Instance Id: {5ee9aebb-1d30-474d-9562-927ba40e2e4e}
State: [9] Failed
Last error: No error
Writer name: 'WMI Writer'
Writer Id: {a6ad56c2-b509-4e6c-bb19-49d8f43532f0}
Writer Instance Id: {0fe76f97-9185-4bb8-b9da-6ce35be4bc01}
State: [9] Failed
Last error: No error
Writer name: 'Event Log Writer'
Writer Id: {eee8c692-67ed-4250-8d86-390603070d00}
Writer Instance Id: {8a2fd6b9-c349-4d3f-9bc2-046e053bee65}
State: [9] Failed
Last error: No error
Six writers, five of them Failed, one Stable, and every single one reporting “Last error: No error”. That combination looks like a broken machine and is the reason people start restarting services. Read the four fields properly first.
| Field | What it is, and what it is not |
|---|---|
Writer name | The component, in single quotes. Names are not unique across products, but the Writer Id is. |
Writer Id | A fixed GUID per writer class. The same across every machine, so it is the right thing to search a vendor knowledge base for. |
Writer Instance Id | A new GUID for this instance of the writer process. It changes on restart, so it is useless for searching and useful only for correlating with one event log entry. |
State | A number in brackets and a short word. The number is the diagnosis; the word is a summary that throws most of it away. |
Last error | The writer’s own error report, which is independent of the state. “No error” alongside a failed state is a normal and meaningful combination. |
The bracketed number is the VSS_WRITER_STATE value from the VSS API. That enumeration has sixteen named values, and ten of them are failure states which vssadmin prints as the same single word, “Failed”. Each one names the phase of the snapshot handshake the writer refused in, which is what tells you where to look.
| Value | Enumeration name | What it means |
|---|---|---|
| 0 | VSS_WS_UNKNOWN | State not known. The docs call this an error on the writer’s part. |
| 1 | VSS_WS_STABLE | Idle and ready. The only healthy resting state. |
| 2 | VSS_WS_WAITING_FOR_FREEZE | Mid-handshake, waiting for the freeze. |
| 3 | VSS_WS_WAITING_FOR_THAW | Mid-handshake, waiting for the thaw. |
| 4 | VSS_WS_WAITING_FOR_POST_SNAPSHOT | Mid-handshake, waiting for PostSnapshot. |
| 5 | VSS_WS_WAITING_FOR_BACKUP_COMPLETE | Snapshot done, waiting for the backup product to say it has finished. |
| 6 | VSS_WS_FAILED_AT_IDENTIFY | Vetoed before anything started. Usually the writer cannot enumerate its own files. |
| 7 | VSS_WS_FAILED_AT_PREPARE_BACKUP | Vetoed while preparing the backup. |
| 8 | VSS_WS_FAILED_AT_PREPARE_SNAPSHOT | Vetoed during PrepareForSnapshot. |
| 9 | VSS_WS_FAILED_AT_FREEZE | Vetoed during the freeze, the moment I/O is held. |
| 10 | VSS_WS_FAILED_AT_THAW | Vetoed during the thaw, so the snapshot exists but the writer did not resume cleanly. |
| 11 | VSS_WS_FAILED_AT_POST_SNAPSHOT | Vetoed after the snapshot. |
| 12 | VSS_WS_FAILED_AT_BACKUP_COMPLETE | The snapshot was created and the writer failed at BackupComplete. |
| 13 | VSS_WS_FAILED_AT_PRE_RESTORE | Failed during PreRestore. A restore-side failure, not a backup one. |
| 14 | VSS_WS_FAILED_AT_POST_RESTORE | Failed during PostRestore. |
| 15 | VSS_WS_FAILED_AT_BACKUPSHUTDOWN | Failed as the backup application shut down. |
vss.h typedef spells out only VSS_WS_UNKNOWN = 0 and lets the rest follow in sequence. Microsoft’s own captures pin that sequence at two points: [1] Stable lines up with VSS_WS_STABLE, and [5] Waiting for completion lines up with VSS_WS_WAITING_FOR_BACKUP_COMPLETE, five places along. That is why the table above can be read with confidence.
So the capture is five writers vetoing at the freeze, the single most specific failure point in the list. And the reason Microsoft published it is the part that matters: on that platform, the Hyper-V requester deliberately stops the process after the thaw phase to skip autorecovery, the guest writers therefore report failure, and the article’s stated resolution is that no resolution is required. The virtual machine’s state is preserved and the backup is good.
vssadmin list writers when no backup is in progress. A writer that has gone back to [1] Stable was telling you about a job that already finished.
Practical examples
1. Pull the writer states out without losing the names
The problem: forty writers on a file server, and you want only the ones in trouble.
The solution: filter, but filter on the right string. Searching for “Writer” looks obvious and returns three lines per writer, because Writer name, Writer Id and Writer Instance Id all contain it. Against the six-writer capture above that is 18 lines instead of 6.
rem 18 lines: name, Id and Instance Id all match the bare word
vssadmin list writers | findstr "Writer"
rem 6 lines: /c: treats the whole phrase as one literal string to find
vssadmin list writers | findstr /c:"Writer name"
Filtering for the state lines works the same way and gives you the five failures, but with a catch that is easy to miss.
rem returns the state lines only, in order, and nothing else
vssadmin list writers | findstr /c:"State:"
State: [9] Failed
State: [9] Failed
State: [1] Stable
State: [9] Failed
State: [9] Failed
State: [9] Failed
findstr has thrown it away. You now know five writers failed and you cannot say which. Pairing the two fields needs something that remembers the last name it saw, which is what the PowerShell section does.
If you only need the names in a script, for /f will split the label from the value. With delims=: the label becomes token 1 and the value token 2, so token 2 is the name. Keep the findstr in the pipeline: without it the loop would also read the two banner lines at the top of the output, which contain no colon and so yield an empty token 2.
rem token 2 keeps a leading space and the single quotes; strip them later if it matters
for /f "tokens=2 delims=:" %a in ('vssadmin list writers ^| findstr /c:"Writer name"') do @echo %a
2. Find out what snapshots actually exist
The problem: Previous Versions shows nothing for a share, and you need to know whether that is because no snapshot exists or because the ones that exist are not client-accessible.
The solution: list the shadow copies for that volume and read the Type and Attributes lines rather than just counting them. Scoping the command with /for keeps the output readable on a server with several protected volumes.
rem all of them, grouped by shadow copy set
vssadmin list shadows
rem just one volume, which is what you want on a multi-volume file server
vssadmin list shadows /for=C:
rem and one specific copy, using a GUID the previous command printed
vssadmin list shadows /shadow={12345678-1234-1234-1234-123456789abc}
Each entry names its originating machine, its provider, a type and a list of attributes. The type is the field that decides whether Previous Versions can see it and whether vssadmin is allowed to delete it.
3. Read the storage association before you touch it
The problem: restore points keep disappearing on SRV-FILE-02 and nobody has deleted them.
The solution: the shadow copy area has a ceiling, and when it is reached Windows drops the oldest copies to make room. Read all three numbers, because only one of them is a limit.
rem save it first: this is the value you will need if a later resize goes wrong
vssadmin list shadowstorage /for=C: > C:\vss-check\storage-before.txt
type C:\vss-check\storage-before.txt
The Used, Allocated and Maximum section further down reads those three numbers line by line.
4. Delete one snapshot, and understand the refusal
The problem: a volume is short of space and you want the oldest snapshot gone.
The solution: delete exactly one, by age or by ID, and never start with /all. Both commands need the elevated prompt from the prerequisites.
rem the safe form: one copy, the oldest, on one named volume
vssadmin delete shadows /for=C: /oldest
rem or one specific copy by the GUID from list shadows
vssadmin delete shadows /for=C: /shadow={12345678-1234-1234-1234-123456789abc}
rem confirm what is left rather than assuming
vssadmin list shadows /for=C:
If the command refuses with Error: Snapshots were found, but they were outside of your allowed context, nothing is wrong with your permissions. Microsoft’s reference is explicit that vssadmin can only delete shadow copies of the client-accessible type, and the ones a backup product created are not that type. The documented answer is to manage those with diskshadow instead.
vssadmin delete shadows /all /quiet. It destroys every client-accessible copy on the machine with no prompt and no undo, which is exactly why ransomware families use that same line to stop victims recovering. Endpoint protection is tuned to alarm on it, so running it by hand can also cost you an incident review.
5. Resize the storage area, and put it back
The problem: shadow storage on C: is capped too low, so snapshots age out within a day.
The solution: raise the maximum. Both volumes have to be named, even when they are the same volume, and Microsoft’s page carries a plain warning that resizing may cause shadow copies to disappear.
rem /for is the protected volume, /on is where the copies live: both are required
vssadmin resize shadowstorage /for=C: /on=C: /maxsize=20GB
rem a percentage of the volume is accepted too; in a .bat file write 10%% instead of 10%
vssadmin resize shadowstorage /for=C: /on=C: /maxsize=10%
rem and this removes the cap entirely, which is the documented undo
vssadmin resize shadowstorage /for=C: /on=C: /maxsize=UNBOUNDED
rem put it back: take the Maximum out of the file you saved in example 3 and set exactly that
type C:\vss-check\storage-before.txt
vssadmin resize shadowstorage /for=C: /on=C: /maxsize=THE_VALUE_YOU_SAVED
rem then confirm all three numbers match what you started with
vssadmin list shadowstorage /for=C:
Used, Allocated and Maximum
Three numbers per association, and people read the wrong one. The three size lines below are reproduced from a Microsoft storage team blog post about restore point disk usage, for the C: association on the author’s machine.
Used Shadow Copy Storage space: 1.335 GB
Allocated Shadow Copy Storage space: 1.539 GB
Maximum Shadow Copy Storage space: 4.395 GB
| Line | What it measures | Why you care |
|---|---|---|
| Used | Space the existing shadow copies actually occupy. | Grows with the rate of change on the volume, not with its size. |
| Allocated | Space Windows has already reserved for the shadow copy area. | Always at least Used. Reserved in advance, so it looks like waste and is not. |
| Maximum | The ceiling the area may grow to. | The only one that is a setting. Reach it and the oldest copies are dropped. |
The relationship is always Used no greater than Allocated, and Allocated no greater than Maximum. It holds for all three associations in that blog post, and if you ever see it broken you are misreading which association you are looking at.
The interesting part is where Maximum comes from. That author states the rule as the smaller of 30 percent of free space or 15 percent of the volume, decided once when the first shadow copy is created, and explains each of his three volumes with it: a 29.3 GB volume at 15 percent, a 97.66 GB volume at 15 percent, and a 48.83 GB backup target at 30 percent. Run those three multiplications and they give 4.395 GB, 14.649 GB and 14.649 GB against printed Maximum values of 4.395 GB, 14.649 GB and 14.648 GB. Two match to the digit and the third is a rounding step away.
list shadowstorage.
Which brings us to the units, and the most avoidable failure on this page. MaxSizeSpec accepts KB, MB, GB, TB, PB or EB, and if you leave the unit off it is read as bytes. The documented minimum on the current page is 1 MB, so a bare number almost always falls under it.
| What you type | What it means | Against the documented 1 MB minimum |
|---|---|---|
/maxsize=900 | 900 bytes | Far below it |
/maxsize=900MB | 943,718,400 bytes | Fine |
/maxsize=20GB | 21,474,836,480 bytes | Fine |
/maxsize=UNBOUNDED | No cap at all | Not applicable |
resize shadowstorage page says 1 MB; the archived add shadowstorage page says 300 MB, which is 300 times larger. Neither is obviously stale. Pass a real working size with an explicit unit and the disagreement never affects you.
One more documented lever worth knowing exists: the current page notes that the minimum for the shadow copy storage area can be set through the MinDiffAreaFileSize registry value. That is a knob for a specific support scenario, not routine tuning, and it belongs in a change record if you use it.
Hidden gems
Two different “State” numbers, two different meanings
VSS has two state enumerations and both surface as a field called State. Writers use VSS_WRITER_STATE, where the values run 0 to 15 and 9 means vetoed at the freeze. Shadow copies use the State property on the Win32_ShadowCopy WMI class, where the values run 0 to 12 and 9 means Created. Same field name, same number, opposite news.
| Value | VSS_WRITER_STATE, for writers | Win32_ShadowCopy.State, for copies |
|---|---|---|
| 1 | Stable | Preparing |
| 7 | Vetoed at PrepareBackup | Committed |
| 9 | Vetoed at Freeze | Created |
| 10 | Vetoed at Thaw | Aborted |
Before you interpret a State number, be sure whether you are looking at a writer or a shadow copy.
Last error is not derived from the state
In the Microsoft capture above, all six writers report “Last error: No error” and five of them are Failed. The two fields come from different places: the state is where the service last saw that writer in the handshake, and the last error is what the writer itself chose to report. “Failed” with “No error” usually means the writer was cut off rather than that it hit a fault of its own, which is precisely what happened on that Hyper-V host.
The error values worth recognising are Timed out, Retryable error and Non-retryable error. A timeout on several writers at once points at load or at another backup running concurrently, not at those components.
The WMI class is documented as having no supported client
Win32_ShadowCopy is the obvious way to work with shadow copies from PowerShell, and its reference lists Minimum supported server as Windows Server 2003 and Minimum supported client as “None supported”. Treat client behaviour as undocumented rather than guaranteed: fine for interactive troubleshooting on a workstation, worth pinning down before a fleet-wide script depends on it.
A writer that is missing is worse than a writer that failed
A failed state is a report about one job. A writer absent from the list has not registered at all, and every backup that needs it will fail the same way until it does. Microsoft’s guidance for the classic case, System Writer missing from the list, is to check the Application log for VSS event 8213, which names the account the writer’s host process runs under and states plainly when that account lacks sufficient access rights.
So the diagnostic order is: is the writer listed at all, then what phase did it veto in, then what did the event log say at that moment.
PowerShell equivalents
Microsoft documents no cmdlet for the writers, so they still come from vssadmin and need parsing. The shadow copies themselves are available as objects through WMI, which is a real upgrade over reading GUIDs off a screen.
| Task | CMD | PowerShell |
|---|---|---|
| List shadow copies | vssadmin list shadows | Get-CimInstance Win32_ShadowCopy |
| Copies on one volume | vssadmin list shadows /for=C: | no direct equivalent: Get-CimInstance Win32_ShadowCopy | Group-Object VolumeName, then pick the volume GUID |
| Writer states | vssadmin list writers | parse vssadmin list writers, see below |
| Service state | sc query VSS | Get-Service VSS |
| VSS errors | wevtutil qe Application | Get-WinEvent -FilterHashtable @{LogName='Application'; ProviderName='VSS'} |
The shadow copies first. The interesting properties are the ID you would feed back to delete shadows, the original volume, the creation time and the two booleans that decide whether Previous Versions can see the copy and whether it survives a reboot.
# ClientAccessible is the property that decides whether vssadmin may delete it
Get-CimInstance Win32_ShadowCopy |
Select-Object ID, VolumeName, InstallDate, ClientAccessible, Persistent |
Sort-Object InstallDate |
Format-Table -AutoSize
# oldest first, which is what delete shadows /oldest would have taken
Get-CimInstance Win32_ShadowCopy |
Sort-Object InstallDate |
Select-Object -First 1 -Property ID, VolumeName, InstallDate
Now the writers. The parser below solves the problem example 1 ran into: it remembers the writer name, picks up the state and the bracketed number, and emits one complete object when it reaches the last line of each block. The hashtable turns that number into the phase name from the table above, which is the whole point of the exercise.
$VssPhase = @{
0='Unknown'; 1='Stable'; 2='Waiting for freeze'; 3='Waiting for thaw'
4='Waiting for PostSnapshot'; 5='Waiting for backup complete'
6='Vetoed at Identify'; 7='Vetoed at PrepareBackup'; 8='Vetoed at PrepareForSnapshot'
9='Vetoed at Freeze'; 10='Vetoed at Thaw'; 11='Vetoed at PostSnapshot'
12='Failed at BackupComplete'; 13='Failed at PreRestore'; 14='Failed at PostRestore'
15='Failed at backup shutdown'
}
# the name arrives three lines before the state, so it has to be held in a variable
$name = $null; $code = 0; $label = $null
$writers = vssadmin list writers | ForEach-Object {
if ($_ -match "^Writer name:\s*'?(.+?)'?\s*$") { $name = $matches[1] }
elseif ($_ -match '^State:\s*\[(\d+)\]\s*(.+?)\s*$') { $code = [int]$matches[1]; $label = $matches[2] }
elseif ($_ -match '^Last error:\s*(.+?)\s*$') {
# Last error is the final line of a writer block, so emit the object here
[pscustomobject]@{
WriterName = $name
StateCode = $code
StateLabel = $label
Phase = $VssPhase[$code]
LastError = $matches[1]
}
}
}
$writers | Format-Table WriterName, StateCode, StateLabel, Phase, LastError -AutoSize
Run against the six-writer capture from the reading section, that returns six objects, and the two banner lines produce none. The rows it prints look like this.
WriterName StateCode StateLabel Phase LastError
---------- --------- ---------- ----- ---------
System Writer 9 Failed Vetoed at Freeze No error
COM+ REGDB Writer 9 Failed Vetoed at Freeze No error
MSDEWriter 1 Stable Stable No error
Registry Writer 9 Failed Vetoed at Freeze No error
WMI Writer 9 Failed Vetoed at Freeze No error
Event Log Writer 9 Failed Vetoed at Freeze No error
With objects in hand the useful question becomes a filter. Anything with a state code of 6 or higher is one of the ten failure values, so that single comparison replaces reading the whole list.
# 6 and up are the failure states; 2 to 5 are mid-handshake and not faults
$writers | Where-Object StateCode -ge 6 |
Select-Object WriterName, StateCode, Phase, LastError
# and the summary line for a ticket: which phases, and how many in each
$writers | Where-Object StateCode -ge 6 |
Group-Object Phase |
Select-Object Name, Count
Against that capture the filter returns five writers, all in one phase. Five components vetoing at the same phase is a platform-level answer; five vetoing at five different phases would be five separate investigations.
Create method on Win32_ShadowCopy, which takes a volume and a context that defaults to ClientAccessible. That is the documented route on builds whose vssadmin has no create shadow subcommand, and diskshadow is the other.
Where this matters
- A nightly backup job fails with no useful error: the job log says the snapshot could not be created, and the writer states say which component refused and at which phase.
- Previous Versions is empty on a share users rely on: either no client-accessible copy exists or the storage cap is dropping them as fast as they are made, and the three storage numbers tell you which.
- A volume is mysteriously full: Used shadow copy storage is invisible to a normal folder-size scan, so a volume can be full of snapshots that nothing in Explorer accounts for.
- Restore points vanish after somebody tidied up disk space: lowering the maximum deletes copies to fit, and it is the single most common self-inflicted cause of a missing restore point.
- Two backup products are installed: concurrent snapshot requests produce timeouts across unrelated writers, which looks like many faults and is one scheduling problem.
- An incident review asks whether snapshots were deleted: knowing that
delete shadows /all /quietis a standard ransomware step, and that it only touches client-accessible copies, shapes both the question and the answer.
Tips and limitations
- Run everything from an elevated prompt, including the read-only subcommands, which is how Microsoft’s own walkthroughs run them.
vssadmin /?is the authoritative subcommand list for the machine in front of you. Microsoft’s current reference documents four; the archived Server reference documents ten.- Writer states are a snapshot of one moment. Capture them while a backup is running if you want to see the failure, and again when nothing is running to see the resting state.
delete shadowsreaches client-accessible copies only. For anything a backup product created, the documented tool isdiskshadow.- Always pass an explicit unit to
/maxsize. A bare number is read as bytes and will not reach the documented minimum. - Resizing the storage association may delete shadow copies, and shrinking it below current usage certainly will.
- No documented cmdlet covers the writers. Parse the text, or read shadow copies as objects through
Win32_ShadowCopyand accept that its client support is undocumented. - A shadow copy is not a backup. It lives on the same disk as the data, so it survives a deleted file and not a failed disk.
Official documentation
- vssadmin: Windows Commands | Microsoft Learn
- Vssadmin, the archived Windows Server reference with all ten subcommands | Microsoft Learn
- vssadmin resize shadowstorage | Microsoft Learn
- vssadmin delete shadows, including the allowed-context error | Microsoft Learn
- VSS_WRITER_STATE enumeration | Microsoft Learn
- Win32_ShadowCopy WMI class | Microsoft Learn
- VSS writers report as failed on a virtual machine | Microsoft Learn
- diskshadow | Microsoft Learn
Related tools
- Event Log Analyzer: VSS failures leave their real explanation in the Application log, and this is where you read the exported entries.
Related guides
- ROBOCOPY backup on Windows: robocopy cannot copy open files on its own, and a shadow copy is what fills that gap.
- fsutil command in Windows: the volume-level view, including free space and the behaviour settings that sit underneath shadow storage.
- chkdsk switches and online scan: check the volume is healthy before trusting any snapshot taken from it.
- diskpart command guide: for reading volume GUIDs and mount points, which is how shadow copies identify their volumes.
- wevtutil command in Windows: pull the VSS and Backup events out of the Application log from CMD.
- Get-WinEvent and PowerShell event logs: the same events as objects, which is easier when you are correlating a writer failure with a timestamp.
- wbadmin command in Windows: the backup tool whose failures the writer states explain, and the event 517 code that names the phase.