VMware Cloud Community
vmsf
Contributor
Contributor
Jump to solution

Scheduling suspend and power on

Hi,

I have a VDI View 3.0.1 test environment. I want to schedule the Anti Virus to run at night. I also want my VMs to be suspended when not in use.

Is there a PowerShell script to schedule all the Virtual Desktops to power on from suspend at a certain time during the night and again go to suspend mode at a later time.

Thanks,

-vmsf

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

There is a thread, see , where I provided such a script.

But since the script uses some older conventions, this is a new, updated version.

First, the creation of a VC scheduled task for suspending VMs.

# Find object(s) on which to perform action
$VMs = Get-View -ViewType VirtualMachine -Filter @{"Name" = "PC*"}

foreach($vm in $VMs){
# What should the scheduled task do
	$ma = New-Object VMware.Vim.MethodAction
	$ma.Argument = $null
	$ma.Name = "SuspendVM_Task"
# Run at 21:00 every day
	$dTScheduler = New-Object VMware.Vim.DailyTaskScheduler
	$dTScheduler.Hour = 21
	$dTScheduler.Minute = 0
	$dTScheduler.Interval = 1
# Create the scheduled task
	$tSpec = New-Object VMware.Vim.ScheduledTaskSpec
	$tSpec.Action = $ma
	$tSpec.Description = "Suspend " + $vm.Name
	$tSpec.Enabled = $TRUE
	$tSpec.Name = "Suspend " + $vm.Name 
	$tSpec.Notification = "my.email@address.com"
	$tSpec.Scheduler = $dTScheduler

	$stMgr = Get-View ScheduledTaskManager
	$stMgr.CreateScheduledTask($vm.MoRef,$tSpec)
}

Second, the creation of a scheduled task to start VMs.

# Find object(s) on which to perform action
$VMs = Get-View -ViewType VirtualMachine -Filter @{"Name" = "PC*"}

foreach($vm in $VMs){
	$maa = New-Object VMware.Vim.MethodActionArgument
       $maa.Value = $vm.Runtime.Host
# What should the scheduled task do
	$ma = New-Object VMware.Vim.MethodAction
	$ma.Argument = $maa
	$ma.Name = "PowerOnVM_Task"
# Run at 07:00 every day
	$dTScheduler = New-Object VMware.Vim.DailyTaskScheduler
	$dTScheduler.Hour = 7
	$dTScheduler.Minute = 0
	$dTScheduler.Interval = 1
# Create the scheduled task
	$tSpec = New-Object VMware.Vim.ScheduledTaskSpec
	$tSpec.Action = $ma
	$tSpec.Description = "Start " + $vm.Name
	$tSpec.Enabled = $TRUE
	$tSpec.Name = "Start " + $vm.Name 
	$tSpec.Notification = "my.email@address.com"
	$tSpec.Scheduler = $dTScheduler

	$stMgr = Get-View ScheduledTaskManager
	$stMgr.CreateScheduledTask($vm.MoRef,$tSpec)
}

Note1: the first Get-View selects the VirtualMachine object(s) for which you want to create scheduled tasks. In the code I selected all guests whose name starts with PC.

But you can use whatever mechanism/filter you want to create this collections of VirtualMachine object(s).

Note2: to avoid having multiple scheduled tasks fire at the same time, you could increment the Minute property for each schduled task.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

Reply
0 Kudos
16 Replies
LucD
Leadership
Leadership
Jump to solution

There are 2 ways you can create these schedules.

1) With the Scheduled Tasks in the VC

2) With Windows Scheduled tasks on a Windows host

Option 1 requires the use of an SDK method.

Option 2 is rather straightforward.

You write 2 simple scripts for the suspend and the start and you schedule them in the Windows Task Scheduler.

Just make sure you take into account Rob's fix for scheduled tasks with VITK v1.5. See .


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
vmsf
Contributor
Contributor
Jump to solution

Thanks for the response LucD.

Is there an available solution with option 1 which I can use right now?

-vmsf

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

There is a thread, see , where I provided such a script.

But since the script uses some older conventions, this is a new, updated version.

First, the creation of a VC scheduled task for suspending VMs.

# Find object(s) on which to perform action
$VMs = Get-View -ViewType VirtualMachine -Filter @{"Name" = "PC*"}

foreach($vm in $VMs){
# What should the scheduled task do
	$ma = New-Object VMware.Vim.MethodAction
	$ma.Argument = $null
	$ma.Name = "SuspendVM_Task"
# Run at 21:00 every day
	$dTScheduler = New-Object VMware.Vim.DailyTaskScheduler
	$dTScheduler.Hour = 21
	$dTScheduler.Minute = 0
	$dTScheduler.Interval = 1
# Create the scheduled task
	$tSpec = New-Object VMware.Vim.ScheduledTaskSpec
	$tSpec.Action = $ma
	$tSpec.Description = "Suspend " + $vm.Name
	$tSpec.Enabled = $TRUE
	$tSpec.Name = "Suspend " + $vm.Name 
	$tSpec.Notification = "my.email@address.com"
	$tSpec.Scheduler = $dTScheduler

	$stMgr = Get-View ScheduledTaskManager
	$stMgr.CreateScheduledTask($vm.MoRef,$tSpec)
}

