Jak włączyć kopiowanie woluminów w tle za pomocą programu PowerShell?


13

Jak włączyć kopiowanie woluminów w tle na określonym dysku (D :, E:, ...) i skonfigurować harmonogram za pomocą programu Powershell?

Potrzebuję tylko kilku wskazówek, jak zacząć.


1
Potrzebujemy więcej informacji tutaj. Z jakiego systemu operacyjnego korzystasz? Z którego programu korzystasz do tworzenia kopii zapasowych?
Holocryptic

Wygraj XP i wygraj 7. Mam na myśli VSS, który jest częścią systemu operacyjnego Windows.
Primoz

Odpowiedzi:


7

Możesz utworzyć kopię Shadow na określonym dysku za pomocą obiektu WMI, tak jak to opisano w artykule Microsoft .

Włącz kopiowanie woluminów w tle na określonym dysku (D :, E:, ...) to dwie rzeczy

  1. Tworzenie kopii w tle, jak pokazano w poprzednim artykule
  2. Tworzenie zaplanowanego zadania w celu utworzenia kopii w tle

Ładny. Ta odpowiedź jest dokładnie tym, czego potrzebowałem. Nie wiedziałem, że muszę stworzyć sceduled task.
Primoz

7

Zajęło mi trochę czasu, aby to zadziałało (po znalezieniu prostego błędu powodującego błąd), a funkcja jest niekompletna. Chcę dodać możliwość włączenia go na komputerze zdalnym, co prawdopodobnie będzie musiało zostać wykonane za pomocą zadania uruchamianego raz. Jeśli ktoś to zmodyfikuje i doda to, daj mi znać!

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

Nawet jeśli to działa i naśladuje to, co dzieje się, gdy robisz to za pomocą GUI, nadal pokazuje się jako wyłączone dla tego dysku. Ale jeśli go włączysz, nic się nie zmieni! (LOL) Domyślam się, że jest coś, co również wymaga modyfikacji w rejestrze.


1
+1 za odpowiedź z pełnym skryptem!
Mark Henderson

Trzeba dodać $ date = Get-Date i $ tskFolder = $ scheduler. GetFolder („\”)
Jeow Li Huan

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"

Po całym zamieszaniu z nim sprawił, że działał nieco inaczej (wydaje się również, że wyświetla się poprawnie za pośrednictwem GUI).

Krzyki na tę stronę, aby uzyskać trochę pomocy: https://social.technet.microsoft.com/forums/windowsserver/en-US/fb69840d-5f52-4711-8168-2faa23088233/shadow-copy-schedule-per-script

Wadą używania schtasks (tego, czego używa ta strona) jest to, że nie mogę mieć wielu wyzwalaczy, o ile widzę.

Również ze względu na sposób, w jaki rozwiązałem problem (Użyłem bindiff działającego / niedziałającego xml), nie jestem do końca przekonany, że używane flagi są optymalne.


2

Prostsze oznacza użycie schtasks wyświetlanych w interfejsie użytkownika, zgodnych z PowerShell 2. Zaprojektowany dla standardowej wersji, może być konieczne użycie $ Volumeinfo [x] podczas tworzenia $ taskrun, aby znaleźć odpowiedni wolumin.

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

Może odpowiednio skonfigurować następujące argumenty:

  • / SC - uruchamiane jest zadanie częstotliwości
  • / ST - zadanie czasowe jest wyzwalane
  • / RI - powtarzanie zadania co x minut po uruchomieniu
  • / DU - czas trwania zadania do powtórzenia

UWAGA: Przełącznik / TR WYMAGA miejsca na końcu, jeśli go nie ma, zastępuje ostatni odwrotny ukośnik podwójnym cudzysłowem, powodując, że interfejs użytkownika VSS nie rozpoznaje zadania.


1

Tego używam w PowerShell . Jest to link do mojej strony, ale wygląda o wiele lepiej niż tutaj wkleił.

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

