Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

How to enable volume shadow copy on specific drive (D:, E:,...) and set up schedule using Powershell ?

I just need some hints how to start.

share|improve this question

migrated from stackoverflow.com Apr 13 '11 at 18:35

This question came from our site for professional and enthusiast programmers.

    
We need some more information here. What OS are you using? Which program are you using to do backups? –  Holocryptic Apr 13 '11 at 19:28
    
Win XP and win 7. And I mean VSS, which is part of win OS. –  Primoz Apr 13 '11 at 19:31

6 Answers 6

up vote 6 down vote accepted

You can create a Shadow copy on a specific drive using WMI object like it's explained in Microsoft Article.

Enable volume shadow copy on specific drive (D:, E:,...) is two things

  1. Creating a shadow copy as shown in the preceding article
  2. Creating a scheduled task to create shadow copy
share|improve this answer
    
Nice. This answer is exactly what I needed. I didn't know that I must create sceduled task. –  Primoz Apr 13 '11 at 21:19

It took me a little while to get this to worked (after finding the simple error causing it to fail), and the function is incomplete. I want to add the ability to enable it on a remote computer, which will probably have to be done via a task that is ran once. If anybody modifies this and adds that, let me know!

function Enable-ShadowCopies {
param(
    [String]$ComputerName = $Env:ComputerName,

    [Parameter(Mandatory=$true)]
    [String]$Drive
)
$volumeWMI = Get-WmiObject -ComputerName $ComputerName -Class Win32_Volume -Filter "DriveLetter = '$Drive'";
$volumeID = ($volumeWMI.DeviceID.SubString(10)).SubString(0,($volumeWMI.DeviceID.SubString(10)).Length-1);

$scheduler = New-Object -ComObject Schedule.Service
$scheduler.Connect($ComputerName)
$tskDef = $scheduler.NewTask(0);
$tskRegInfo = $tskDef.RegistrationInfo;
$tskSettings = $tskDef.Settings;
$tskTriggers = $tskDef.Triggers;
$tskActions = $tskDef.Actions;
$tskPrincipals = $tskDef.Principal;

# Registration Info
$tskRegInfo.Author = "PowerShell Script";

# Settings
$tskSettings.DisallowStartIfOnBatteries = $false;
$tskSettings.StopIfGoingOnBatteries = $false
$tskSettings.AllowHardTerminate = $false;
$tskSettings.IdleSettings.IdleDuration = "PT600S";
$tskSettings.IdleSettings.WaitTimeout = "PT3600S";
$tskSettings.IdleSettings.StopOnIdleEnd = $false;
$tskSettings.IdleSettings.RestartOnIdle = $false;
$tskSettings.Enabled = $true;
$tskSettings.Hidden = $false;
$tskSettings.RunOnlyIfIdle = $false;
$tskSettings.WakeToRun = $false;
$tskSettings.ExecutionTimeLimit = "PT259200S";
$tskSettings.Priority = "5";
$tskSettings.StartWhenAvailable = $false;
$tskSettings.RunOnlyIfNetworkAvailable = $false;

# Triggers
$tskTrigger1 = $tskTriggers.Create(3);
$tskTrigger2 = $tskTriggers.Create(3);

## Trigger 1
$tskTrigger1.Id = "Trigger1"
$tskTrigger1.StartBoundary = (Get-Date -format "yyyy-MM-dd")+"T07:00:00";
$tskTrigger1.DaysOfWeek = 0x3E; # Monday - Friday - http://msdn.microsoft.com/en-us/library/windows/desktop/aa384024(v=vs.85).aspx
$tskTrigger1.Enabled = $true;

## Trigger 2
$tskTrigger2.Id = "Trigger2";
$tskTrigger2.StartBoundary = (Get-Date -format "yyyy-MM-dd")+"T12:00:00";
$tskTrigger2.DaysOfWeek = 0x3E; # Monday - Friday - http://msdn.microsoft.com/en-us/library/windows/desktop/aa384024(v=vs.85).aspx
$tskTrigger2.Enabled = $true;

# Principals (RunAs User)
$tskPrincipals.Id = "Author";
$tskPrincipals.UserID = "SYSTEM";
$tskPrincipals.RunLevel = 1;

 # Actions
$tskActions.Context = "Author"
$tskAction1 = $tskActions.Create(0);

# Action 1
$tskAction1.Path = "C:\Windows\system32\vssadmin.exe";
$tskAction1.Arguments = "Create Shadow /AutoRetry=15 /For="+$volumeWMI.DeviceID;
$tskAction1.WorkingDirectory = "%systemroot%\system32";

# Configure VSS, Add scheduled task
vssadmin Add ShadowStorage /For=$Drive /On=$Drive /MaxSize=10%;
$tskFolder = $scheduler.GetFolder("\")
$tskFolder.RegisterTaskDefinition("ShadowCopyVolume$volumeID", $tskDef, 6, "SYSTEM", $null,5);
}

Even though this works, and it mimics what happens when you do it via the GUI, it still shows as disabled for that drive. But if you enable it, nothing changes! (LOL) I'm guessing there's something that needs to also be modified in the registry.

share|improve this answer
1  
+1 for answering with a full script! –  Mark Henderson Jun 10 '12 at 22:19
    
Need to add $date = Get-Date and $tskFolder = $scheduler.GetFolder("\") –  Jeow Li Huan Jan 5 '14 at 15:49
$diskname = "C:\"
$VolumeWmi = gwmi Win32_Volume -Namespace root/cimv2 | ?{ $_.Name -eq $diskname }
$DeviceID = $VolumeWmi.DeviceID.ToUpper().Replace("\\?\VOLUME", "").Replace("\","")
$TaskName = "ShadowCopyVolume" + $DeviceID
$TaskFor = "\\?\Volume" + $DeviceID + "\"
$Task = "C:\Windows\system32\vssadmin.exe"
$Argument = "Create Shadow /AutoRetry=15 /For=$TaskFor"
$WorkingDir = "%systemroot%\system32"

$ScheduledAction = New-ScheduledTaskAction –Execute $Task -WorkingDirectory $WorkingDir -Argument $Argument
$ScheduledTrigger = @()
$ScheduledTrigger += New-ScheduledTaskTrigger -Daily -At 10:00
$ScheduledTrigger += New-ScheduledTaskTrigger -Daily -At 15:00
$ScheduledSettings = New-ScheduledTaskSettingsSet -Compatibility V1 -DontStopOnIdleEnd -ExecutionTimeLimit (New-TimeSpan -Days 3) -Priority 5
$ScheduledTask = New-ScheduledTask -Action $ScheduledAction -Trigger $ScheduledTrigger -Settings $ScheduledSettings
Register-ScheduledTask $TaskName -InputObject $ScheduledTask -User "NT AUTHORITY\SYSTEM"

After a whole bunch of messing with it, got it to work slightly differently (it also seems to show up properly via the GUI).

Shoutouts to this page for a bit of help: https://social.technet.microsoft.com/forums/windowsserver/en-US/fb69840d-5f52-4711-8168-2faa23088233/shadow-copy-schedule-per-script

The downside to using schtasks (what that page uses) is that you can't have multiple triggers as far as I can see.

Also because of the way I troubleshot the solution (Used a bindiff of working/not working xml), I'm not entirely convinced that the flags I use are optimal.

share|improve this answer

Simpler means using schtasks that shows in the UI, compatible in PowerShell 2. Designed for a standard build, may need to play about with $volumeinfo[x] when creating $taskrun to find the appropriate volume.

$volumeinfo = GWMI -namespace root\cimv2 -class win32_volume
$volumeid = $volumeinfo[1].deviceid
$taskname = "ShadowCopyVolume" + $volumeid.replace("\","").replace("?Volume","")
$taskrun = "C:\Windows\system32\vssadmin.exe Create Shadow /AutoRetry=15 /For=$volumeid"
schtasks /create /RU SYSTEM /SC DAILY /ST 07:00 /RI 60 /DU 12:00 /K /V1 /TN $TaskName /TR "$taskrun "

Can configure the following arguments appropriately:

  • /SC - frequency task is triggered
  • /ST - time task is triggered
  • /RI - repetition of task every x minutes after trigger
  • /DU - duration of task to be repeated

NOTE: The /TR switch REQUIRES the space at the end, if it is not there it replaces the final backslash with a double quote causing the VSS UI to not recognise the task.

share|improve this answer

The best I can do is point you here, and specifically point out this one and this one.

Neither address exactly what you're looking for, but I will point out you can create shadow copies at any point as VSS is a background service that runs until called.

share|improve this answer

This is what I use in PowerShell. Its a link to my site, but it looks a lot better than it does pasted here.

#Enable Volume Shadow copy
clear
$Continue = Read-Host "Enable Volume Shadowcopy (Y/N)?"
while("Y","N" -notcontains $Continue){$Continue = Read-Host "Enable Volume Shadowcopy (Y/N)?"}
if ($Continue -eq "Y") {
#Enable Shadows
vssadmin add shadowstorage /for=C: /on=C:  /maxsize=8128MB
vssadmin add shadowstorage /for=D: /on=D:  /maxsize=8128MB
#Create Shadows
vssadmin create shadow /for=C:
vssadmin create shadow /for=D:
#Set Shadow Copy Scheduled Task for C: AM
$Action=new-scheduledtaskaction -execute "c:\windows\system32\vssadmin.exe" -Argument "create shadow /for=C:"
$Trigger=new-scheduledtasktrigger -daily -at 6:00AM
Register-ScheduledTask -TaskName ShadowCopyC_AM -Trigger $Trigger -Action $Action -Description "ShadowCopyC_AM"
#Set Shadow Copy Scheduled Task for C: PM
$Action=new-scheduledtaskaction -execute "c:\windows\system32\vssadmin.exe" -Argument "create shadow /for=C:"
$Trigger=new-scheduledtasktrigger -daily -at 6:00PM
Register-ScheduledTask -TaskName ShadowCopyC_PM -Trigger $Trigger -Action $Action -Description "ShadowCopyC_PM"
#Set Shadow Copy Scheduled Task for D: AM
$Action=new-scheduledtaskaction -execute "c:\windows\system32\vssadmin.exe" -Argument "create shadow /for=D:"
$Trigger=new-scheduledtasktrigger -daily -at 7:00AM
Register-ScheduledTask -TaskName ShadowCopyD_AM -Trigger $Trigger -Action $Action -Description "ShadowCopyD_AM"
#Set Shadow Copy Scheduled Task for D: PM
$Action=new-scheduledtaskaction -execute "c:\windows\system32\vssadmin.exe" -Argument "create shadow /for=D:"
$Trigger=new-scheduledtasktrigger -daily -at 7:00PM
Register-ScheduledTask -TaskName ShadowCopyD_PM -Trigger $Trigger -Action $Action -Description "ShadowCopyD_PM"
}
share|improve this answer
    
I suggest to indent... –  peterh Jan 30 at 16:18

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.