如何使用Powershell启用卷影复制?


13

如何在特定驱动器(D :, E:,...)上启用卷影复制并使用Powershell设置时间表?

我只需要一些提示即可开始。


1
我们在这里需要更多信息。您正在使用什么操作系统?您使用哪个程序进行备份?
Holocryptic 2011年

Win XP和Win7。我的意思是VSS,它是Win OS的一部分。
Primoz

Answers:


7

您可以使用WMI对象在特定驱动器上创建卷影副本,如Microsoft文章中所述

在特定驱动器上启用卷影复制(D :, E:,...)是两件事

  1. 如上一篇文章所示创建卷影副本
  2. 创建计划任务以创建卷影副本

真好 这个答案正是我所需要的。我不知道我必须创建计划任务。
Primoz

7

我花了一些时间使它生效(在找到导致失败的简单错误之后),该功能不完整。我想添加在远程计算机上启用它的功能,这可能必须通过运行一次的任务来完成。如果有人对此进行了修改并添加了该信息,请告诉我!

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);
}

即使此方法有效,并且它模仿了通过GUI进行操作时发生的情况,但对于该驱动器仍然显示为禁用。但是,如果启用它,则什么都不会改变!(LOL)我猜注册表中有些东西也需要修改。


1
+1可使用完整脚本回答!
Mark Henderson

需要添加$ date = Get-Date和$ tskFolder = $ scheduler.GetFolder(“ \”)
Jeow Li Huan 2014年

2
$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"

经过一堆混乱之后,让它的工作方式略有不同(它似乎也可以通过GUI正确显示)。

向此页面大喊一些帮助: https //social.technet.microsoft.com/forums/windowsserver/zh-CN/fb69840d-5f52-4711-8168-2faa23088233/shadow-copy-schedule-per-script

使用schtasks(页面使用的内容)的不利之处在于,据我所知,您不能有多个触发器。

另外,由于我对解决方案进行故障排除的方式(使用了可工作/无效的xml绑定),我也不完全相信我使用的标志是最佳的。


2

更简单的方法是使用在UI中显示并与PowerShell 2兼容的schtasks。为标准构建而设计的,在创建$ taskrun以查找合适的卷时可能需要使用$ volumeinfo [x]。

$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 "

可以适当地配置以下参数:

  • / SC-频率任务已触发
  • / ST-时间任务被触发
  • / RI-触发后每x分钟重复执行一次任务
  • / DU-重复任务的持续时间

注意:/ TR开关在末尾需要空格,如果不存在,它将用双引号替换最终的反斜杠,从而使VSS UI无法识别该任务。


1

这就是我在PowerShell中使用的。它是我网站的链接,但看起来比这里粘贴的要好得多。

#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"
}

我建议缩进...
peterh-恢复莫妮卡2015年

1

卷影复制实际上是通过创建调用vssadmin.exe的任务来启用的。

PowerShell 3.0具有使您能够创建任务的cmdlet,但是这些cmdlet取决于直到Windows 8 / Windows Server 2012才实现的系统调用。您需要以下cmdlet中的以下三个以PowerShell方式执行此操作:

register-scheduledTask
new-scheduledtaskaction
new-scheduledtasktrigger

在Windows的早期版本中,将只能使用schtasks.exe。

但是-这是其他答案的不同之处-以这种方式创建卷影复制任务不是正确的处理方式,因为所做的任何更改都不会显示在GUI中。因此,一个不留神的用户可能不知道已启用卷影复制,从而导致他们启用了它的第二个实例,或者更糟糕的是,无声地覆盖了您的任务(如果您遵循Windows的命名约定(VolumeShadowCopy {$ GUID}))。

您需要做的是通过GUI创建一个(最好在Win7 / Win2008上,因为Windows的新版本默认使用taskxml 1.2而不是更兼容的taskxml 1.1),通过schtasks将任务导出为XML,以编程方式编辑该XML ,将该XML保存为UTF16,然后导入。幸运的是,一旦您一开始就通过了GUI,就可以在命令行中完成所有操作。

我想发布代码,但是我写的是专有的,而且我没有得到雇主的许可。我希望XML技巧至少可以为您节省无数小时。我刚刚在数百台托管服务器上部署了XML解决方案,并取得了巨大的成功。


1

多亏了每个人,这才对这个线程有所帮助。这很有帮助,为我节省了很多工作。以下PowerShell脚本已在Windows Server 2008 R2上进行了测试。

以下示例在Mo.-Fr之间每2小时创建一个快照。从C卷的08:00h-18:00h开始:

如果要修改计划,只需编辑或替换内联XML数据。

注意:不提供保修。没有责任。在用于生产环境之前,请在您自己的实验室中进行测试。

# German Keyboard-Layout for Console Output. Can be skipped in english enviroments
#chcp 1252 >$null 2>&1

