Как включить теневое копирование тома на конкретный диск (D :, E:, ...) и настроить расписание с помощью Powershell?
Мне просто нужны подсказки, как начать.
Мне потребовалось некоторое время, чтобы заставить это работать (после обнаружения простой ошибки, приводящей к сбою), и функция не завершена. Я хочу добавить возможность включить его на удаленном компьютере, что, вероятно, нужно будет сделать с помощью задачи, которая запускается один раз. Если кто-то изменит это и добавит то, дайте мне знать!
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);
}
Несмотря на то, что это работает и имитирует то, что происходит, когда вы делаете это через графический интерфейс, он по-прежнему отображается как отключенный для этого диска. Но если включить, ничего не изменится! (LOL) Я предполагаю, что есть что-то, что также нужно изменить в реестре.
Вы можете создать теневую копию на определенном диске с помощью объекта WMI, как описано в Статья Microsoft.
Включить теневое копирование тома на определенном диске (D :, E:, ...) это две вещи
$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"
После целой кучи возни с ним, он начал работать немного по-другому (он также, кажется, правильно отображается через графический интерфейс).
Приветствую эту страницу за небольшой помощью: https://social.technet.microsoft.com/forums/windowsserver/en-US/fb69840d-5f52-4711-8168-2faa23088233/shadow-copy-schedule-per-script
Обратной стороной использования schtasks (используемых на этой странице) является то, что, насколько я понимаю, у вас не может быть нескольких триггеров.
Кроме того, из-за того, как я устраняю проблемы с решением (использовал bindiff рабочего / неработающего xml), я не совсем уверен, что используемые мной флаги оптимальны.
Упрощение означает использование schtasks, отображаемых в пользовательском интерфейсе, совместимых с PowerShell 2. Разработанный для стандартной сборки, может потребоваться поиграться с $ volumeinfo [x] при создании $ taskrun, чтобы найти подходящий том.
$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 "
Можно соответствующим образом настроить следующие аргументы:
ПРИМЕЧАНИЕ. Для переключателя / TR ТРЕБУЕТСЯ пробел в конце, если его нет, он заменяет последнюю обратную косую черту двойной кавычкой, в результате чего пользовательский интерфейс VSS не распознает задачу.
Это то, что я использую в 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"
}
На самом деле теневое копирование активируется путем создания задач, вызывающих vssadmin.exe.
В PowerShell 3.0 есть командлеты, которые позволяют создавать задачи, но они зависят от системных вызовов, которые не были реализованы до Windows 8 / Windows Server 2012. Чтобы сделать это способом PowerShell, вам потребуются следующие три из этих командлетов:
register-scheduledTask
new-scheduledtaskaction
new-scheduledtasktrigger
В более ранних версиях Windows вы будете ограничены использованием schtasks.exe.
Однако - и в этом этот ответ отличается от других - создание задачи теневого копирования такими способами - неправильный способ делать что-то, поскольку любые внесенные вами изменения не будут отображаться в графическом интерфейсе. Таким образом, ненаблюдающий пользователь может не знать, что теневое копирование включено, что приводит к включению второго его экземпляра или, что еще хуже, тихой перезаписи вашей задачи (если вы следовали соглашениям об именах Windows (VolumeShadowCopy {$ GUID})).
Что вам нужно сделать, так это создать его через графический интерфейс (желательно на Win7 / Win2008, поскольку более новые версии Windows по умолчанию используют taskxml 1.2 вместо более совместимого taskxml 1.1), экспортировать задачу как XML через schtasks, программно отредактировать этот XML , сохраните этот XML как UTF16 и импортируйте его. К счастью, как только вы пройдете через графический интерфейс в начале, все это можно будет сделать из командной строки.
Я хотел бы опубликовать код, но то, что я написал, является собственностью, и у меня нет разрешения от моего работодателя. Я надеюсь, что совет по XML, по крайней мере, сэкономит вам бесчисленное количество часов. Я только что развернул решение XML на сотнях управляемых серверов и добился большого успеха.
Спасибо всем, кто участвовал в этой теме. Это было полезно и сэкономило мне много работы. Следующий сценарий PowerShell был протестирован на Windows Server 2008 R2.
В следующем примере снимок создается каждые 2 часа с понедельника по пятницу. с 08:00 до 18:00 на томе C:
Если вы хотите изменить расписание, просто отредактируйте или замените встроенные 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%"
Лучшее, что я могу сделать, это указать тебе Воти особо указать вот этот и вот этот.
Ни один из них не указывает именно то, что вы ищете, но я отмечу, что вы можете создавать теневые копии в любой момент, поскольку VSS - это фоновая служба, которая работает до вызова.
Я получил именно то, что мне нужно, с помощью следующего кода, моим требованием было настроить VSS, но он также должен был быть видимым в графическом интерфейсе. Ключевой частью, чтобы сделать его видимым в графическом интерфейсе, является добавление идентификатора тома в имя запланированной задачи, как указано пользователем261949 (это немного странно, честно говоря, я искал ключ реестра, но я ничего не нашел ...). В итоге я получил следующий код, который мне подходит:
#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'
Спасибо всем за полезную информацию!