System restore can be great if Microsoft releases a botched update, or a program fails to install or uninstall properly. There’s several different scenarios in which System restore points can be useful to recover your system files back to a previously know “good” point. However, malware writers understand this too, and starting back in my XP days at DoIT it was a well-known procedure when doing Virus Rescue cases to just disable System Restore (deleting all restore points automatically) and then re-enable it. This prevents a virus from hiding out in old files, ready to rear its head again if you need to do a System Restore in the future.

At my office, System Restore has always been disabled. This has been an irritant several times in the past, as me and the other PC Support guys would say…well, darn, the system is hosed and even though it doesn’t have anywhere near a 100% success rate, it would have been nice to at least try it and see if worked. Our sysadmin’s reasons for this has been – well, it takes up as much as 10GB of space on your HDD or 10%, whatever’s smaller. We can’t guarantee all our machines will have that. And then there was the aforementioned virus issue.

I convinced him that if PC Support took responsibility for deleting the system restore points on infected/compromised machines, would he at least consider setting the Group Policy object for “Disable System Restore” from “enforced” to not configured? That means that at least, new machines we image and set up in the future will have System Restore turned on. And old machines, with possibly space-limited HDD’s, will just stay off – which is fine. We didn’t want to have to bother with RDP’ing into the system and going through the GUI to delete the Restore Points – why do that, if you can just do that (and pretty much anything under the sun) in Powershell?

So this was my first time making (well, customizing) a powershell script. I used this one here as a base, but decided I wanted two things – the user to be able to input a name of a machine, and also for some better error handling. The script as it exists on that page will give big ugly error messages if System Restore can’t be contacted, or doesn’t have any restore points. I cleaned it up so that it will gracefully fail.

Here it is:

$compname = Read-Host -Prompt 'Input computer name to delete all shadow copies from' #Requests computer name from you
$shadowCopies = Get-WMIObject -Class Win32_ShadowCopy -Computer $compname # Accesses Shadow Copy WMI
$shadowCopies | % {$_.DeviceObject} #Lists the copies
$numberofcopies = $shadowCopies.Count # Stores variable for success message
if ($shadowCopies -eq $null) {
Write-Host 'No shadow copies found, or System Restore disabled.' -ForegroundColor White -BackgroundColor Black} # if service cannot be contacted or no copies found
if ($shadowCopies.Count -gt 1) {
for($i = 0; $i -lt $shadowcopies.count; $i++){
$shadowCopies[($i-1)].Delete()
}} # if there is more than one shadow copy, loops back to delete them all
if ($shadowCopies.Count -eq 1) {
$shadowCopies.Delete()} # if only one shadow copy, deletes it
if ($shadowCopies) {
Write-Host "$numberofcopies deleted successfully." -ForegroundColor Black -BackgroundColor White
} #print success message

This is available to download as a .ps1 script from Microsoft Technet here. Note that in order to run it, you will need to Set-ExecutionPolicy bypass in your Powershell session. On Windows 10 at least (my main system at work) I did not need to run it as an administrator. If anyone happens across this post and has a correction for me or suggestion I will incorporate it, but mainly this was just a little post because I’m proud of myself. It may be simple, but considering the last “programming” I did was having a computer play Mary Had a Little Lamb in Basic (which I got a blue ribbon for in 4-H, I may add!) I am glad to contribute something useful to other sysadmins.