Sugeruję wcięcie ...
Peter - Przywróć Monikę

1

Kopiowanie w tle jest faktycznie włączane poprzez tworzenie zadań wywołujących vssadmin.exe.

Program PowerShell 3.0 ma polecenia cmdlet, które umożliwiają tworzenie zadań, ale zależą one od wywołań systemowych, które nie zostały zaimplementowane do systemu Windows 8 / Windows Server 2012. Aby wykonać tę czynność w następujący sposób, potrzebne są trzy z tych poleceń cmdlet:

register-scheduledTask
new-scheduledtaskaction
new-scheduledtasktrigger

We wcześniejszych wersjach systemu Windows korzystanie z programu schtasks.exe było ograniczone.

Jednak - i tutaj ta odpowiedź różni się od innych - tworzenie zadania kopiowania w tle w ten sposób nie jest właściwym sposobem na robienie rzeczy, ponieważ wszelkie wprowadzone zmiany nie pojawią się w graficznym interfejsie użytkownika. W związku z tym nieobserwujący użytkownik może nie wiedzieć, że funkcja Shadow Copy została włączona, co powoduje, że włącza ona drugą instancję lub, co gorsza, dyskretnie zastępuje twoje zadanie (jeśli przestrzegałeś konwencji nazewnictwa Windows (VolumeShadowCopy {$ GUID})).

Co musisz zrobić, to utworzyć go za pomocą GUI (najlepiej na Win7 / Win2008, ponieważ nowsze wersje systemu Windows domyślnie używają taskxml 1.2 zamiast bardziej kompatybilnego taskxml 1.1), eksportować zadanie jako XML za pomocą schtasks, programowo edytować ten XML , zapisz ten plik XML jako UTF16 i zaimportuj go. Na szczęście po przejściu przez interfejs GUI na początku można to wszystko zrobić w wierszu polecenia.

Chciałbym napisać kod, ale to, co napisałem, jest zastrzeżone i nie mam pozwolenia od mojego pracodawcy. Mam nadzieję, że wskazówka XML pozwoli przynajmniej zaoszczędzić niezliczone godziny. Właśnie wdrożyłem rozwiązanie XML na setkach zarządzanych serwerów, z wielkim sukcesem.


1

Dzięki wszystkim, którzy przyczynili się do tego wątku. Było to pomocne i pozwoliło mi zaoszczędzić dużo pracy. Następujący skrypt PowerShell został przetestowany w systemie Windows Server 2008 R2.

Poniższy przykład tworzy migawkę co 2 godziny między Mo.-Fr. od 08:00 do 18:00 w tomie C:

Jeśli chcesz zmodyfikować harmonogram, po prostu edytuj lub zamień wbudowane dane XML.

Uwaga: brak gwarancji. Brak odpowiedzialności. Proszę przetestować we własnym laboratorium przed użyciem w środowisku produkcyjnym.

# 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

Najlepsze, co mogę zrobić, to wskazać ci tutaj , a konkretnie wskazać ten i ten .

Nie adresuj dokładnie tego, czego szukasz, ale zaznaczę, że możesz tworzyć kopie w tle w dowolnym momencie, ponieważ VSS jest usługą działającą w tle, dopóki nie zostanie wywołana.


0

Dostałem dokładnie to, czego potrzebowałem z poniższym kodem, moim wymaganiem była konfiguracja VSS, ale także musiała być widoczna w GUI. Kluczową częścią, aby był widoczny w GUI, jest dodanie identyfikatora woluminu do nazwy zaplanowanego zadania, jak wskazał użytkownik 261949 (to trochę dziwne, szczerze mówiąc, szukałem klucza rejestru, ale absolutnie nic nie znalazłem ...). Skończyłem z następującym kodem, który odpowiada moim potrzebom:

#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'

Dziękujemy wszystkim za przydatne informacje!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.