function ConfigureVolumeShadowCopies([string] $diskname, $vssMaxSizeInPercent) {

$xmlDocument = [xml] "<?xml version='1.0' encoding='UTF-16'?>
<Task version='1.1' xmlns='http://schemas.microsoft.com/windows/2004/02/mit/task'>
  <RegistrationInfo>
    <Author>Administrator</Author>
  </RegistrationInfo>
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2018-01-01T08:00:00</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByWeek>
        <DaysOfWeek>
          <Monday />
          <Tuesday />
          <Wednesday />
          <Thursday />
          <Friday />
        </DaysOfWeek>
        <WeeksInterval>1</WeeksInterval>
      </ScheduleByWeek>
    </CalendarTrigger>
    <CalendarTrigger>
      <StartBoundary>2018-01-01T10:00:00</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByWeek>
        <DaysOfWeek>
          <Monday />
          <Tuesday />
          <Wednesday />
          <Thursday />
          <Friday />
        </DaysOfWeek>
        <WeeksInterval>1</WeeksInterval>
      </ScheduleByWeek>
    </CalendarTrigger>
    <CalendarTrigger>
      <StartBoundary>2018-01-01T12:00:00</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByWeek>
        <DaysOfWeek>
          <Monday />
          <Tuesday />
          <Wednesday />
          <Thursday />
          <Friday />
        </DaysOfWeek>
        <WeeksInterval>1</WeeksInterval>
      </ScheduleByWeek>
    </CalendarTrigger>
    <CalendarTrigger>
      <StartBoundary>2018-01-01T14:00:00</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByWeek>
        <DaysOfWeek>
          <Monday />
          <Tuesday />
          <Wednesday />
          <Thursday />
          <Friday />
        </DaysOfWeek>
        <WeeksInterval>1</WeeksInterval>
      </ScheduleByWeek>
    </CalendarTrigger>
    <CalendarTrigger>
      <StartBoundary>2018-01-01T16:00:00</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByWeek>
        <DaysOfWeek>
          <Monday />
          <Tuesday />
          <Wednesday />
          <Thursday />
          <Friday />
        </DaysOfWeek>
        <WeeksInterval>1</WeeksInterval>
      </ScheduleByWeek>
    </CalendarTrigger>
    <CalendarTrigger>
      <StartBoundary>2018-01-01T18:00:00</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByWeek>
        <DaysOfWeek>
          <Monday />
          <Tuesday />
          <Wednesday />
          <Thursday />
          <Friday />
        </DaysOfWeek>
        <WeeksInterval>1</WeeksInterval>
      </ScheduleByWeek>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id='Author'>
      <UserId>S-1-5-18</UserId>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
    <IdleSettings>
      <Duration>PT600S</Duration>
      <WaitTimeout>PT3600S</WaitTimeout>
      <StopOnIdleEnd>false</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT259200S</ExecutionTimeLimit>
    <Priority>5</Priority>
  </Settings>
  <Actions Context='Author'>
    <Exec>
      <Command>C:\Windows\system32\vssadmin.exe</Command>
      <Arguments>Create Shadow /AutoRetry=15 /For=\\?\Volume{REPLACEME}\</Arguments>
      <WorkingDirectory>%systemroot%\system32</WorkingDirectory>
    </Exec>
  </Actions>
</Task>"

# Query Volume GUID of the given Volume
$VolumeWmi = gwmi Win32_Volume -Namespace root/cimv2 | ?{ $_.Name -eq ($diskname +"\") }

# Build Variables
$DeviceID = $VolumeWmi.DeviceID.ToUpper().Replace("\\?\VOLUME", "").Replace("\","")
$TaskName = "ShadowCopyVolume" + $DeviceID
$TaskFor = "\\?\Volume" + $DeviceID + "\"

# Replace Volume GUID in XML-Data
$xmlDocument.Task.Actions.Exec.Arguments = "Create Shadow /AutoRetry=15 /For=$TaskFor"

# Write temporary XML-File for Import of scheduled Task with schtask
$xmlDocumentFileName = $PSScriptRoot + "\" + $TaskName + ".xml"
$xmlDocument.Save($xmlDocumentFileName)

# Try to Delete existing Task for VSS
try {
schtasks /delete /TN $Taskname /f
}
catch {
    #If Task can not be found: do nothing
}

# Create Scheduled Task
schtasks /Create /XML $xmlDocumentFileName /TN $TaskName

# Create (First) Snapshot
vssadmin Create Shadow /For=$diskname /AutoRetry=15

# Define Max Size of VSS Shadow Storage
vssadmin resize shadowstorage /For=$diskname /On=$diskname /MaxSize=$vssMaxSizeInPercent

# Delete temporary XML Document
Remove-Item $xmlDocumentFileName -Force

}

# Start Configuration - for Example on Volume C: with 10% MaxSize
ConfigureVolumeShadowCopies "C:" "10%"

0

我能做的最好的就是将您指向此处,并特别指出这一点这一点

两者都不能满足您的需求,但是我要指出的是,由于VSS是一直运行到被调用的后台服务,因此您可以随时创建卷影副本。


0

使用下面的代码,我得到了我真正需要的东西,我的要求是配置VSS,但是它也必须在GUI中可见。使它在GUI中可见的关键部分是在user261949指出的计划任务名称中添加卷ID(这有点奇怪,老实说我在搜索注册表项,但我什么也没发现。)。我最终得到了适合我需要的以下代码:

#Enable Volume Shadow copy

#Enable Shadows
vssadmin add shadowstorage /for=C: /on=C:  /maxsize=8128MB

#Create Shadows
vssadmin create shadow /for=C:

#create scheduled tasks
$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 07:00
$ScheduledTrigger += New-ScheduledTaskTrigger -Daily -At 12: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'

感谢您提供的有用信息!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.