Hi All,
I there any way to use PowerCli to schedule a snapshot? I'm looking to built a script to take user inputs such as Vm name, snapshot name, snapshot date, etc. to schedule a snapshot. I'm hoping to create a simple webpage to take some user inputs and pass it to script. I saw some examples that use PowerShell to create schedule task but they are all about creating a windows scheduled task. I would like to create the task as you would create in vSphere.
Thanks,
Haluk
I did a post on that, see Scheduled Tasks – MethodAction for some background info.
Try like this
###############
# These are the values you should get from your webform
#
$vmName = 'MyVM'
$snapTime = Get-Date "31/10/16 23:00"
$snapName = 'Test'
$snapDescription = 'Scheduled snapshot'
$snapMemory = $false
$snapQuiesce = $true
$emailAddr = 'lucd@lucd.info'
###############
$vm = Get-VM -Name $vmName
$si = get-view ServiceInstance
$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager
$spec = New-Object VMware.Vim.ScheduledTaskSpec
$spec.Name = "Snapshot",$_.VMname -join ' '
$spec.Description = "Take a snapshot of $($vm.Name)"
$spec.Enabled = $true
$spec.Notification = $emailAddr
$spec.Scheduler = New-Object VMware.Vim.OnceTaskScheduler
$spec.Scheduler.runat = $snapTime
$spec.Action = New-Object VMware.Vim.MethodAction
$spec.Action.Name = "CreateSnapshot_Task"
@($snapName,$snapDescription,$snapMemory,$snapQuiesce) | %{
$arg = New-Object VMware.Vim.MethodActionArgument
$arg.Value = $_
$spec.Action.Argument += $arg
}
$scheduledTaskManager.CreateObjectScheduledTask($vm.ExtensionData.MoRef, $spec)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hate to bring up an old thread but is there a way to modify this script so that it uses the import-csv function. I would like to have the values be VMName, and Description. I am having a hard time with this one.
You mean something like this?
It assumes a CSV with this layout
VMName,Description
VM1,Test1
VM2,Test2
###############
# These are the values you should get from your webform
#
$snapTime = Get-Date "31/10/16 23:00"
$snapName = 'Test'
$snapDescription = 'Scheduled snapshot'
$snapMemory = $false
$snapQuiesce = $true
$emailAddr = 'lucd@lucd.info'
$fileName = 'C:\Temp\snap.csv'
###############
Import-Csv -Path $fileName -UseCulture | %{
$vm = Get-VM -Name $_.VMName
$si = get-view ServiceInstance
$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager
$spec = New-Object VMware.Vim.ScheduledTaskSpec
$spec.Name = "Snapshot",$vm.Name -join ' '
$spec.Description = $_.Description
$spec.Enabled = $true
$spec.Notification = $emailAddr
$spec.Scheduler = New-Object VMware.Vim.OnceTaskScheduler
$spec.Scheduler.runat = $snapTime
$spec.Action = New-Object VMware.Vim.MethodAction
$spec.Action.Name = "CreateSnapshot_Task"
@($snapName,$snapDescription,$snapMemory,$snapQuiesce) | %{
$arg = New-Object VMware.Vim.MethodActionArgument
$arg.Value = $_
$spec.Action.Argument += $arg
}
$scheduledTaskManager.CreateObjectScheduledTask($vm.ExtensionData.MoRef, $spec)
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Wow! You sir, are a legend!
Hi LucD,
How can I add snaptime column in csv file? I want to make csv file look like: VMname | Snapshot name | description | date | email
*email column is working but not the rest. Please check, thanks!
$snapTime = Get-Date "04/17/18 08:00"
$snapName = 'Test'
$snapDescription = 'Scheduled snapshot'
$snapMemory = $true
$snapQuiesce = $false
$fileName = 'C:\snapshotfile.csv'
Import-Csv -Path $fileName -UseCulture | %{
$vm = Get-VM -Name $_.VMName
$si = get-view ServiceInstance
$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager
$spec = New-Object VMware.Vim.ScheduledTaskSpec
$spec.Name = "Snapshot",$vm.Name -join ' '
$spec.Description = $_.Description
$spec.Enabled = $true
$spec.Notification = $_.email
$spec.Scheduler = New-Object VMware.Vim.OnceTaskScheduler
$spec.Scheduler.runat = $snapTime
$spec.Action = New-Object VMware.Vim.MethodAction
$spec.Action.Name = "CreateSnapshot_Task"
@($snapName,$snapDescription,$snapMemory,$snapQuiesce) | %{
$arg = New-Object VMware.Vim.MethodActionArgument
$arg.Value = $_
$spec.Action.Argument += $arg
}
$scheduledTaskManager.CreateObjectScheduledTask($vm.ExtensionData.MoRef, $spec)
}
All properties in the objects imported from a CSV are strings.
You can convert to a DateTime object with the Get-Date cmdlet.
For example:
$date = '20/04/2018 09:00'
Get-Date $date
You'll have to experiment how Get-Date interprets the string, there are differences.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
This code indeed works, thanks!
There's only a problem when you connect to multiple VIservers (in my case 8).
More often than not it will return me this error:
Exception calling "CreateObjectScheduledTask" with "2" argument(s): "The object has already been deleted or has not been completely created"
At D:\Scripts\ScheduleSnapshot.psm1:160 char:5
+ $scheduledTaskManager.CreateObjectScheduledTask($vm.ExtensionData ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : VimException
How can I adjust the code so it automatically finds the right viserver?
Btw. VMware should create some cmdlets for scheduled tasks don't you think?
You will have to use the Server parameter on the cmdlets.
And you will have to pass the name of the vCenter.
###############
# These are the values you should get from your webform
#
$snapTime = Get-Date "31/10/16 23:00"
$snapName = 'Test'
$snapDescription = 'Scheduled snapshot'
$snapMemory = $false
$snapQuiesce = $true
$emailAddr = 'lucd@lucd.info'
$fileName = 'C:\Temp\snap.csv'
$vcName = 'MyVC'
###############
Import-Csv -Path $fileName -UseCulture | %{
$vm = Get-VM -Name $_.VMName -Server $vcName
$si = Get-View ServiceInstance -Server $vcName
$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager -Server $vcName
$spec = New-Object VMware.Vim.ScheduledTaskSpec
$spec.Name = "Snapshot",$vm.Name -join ' '
$spec.Description = $_.Description
$spec.Enabled = $true
$spec.Notification = $emailAddr
$spec.Scheduler = New-Object VMware.Vim.OnceTaskScheduler
$spec.Scheduler.runat = $snapTime
$spec.Action = New-Object VMware.Vim.MethodAction
$spec.Action.Name = "CreateSnapshot_Task"
@($snapName,$snapDescription,$snapMemory,$snapQuiesce) | %{
$arg = New-Object VMware.Vim.MethodActionArgument
$arg.Value = $_
$spec.Action.Argument += $arg
}
$scheduledTaskManager.CreateObjectScheduledTask($vm.ExtensionData.MoRef, $spec)
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Awesome. that works!
to prevent having to use the -Server argument on the Get-VM cmdlet, I changed the code to:
Before you do the Connect-VIServer, you might want to check the DefaultVIServerMode setting with the Get-PowerCLIConfiguration cmdlet.
To make sure it is set to 'multiple'
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I am making sure of that
if ($CurrentPowerCLIConfig.DefaultVIServerMode -ne "Multiple") {
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Confirm:$false | Out-Null
}
Hi LucD,
Slightly stuck with one thing, below works perfectly but I wish to change from single task execution to reocurring event, once a month.
Doing so, changing "$spec.Scheduler = New-Object VMware.Vim.OnceTaskScheduler" to "$spec.Scheduler = New-Object VMware.Vim.MonthlyByWeekdayTaskScheduler" although, I'm unable to ajdust parameters like offset, day and time.
Any hints please? For example, willing to task occur second Tuesday, every 1 month at 6:00am.
Try like this
$spec = New-Object VMware.Vim.ScheduledTaskSpec
$spec.Scheduler = New-Object VMware.Vim.MonthlyByWeekdayTaskScheduler
$spec.Scheduler.Offset = [VMware.Vim.WeekOfMonth]::second
$spec.Scheduler.Weekday = [VMware.Vim.DayOfWeek]::tuesday
$spec.Scheduler.Hour = 6
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks LucD unfortunately, receiving below. Definitely doing something wrong, although I'm lost.
Here is full script:
###############
# These are the values you should get from your webform
#
$vmName = 'servername'
$snapTime = Get-Date "10/11/18 23:00"
$snapName = 'Test'
$snapDescription = 'Scheduled snapshot'
$snapMemory = $false
$snapQuiesce = $true
$emailAddr = 'xxx@xxx.com'
###############
$vm = Get-VM -Name $vmName
$si = get-view ServiceInstance
$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager
$spec = New-Object VMware.Vim.ScheduledTaskSpec
$spec.Scheduler = New-Object VMware.Vim.MonthlyByWeekdayTaskScheduler
$spec.Scheduler.Offset = [VMware.Vim.WeekOfMonth]::second
$spec.Scheduler.Weekday = [VMware.Vim.DayOfWeek]::tuesday
$spec.Scheduler.Hour = 6
$spec.Name = "Snapshot",$_.VMname -join ' '
$spec.Description = "Take a snapshot of $($vm.Name)"
$spec.Enabled = $true
$spec.Notification = $emailAddr
$spec.Action = New-Object VMware.Vim.MethodAction
$spec.Action.Name = "CreateSnapshot_Task"
@($snapName,$snapDescription,$snapMemory,$snapQuiesce) | %{
$arg = New-Object VMware.Vim.MethodActionArgument
$arg.Value = $_
$spec.Action.Argument += $arg
}
$scheduledTaskManager.CreateObjectScheduledTask($vm.ExtensionData.MoRef, $spec)
Oops, the Interval property needs to be explicitly set (I assumed it would take the default, which is 1).
Try with this version
###############
# These are the values you should get from your webform
#
$vmName = 'servername'
$snapTime = Get-Date "10/11/18 23:00"
$snapName = 'Test'
$snapDescription = 'Scheduled snapshot'
$snapMemory = $false
$snapQuiesce = $true
$emailAddr = 'xxx@xxx.com'
###############
$vm = Get-VM -Name $vmName
$si = get-view ServiceInstance
$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager
$spec = New-Object VMware.Vim.ScheduledTaskSpec
$spec.Scheduler = New-Object VMware.Vim.MonthlyByWeekdayTaskScheduler
$spec.Scheduler.Offset = [VMware.Vim.WeekOfMonth]::second
$spec.Scheduler.Weekday = [VMware.Vim.DayOfWeek]::tuesday
$spec.Scheduler.Hour = 6
$spec.Scheduler.Interval = 1
$spec.Name = "Snapshot",$_.VMname -join ' '
$spec.Description = "Take a snapshot of $($vm.Name)"
$spec.Enabled = $true
$spec.Notification = $emailAddr
$spec.Action = New-Object VMware.Vim.MethodAction
$spec.Action.Name = "CreateSnapshot_Task"
@($snapName,$snapDescription,$snapMemory,$snapQuiesce) | %{
$arg = New-Object VMware.Vim.MethodActionArgument
$arg.Value = $_
$spec.Action.Argument += $arg
}
$scheduledTaskManager.CreateObjectScheduledTask($vm.ExtensionData.MoRef, $spec)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Works now perfectly, thank you!
I am trying to add some user input to the script as follows:
###############
# These are the values you should get from your webform
$Vcenter= Read-Host -Prompt "Which Vcenter is the machine located on?"
$vmName = Read-Host -Prompt "Snapshot of VM"
$date = Read-Host -Prompt "When would you like this to be taken (DD/MM/YY 23:00 Format)"
$Owner = Read-Host -Prompt "Who are you?"
$requester = Read-Host -Prompt "Email Address of Requester"
$SR = Read-Host -Prompt "What is the SR number?"
$snapTime = Get-Date "$date"
$snapName = "Snapshot of $vmName by $owner on $date per SR $SR"
$snapDescription = "Snapshot of $vmName by $owner on $date Per SR $SR"
$snapMemory = $false
$snapQuiesce = $true
$emailAddr = @("Myemailaddress@somewhere.com", "$requester")
###############
#Add VMWare Snapin & connect to vcenter
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer -server $Vcenter
$vm = Get-VM -Name $vmName
$si = get-view ServiceInstance
$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager
$spec = New-Object VMware.Vim.ScheduledTaskSpec
$spec.Name = "Snapshot",$_.VMname -join ' '
$spec.Description = "Take a snapshot of $($vm.Name)"
$spec.Enabled = $true
$spec.Notification = $emailAddr
$spec.Scheduler = New-Object VMware.Vim.OnceTaskScheduler
$spec.Scheduler.runat = $snapTime
$spec.Action = New-Object VMware.Vim.MethodAction
$spec.Action.Name = "CreateSnapshot_Task"
@($snapName,$snapDescription,$snapMemory,$snapQuiesce) | %{
$arg = New-Object VMware.Vim.MethodActionArgument
$arg.Value = $_
$spec.Action.Argument += $arg
}
$scheduledTaskManager.CreateObjectScheduledTask($vm.ExtensionData.MoRef, $spec)
but I get the following error. I'm pretty new to scripting, so can someone please help me?:
Cannot convert argument "obj", with value: "System.Object[]", for
"CreateObjectScheduledTask" to type "VMware.Vim.ManagedObjectReference": "Cannot convert
the "System.Object[]" value of type "System.Object[]" to type
"VMware.Vim.ManagedObjectReference"."
At \\MyServer\Folder1\Folder2\ScheduleSnapshots.ps1:43 char:1
+ $scheduledTaskManager.CreateObjectScheduledTask($vm.ExtensionData.MoR ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
Could it be that Get-VM -Name $vmName returns more than 1 VM?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference