¿Cómo habilitar el volumen de instantáneas en una unidad específica (D :, E:, ...) y configurar la programación usando Powershell?
Solo necesito algunos consejos sobre cómo comenzar.
¿Cómo habilitar el volumen de instantáneas en una unidad específica (D :, E:, ...) y configurar la programación usando Powershell?
Solo necesito algunos consejos sobre cómo comenzar.
Respuestas:
Puede crear una instantánea en una unidad específica utilizando un objeto WMI como se explica en el artículo de Microsoft .
Habilitar instantáneas de volumen en una unidad específica (D :, E:, ...) es dos cosas
Me tomó un poco de tiempo hacer que esto funcionara (después de encontrar el simple error que causaba que fallara), y la función está incompleta. Quiero agregar la capacidad de habilitarlo en una computadora remota, lo que probablemente tendrá que hacerse a través de una tarea que se ejecuta una vez. Si alguien modifica esto y agrega eso, ¡hágamelo saber!
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);
}
Aunque esto funciona, e imita lo que sucede cuando lo haces a través de la GUI, todavía se muestra como deshabilitado para esa unidad. Pero si lo habilitas, ¡nada cambia! (LOL) Supongo que hay algo que también debe modificarse en el registro.
$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"
Después de un montón de problemas con él, funcionó de manera ligeramente diferente (también parece mostrarse correctamente a través de la GUI).
Gracias a esta página para obtener un poco de ayuda: https://social.technet.microsoft.com/forums/windowsserver/en-US/fb69840d-5f52-4711-8168-2faa23088233/shadow-copy-schedule-per-script
La desventaja de usar schtasks (lo que usa esa página) es que no puedo tener múltiples desencadenantes hasta donde puedo ver.
Además, debido a la forma en que solucioné los problemas de la solución (utilicé un bindiff de xml de trabajo / no funciona), no estoy completamente convencido de que los indicadores que uso sean óptimos.
Más simple significa usar schtasks que se muestran en la interfaz de usuario, compatible en PowerShell 2. Diseñado para una compilación estándar, puede necesitar jugar con $ volumeinfo [x] al crear $ taskrun para encontrar el volumen apropiado.
$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 "
Puede configurar los siguientes argumentos adecuadamente:
NOTA: El modificador / TR REQUIERE el espacio al final, si no está allí, reemplaza la barra diagonal inversa final con una comilla doble, lo que hace que la interfaz de usuario de VSS no reconozca la tarea.
Esto es lo que uso en PowerShell . Es un enlace a mi sitio, pero se ve mucho mejor de lo que se pega aquí.
#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"
}
La Copia de sombra se habilita creando tareas que llaman a vssadmin.exe.
PowerShell 3.0 tiene cmdlets que le permiten crear tareas, pero dependen de syscalls que no se implementaron hasta Windows 8 / Windows Server 2012. Necesita los siguientes tres de estos cmdlets para hacer esto de la manera PowerShell:
register-scheduledTask
new-scheduledtaskaction
new-scheduledtasktrigger
En versiones anteriores de Windows, estará restringido a usar schtasks.exe.
Sin embargo, y aquí es donde esta respuesta difiere de las demás, crear una tarea de Copia de sombra de esta manera no es la forma correcta de hacer las cosas, ya que cualquier cambio que realice no aparecerá en la GUI. Como tal, un usuario no observador puede desconocer que se ha habilitado Shadow Copy, lo que resulta en que habilite una segunda instancia del mismo, o peor, sobrescriba su tarea en silencio (si siguió las convenciones de nomenclatura de Windows (VolumeShadowCopy {$ GUID})).
Lo que debe hacer es crear uno a través de la GUI (preferiblemente en Win7 / Win2008, ya que las versiones más nuevas de Windows usan taskxml 1.2 por defecto en lugar del taskxml 1.1 más compatible), exportar la tarea como XML a través de schtasks, editar programáticamente ese XML , guarde ese XML como UTF16 e impórtelo. Afortunadamente, una vez que pasa la GUI al principio, todo esto se puede hacer en la línea de comandos.
Me gustaría publicar el código, pero lo que escribí es de propiedad y no tengo permiso de mi empleador. Espero que la sugerencia XML, al menos, le ahorre incontables horas. Acabo de implementar la solución XML en cientos de servidores administrados, con gran éxito.
Gracias a todos, eso contribuyó a este hilo. Fue útil y me ahorró mucho trabajo. El siguiente script de PowerShell se probó en Windows Server 2008 R2.
El siguiente ejemplo crea una Instantánea cada 2h entre lunes a viernes. de 08: 00h-18: 00h en el Volumen C:
Si desea modificar la programación simplemente edite o reemplace los datos XML en línea.
Atención: sin garantía. Sin responsabilidad. Por favor, pruebe en su propio laboratorio antes de usarlo en un entorno de producción.
# 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%"
Obtuve exactamente lo que necesitaba con el siguiente código, mi requisito era configurar VSS pero también tenía que estar visible en la GUI. La parte clave para hacerlo visible en la GUI es agregar la ID del volumen en el nombre de la tarea programada como lo indicó el usuario 261949 (eso es un poco extraño, sinceramente estaba buscando una clave de registro pero no encontré absolutamente nada ...). Terminé con el siguiente código que se adapta a mis necesidades:
#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'
¡Gracias a todos por sus útiles informaciones!