Script Recipe of the week: Shadow Copy secrets

One useful feature that you probably noticed in Windows Server 2003 is Shadow Copies for Shared Folders. I will not give too many details about it – suffice to say that it will create periodic versions of your shares. So if you lost or overwritten a file on some share then you simply right-click that file and you will be able to access its previous versions.

This feature can be easily enabled on any volume – just go to the Properties page for a volume, select “Shadow Copy” tab and then click “Enable”. This will schedule a task that will create two versions per day. One more thing to add is that you can have a maximum of 64 versions for a given volume, which gives us about a month of history (for more details about this feature, see this link)

OK – this might be good enough in many cases, but what about the case when you want a more granular control on the shadow copy history? For example, you might want to implement a more complex policy: shadow copies created daily should be persisted for two weeks. With one exception - shadow copies created Monday should stay there for at least one month, and so on and so forth. 

Here is a simple VBScript example which will delete all shadow copies that are more than two weeks old, with the exception of those created Monday (which remain there as long as possible). Just make sure you run this script once per day, using a scheduled task for example:

  Dim namespace
Set namespace = GetObject("winmgmts://localhost/root/cimv2")

  Dim objSet
Set objSet = namespace.ExecQuery("select * from Win32_ShadowCopy")

  Dim dateTime
set dateTime = CreateObject("WbemScripting.SWbemDateTime")

  Dim vDate

  for each obj in objSet
dateTime.Value = obj.InstallDate
vDate = dateTime.GetVarDate(True)

      WScript.echo "- Snapshot on " & _
obj.VolumeName & " @ " & vDate

      if (DateDiff("d", vDate, Date) > 14) then
dayOfWeek = DatePart("w", vDate)
WScript.Echo "dayOfWeek = " & dayOfWeek
if (dayOfWeek <> 2) then
WScript.echo " [Deleting snapshot...]"
obj.Delete_()
end if
end if
next