New vCenter Scheduled Tasks with PowerCLI (Part 2)

In a recent post New vCenter Scheduled Tasks with PowerCLI (Part 1), I provided two functions that return information related to vCenter Scheduled Tasks. This was my first step towards creating a PowerShell function that I could run to create scheduled snapshot tasks. This post will cover the create scheduled snapshot function.

NOTE: This function requires two additional functions, Get-VMScheduledSnapshots and Get-VIScheduledTasks, available here: New vCenter Scheduled Tasks with PowerCLI (Part 1).

[cc lang=”powershell”]
Function New-VMScheduledSnapshot {
[string]$taskName=”$vmName Scheduled Snapshot”

# Verify we found a single VM
$vm = (get-view -viewtype virtualmachine -property Name -Filter @{“Name”=”^$($vmName)$”}).MoRef
if (($vm | Measure-Object).Count -ne 1 ) { “Unable to locate a specific VM $vmName”; break }

# Validate datetime value and convert to UTC
try { $castRunTime = ([datetime]$runTime).ToUniversalTime() } catch { “Unable to convert runtime parameter to date time value”; break }
if ( [datetime]$runTime -lt (Get-Date) ) { “Single run tasks can not be scheduled to run in the past. Please adjust start time and try again.”; break }

# Verify the scheduled task name is not already in use
if ( (Get-VIScheduledTasks | ?{$_.Name -eq $taskName } | Measure-Object).Count -eq 1 ) { “Task Name `”$taskName`” already exists. Please try again and specify the taskname parameter”; break }

$spec = New-Object VMware.Vim.ScheduledTaskSpec
$ = $taskName
$spec.description = “Snapshot of $vmName scheduled for $runTime”
$spec.enabled = $true
if ( $notifyEmail ) {$spec.notification = $notifyEmail}
($spec.scheduler = New-Object VMware.Vim.OnceTaskScheduler).runAt = $castRunTime
($spec.action = New-Object VMware.Vim.MethodAction).Name = “CreateSnapshot_Task”
$spec.action.argument = New-Object VMware.Vim.MethodActionArgument[] (4)
($spec.action.argument[0] = New-Object VMware.Vim.MethodActionArgument).Value = “$vmName scheduled snapshot”
($spec.action.argument[1] = New-Object VMware.Vim.MethodActionArgument).Value = “Snapshot created using $taskName”
($spec.action.argument[2] = New-Object VMware.Vim.MethodActionArgument).Value = $false # Snapshot memory
($spec.action.argument[3] = New-Object VMware.Vim.MethodActionArgument).Value = $false # quiesce guest file system (requires VMware Tools)

[Void](Get-View -Id ‘ScheduledTaskManager-ScheduledTaskManager’).CreateScheduledTask($vm, $spec)
Get-VMScheduledSnapshots | ?{$_.Name -eq $taskName }

# Create a snapshot of the VM test002 at 9:40AM on 3/2/13
New-VMScheduledSnapshot test002 "3/2/13 9:40AM"

# Create a snapshot and send an email notification
New-VMScheduledSnapshot test002 "3/2/13 9:40AM"

# Use all of the options and name the parameters
New-VMScheduledSnapshot -vmname 'test001' -runtime '3/2/13 9:40am' -notifyemail '' -taskname 'My scheduled task of test001'

I hope someone finds this function useful.

This entry was posted in Scripting, Virtualization. Bookmark the permalink.

11 Responses to New vCenter Scheduled Tasks with PowerCLI (Part 2)

  1. TJ Hansen says:

    This is an awesome function but could you help me modify it to schedule vstorage migrations and/or vmotion to another host?

  2. TJ, I like how you think. Yes, I would think it would be easier to make a new function for each of these scenarios than to modify the existing on (as each would require different input/validation). I tried to make a sample function that could be used to schedule a vmotion, but I couldn’t get it to work as expected in the few minutes I had to look at the code. I’ll leave myself a note to pick back up on this when I return from VMworld in about a week. If you want to take a stab at it, I would recommend using the VMware Onyx Fling ( and then creating a scheduled vmotion in the GUI. That process should kick out some powershell that should be easily adaptable to the function provided above. If you come up with something please let me know, I’d like to see how it comes out!

  3. Hey TJ, I sat down to take a look at this, but after a quick Google search, it looks like LucD may have already done the work. Have you seen his post on scheduled tasks?

  4. Venkat says:

    I used this great function of yours but keep getting this error
    Exception calling “CreateScheduledTask” with “2” argument(s): “The object has
    already been deleted or has not been completely created”

    The error is on this line
    [Void](Get-View -Id ‘ScheduledTaskManager-ScheduledTaskManager’).CreateScheduledTask($vm, $spec)

    Have you encountered it and do you know of ways to resolve, if you do can you please if you have time, tell me. My email is

  5. Adrian says:

    How can I make this script read VM names from a text file? I have several tasks scheduled for multiple VMs. HELP!!!!!!

  6. Pingback: Snapshot scheduling

  7. Frank says:

    I tried using your functions as a starting point for a script I was making to automate snapshots. I ran into issues removing the task I had created previously – the same problem as Venkat had, actually. This is what I used to accomplish the task I needed.

    1. Connect to server
    Connect-VIServer -server $sVCenterHost -user $username -password $password |out-null

    2. Populate variable with the task that matches the name:
    $_task = Get-View -Id $taskName

    3. Remove the task

    You first need to be connected to the VS server, meaning you must use these commands from the PowerCLI shell, or initialize the PowerCLI commandlets in a normal PowerShell window.

    I hope this helps someone, it took me longer than I’d care to admit to get this working haha.

  8. sat says:

    Brian, Thanks for this script, very useful for me. small concern
    I want Spec.Description, as a Input “Snapshot request from this team, I created blah blah”..?

  9. Gerry Maddock says:

    These work great (running 6.7u2), thank you!!!!

    Is there an easy way to remove already completed tasks? When I go to re-run New-VMScheduledSnapshot test002 “3/2/13 9:40AM” (for example) it says the task is already set. If I want to reschedule, I have to add: -taskname “whatever”

    I have tried get-task & stop-task -task “taskname”

  10. Hey @Gerry, glad you found some value with these functions. I’ll work on a Remove-VIScheduledTask function and get it posted. One quick workaround would be to update line 18 of the function to state:
    if ( (Get-VIScheduledTasks | ?{$_.Name -eq $taskName } | Measure-Object).Count -eq 1 ) { $taskName = “$taskName $(Get-Random)” }
    With this change, instead of throwing an error and breaking out of the function, we’ll just add a random number to the end of the task name after that first run.

  11. Hey @Gerry, I put together a Remove-VIScheduledTask function that can remove a scheduled task by task name or pipeline. The function is below & some sample usage is listed below that. Its been a couple years since I built a function, but I tested this one out in a lab and it seems to get the job done. Hope this helps!

    Function Remove-VIScheduledTask {
    [parameter(ParameterSetName=’ID’, ValueFromPipeline)]$ScheduledTask
    begin {
    if ($TaskName) { $ScheduledTask = Get-VIScheduledTasks -Full | ?{$_.Name -eq $TaskName} }
    } # end begin block

    process {
    $thisView = Get-View -Id ($ScheduledTask.ScheduledTask)
    if ($thisView) {
    “Removing task $($ScheduledTask.Name)”
    } else {
    “No Snapshot found”
    } # end process block
    } # end Remove-VIScheduledTask

    Example usage:
    Remove-VIScheduledTask -SnapshotName ‘VM Name – Take Snapshot’
    Get-VIScheduledTasks -Full |?{$ -eq ‘VM Name – Take Snapshot’} |Remove-VIScheduledTask
    Get-VIScheduledTasks -Full |?{$ -match ‘VM Name’} |Remove-VIScheduledTask

Leave a Reply

Your email address will not be published. Required fields are marked *


Notify me of followup comments via e-mail. You can also subscribe without commenting.