PowerCLI script to schedule snapshots
##############START OF FUNCTION###############
Function Get-VIScheduledTasks {
PARAM ( [switch]$Full )
if ($Full) {
# Note: When returning the full View of each Scheduled Task, all date times are in UTC
(Get-View ScheduledTaskManager).ScheduledTask | %{ (Get-View $_).Info }
} else {
# By default, lets only return common headers and convert all date/times to local values
(Get-View ScheduledTaskManager).ScheduledTask | %{ (Get-View $_ -Property Info).Info } |
Select-Object Name, Description, Enabled, Notification, LastModifiedUser, State, Entity,
@{N="EntityName";E={ (Get-View $_.Entity -Property Name).Name }},
@{N="LastModifiedTime";E={$_.LastModifiedTime.ToLocalTime()}},
@{N="NextRunTime";E={$_.NextRunTime.ToLocalTime()}},
@{N="PrevRunTime";E={$_.LastModifiedTime.ToLocalTime()}},
@{N="ActionName";E={$_.Action.Name}}
}
}
Function Get-VMScheduledSnapshots {
Get-VIScheduledTasks | ?{$_.ActionName -eq 'CreateSnapshot_Task'} |
Select-Object @{N="VMName";E={$_.EntityName}}, Name, NextRunTime, Notification
}
Function New-VMScheduledSnapshot {
PARAM (
[string]$vmName,
[string]$runTime,
[string]$notifyEmail=$null,
[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
$spec.name = $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 }
}
Function Remove-VIScheduledTask {
PARAM ([string]$taskName)
(Get-View -Id ((Get-VIScheduledTasks -Full | ?{$_.Name -eq $taskName}).ScheduledTask)).RemoveScheduledTask()
}
##############END OF FUNCTION###############
Copy the above Function as a .ps1 file to this location: "C:\Windows\System32\WindowsPowerShell\v1.0"
You can then call these functions in your script.
##############BEGINNING OF SCRIPT###############
#### HTML Output Formatting #######
$a = "<style>"
$a = $a + "BODY{background-color:White ;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:Green}"
$a = $a + "TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:PaleGoldenrod}"
$a = $a + "</style>"
################################################################################################
Connect-VIServer vcenter_server
Remove-Item C:\Temp\ScheduleSnapshotReport.html
""
"Deleting all old scheduled snapshots that are already complete ..."
Get-VMScheduledSnapshots | ?{$_.NextRunTime -eq $null} | %{ Remove-VIScheduledTask $_.Name }
$report = @()
$date = Get-Date
$input = Import-Csv C:\Temp\server.csv
""
"Creating new scheduled snapshots ..."
foreach ($row in $input)
{
$VMName=$row.VMName
$Sched=$row.Schedule
$Mail=$row.Email
New-VMScheduledSnapshot $VMName $Sched "$Mail"
$report += $row
}
$report | ConvertTo-html -Head $a -Body "<H2> </H2>" >> C:\Temp\ScheduleSnapshotReport.html
$body = [System.IO.File]::ReadAllText('C:\Temp\ScheduleSnapshotReport.html')
$text = '<font=Arial>Snapshots have been scheduled for the virtual machines listed below as per the specified date and time. A confirmation mail will be sent to the email mentioned upon completion of the snapshot.</font>'
""
"Sending a confirmation e-mail to To@MailAddress.com ..."
Send-MailMessage -To To@MailAddress.com -From From@MailAddress.com -Subject "Scheduled Snapshot Report - $date" -Body "$text $body" -SmtpServer smtp.MailAddress.com -BodyAsHtml
Disconnect-VIServer vcenter_server -Confirm:$false
##############END OF SCRIPT###############
Content of server.csv