Second, the creation of a scheduled task to start VMs.

# Find object(s) on which to perform action
$VMs = Get-View -ViewType VirtualMachine -Filter @{"Name" = "PC*"}

foreach($vm in $VMs){
	$maa = New-Object VMware.Vim.MethodActionArgument
       $maa.Value = $vm.Runtime.Host
# What should the scheduled task do
	$ma = New-Object VMware.Vim.MethodAction
	$ma.Argument = $maa
	$ma.Name = "PowerOnVM_Task"
# Run at 07:00 every day
	$dTScheduler = New-Object VMware.Vim.DailyTaskScheduler
	$dTScheduler.Hour = 7
	$dTScheduler.Minute = 0
	$dTScheduler.Interval = 1
# Create the scheduled task
	$tSpec = New-Object VMware.Vim.ScheduledTaskSpec
	$tSpec.Action = $ma
	$tSpec.Description = "Start " + $vm.Name
	$tSpec.Enabled = $TRUE
	$tSpec.Name = "Start " + $vm.Name 
	$tSpec.Notification = "my.email@address.com"
	$tSpec.Scheduler = $dTScheduler

	$stMgr = Get-View ScheduledTaskManager
	$stMgr.CreateScheduledTask($vm.MoRef,$tSpec)
}

Note1: the first Get-View selects the VirtualMachine object(s) for which you want to create scheduled tasks. In the code I selected all guests whose name starts with PC.

But you can use whatever mechanism/filter you want to create this collections of VirtualMachine object(s).

Note2: to avoid having multiple scheduled tasks fire at the same time, you could increment the Minute property for each schduled task.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
vmsf
Contributor
Contributor
Jump to solution

Thanks LucD - this is exactly what I was looking for!

-vmsf

Reply
0 Kudos
admin
Immortal
Immortal
Jump to solution

For option 2 : Do you have a sample script for suspending and starting machine where I can specify a particular resource pool and select all the VMs in that pool only? Also it would be nice if I can delay the startup of each machine by 30 seconds to avoid overloading the ESX server.

Thanks again for your help.

-vmsf

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Sure, suspending and starting

Get-ResourcePool <pool-name> | Get-Vm | Suspend-Vm -Confirm:$false
Get-ResourcePool <pool-name> | Get-Vm | Start-Vm -Confirm:$false

And If you want to delay the startup of the guests

Get-ResourcePool <pool-name> | Get-Vm | %{Start-Vm -Vm $_ -Confirm:$false; sleep 30}

You can save the scripts in a .ps1 file and then schedule the execution with the Windows Task Scheduler.

You have to add a Connect-ViServer cmdlet to the script of course.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
admin
Immortal
Immortal
Jump to solution

Perfect - Thanks again Smiley Happy

Is it possible to trigger the suspend and start based on a certain event. For example when Antivirus has completed the scan, it might write an event to the event log or somekind of change in the machine, and that could trigger the start and suspend (i hope its ok if I ask more questions Smiley Wink )

-vmsf

Reply
0 Kudos
vmsf
Contributor
Contributor
Jump to solution

any thoughts on the previous question - any help is appreciated...

Thanks

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I would look in the direction of the new "event trigger" feature that is available in Task Scheduler 2.0 that comes with W2K8 and Vista.

You could start a PS script from there.

I'm not sure if there are currently any Snapins and/or Modules that expose this feature to PS but since the Task Scheduler 2.0 has a published API it should be not too difficult.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
vmsf
Contributor
Contributor
Jump to solution

Thanks Luc.

Can the trigger be a creation of a file or change in the properties of a file or anything else that can be tracked?

-vmsf

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You can always use a script that looks for such changes on a regular basis.

And since PS v2 CTP2 there is the Register-WMIEvent cmdlet that opens quite some possibilties.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
vmsf
Contributor
Contributor
Jump to solution

Thanks Luc.

Are there any existing examples I can use?

-vmsf

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Were you looking for anything specific ?

Is it the end of the anti-virus scan with an entry in the eventlog ?

Or the presence of a specific file on the guest ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Were you looking for anything specific ?

Is it the end of the anti-virus scan with an entry in the eventlog ?

Or the presence of a specific file on the guest ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Were you looking for anything specific ?

Is it the end of the anti-virus scan with an entry in the eventlog ?

Or the presence of a specific file on the guest ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
vmsf
Contributor
Contributor
Jump to solution

The scan creates a file when it completes.

But it would be nice to know the solution to use both cases as a trigger

Thanks,

-vmsf

Reply
0 Kudos