khalil1974
Enthusiast
Enthusiast

Possible to have one script to Schedule Monthly Power On, Power Off, Snapshot

Jump to solution

Hi

I was wondering if you can have a script to that will look at a csv and schedule monthly(every 2nd sunday)

- power on and after 7 hours later poweroff

- After 30 mins after power off take a snapshot(our systems need snapshot to be taken at the end).

Do you think the following script would work

CSV

VMName

<ServerName>

Script

connect-viserver xxxx

$Time = Get-Date '21/07/20 20:00'

$fileName = '.\serverlist.csv'

$WeekofMonth = 'Second'

$WeekofDay = 'Sunday'

$emailAddr = 'xxxxx'

$poweroffts = New-TimeSpan -Hours 7 -Minutes 00

(get-date) + $poweroffts

$snapshotts = New-TimeSpan -Hours 7 -Minutes 30

(get-date) + $snapshotts

Import-Csv -Path $fileName -UseCulture | %{

    $vm = Get-VM -Name $_.VMName

    $si = get-view ServiceInstance

    # Create the PowerOff Task

    $scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager

    $spec = New-Object VMware.Vim.ScheduledTaskSpec

    $spec.Name = "Recurring PowerOn of",$vm.Name -join ' '

    $spec.Description = "Recurring PowerOn of VM prior to Patching"

    $spec.Enabled = $true

    $spec.Notification = $emailAddr

    $spec = New-Object -TypeName VMware.Vim.MonthlyByWeekdayTaskScheduler

    $spec.Offset = $WeekofMonth

    $spec.Weekday = $WeekofDay

    $spec.Scheduler.runat = $Time

    $spec.Action = New-Object VMware.Vim.MethodAction

    $spec.Action.Name = "CreatePowerOn_Task"

    $scheduledTaskManager.CreateScheduledTask($vm.ExtensionData.MoRef, $spec)

    # Create the PowerOff Task

    $spec2 = New-Object VMware.Vim.ScheduledTaskSpec

    $spec2.Name = "Recurring PowerOff of",$vm.Name -join ' '

    $spec2.Description = "Recurring PowerOff of VM after Patching Completed"

    $spec2.Enabled = $true

    $spec2.Notification = $emailAddr

    $spec2 = New-Object -TypeName VMware.Vim.MonthlyByWeekdayTaskScheduler

    $spec2.Offset = $WeekofMonth

    $spec2.Weekday = $WeekofDay

    $spec2.Scheduler.runat = $poweroffts

    $spec2.Action = New-Object VMware.Vim.MethodAction

    $spec2.Action.Name = "CreatePowerOff_Task"

    $scheduledTaskManager.CreateScheduledTask($vm.ExtensionData.MoRef, $spec2)

    # Create the Snapshot Task

    $spec3 = New-Object VMware.Vim.ScheduledTaskSpec

    $spec3.Name = "Recurring Snanpshot of",$vm.Name -join ' '

    $spec3.Description = "Recurring Snapshot of VM after Patching Completed"

    $spec3.Enabled = $true

    $spec3.Notification = $emailAddr

    $spec3 = New-Object -TypeName VMware.Vim.MonthlyByWeekdayTaskScheduler

    $spec3.Offset = $WeekofMonth

    $spec3.Weekday = $WeekofDay

    $spec3.Scheduler.runat = $snapshotts

    $spec3.Action = New-Object VMware.Vim.MethodAction

    $spec3.Action.Name = "CreateSnapshot_Task"

    $scheduledTaskManager.CreateScheduledTask($vm.ExtensionData.MoRef, $spec3)

}

1 Solution

Accepted Solutions
LucD
Leadership
Leadership

Try something like this

connect-viserver xxxxx

$fileName = '.\serverlist.csv'

$emailAddr = 'xxxxx'


$now = Get-Date

$lastDayOfPreviousMonth = (Get-Date -Year $now.Year -Month $now.Month -Day 1 -Hour 20 -Minute 0 -Second 0).AddDays(-1)

$poweronTime = $lastDayOfPreviousMonth.AddDays(14 - [int]$lastDayOfPreviousMonth.DayOfWeek).ToUniversalTime()

$poweroffTime = $poweronTime.AddHours(7)

$snapshotTime = $poweroffTime.AddMinutes(30)


# Create the PowerOn Task Spec

$spec = New-Object VMware.Vim.ScheduledTaskSpec

$spec.Name = "Recurring PowerOn of",$vm.Name -join ' '

$spec.Description = "Recurring PowerOn of VM prior to Patching"

$spec.Enabled = $false

$spec.Notification = $emailAddr

$schedule = New-Object -TypeName VMware.Vim.MonthlyByWeekdayTaskScheduler

$schedule.Offset = [VMware.Vim.WeekOfMonth]::second

$schedule.Weekday = $poweronTime.DayOfWeek

$schedule.Hour = $poweronTime.Hour

$schedule.Minute = $poweronTime.Minute

$schedule.Interval = 1              # Once every month

$spec.Scheduler = $schedule

$spec.Action = New-Object VMware.Vim.MethodAction

$spec.Action.Name = "PowerOnVM_Task"


# Create the PowerOff Task Spec

$spec2 = New-Object VMware.Vim.ScheduledTaskSpec

$spec2.Name = "Recurring PowerOff of",$vm.Name -join ' '

$spec2.Description = "Recurring PowerOff of VM after Patching Completed"

$spec2.Enabled = $false

$spec2.Notification = $emailAddr

$schedule = New-Object -TypeName VMware.Vim.MonthlyByWeekdayTaskScheduler

$schedule.Offset = [VMware.Vim.WeekOfMonth]::second

$schedule.Weekday = $poweroffTime.DayOfWeek

$schedule.Hour = $poweroffTime.Hour

$schedule.Minute = $poweroffTime.Minute

$schedule.Interval = 1              # Once every month

$spec2.Scheduler = $schedule

$spec2.Action = New-Object VMware.Vim.MethodAction

$spec2.Action.Name = "ShutdownGuest"


# Create the Snapshot Task Spec

$spec3 = New-Object VMware.Vim.ScheduledTaskSpec

$spec3.Name = "Recurring Snanpshot of",$vm.Name -join ' '

$spec3.Description = "Recurring Snapshot of VM after Patching Completed"

$spec3.Enabled = $false

$spec3.Notification = $emailAddr

$schedule = New-Object -TypeName VMware.Vim.MonthlyByWeekdayTaskScheduler

$schedule.Offset = [VMware.Vim.WeekOfMonth]::second

$schedule.Weekday = $snapshotTime.DayOfWeek

$schedule.Hour = $snapshotTime.Hour

$schedule.Minute = $snapshotTime.Minute

$schedule.Interval = 1              # Once every month

$spec3.Scheduler = $schedule

$spec3.Action = New-Object VMware.Vim.MethodAction

$spec3.Action.Name = "CreateSnapshot_Task"

$arg1 = New-Object VMware.Vim.MethodActionArgument

$arg1.Value = 'Snapshot name'

$arg2 = New-Object VMware.Vim.MethodActionArgument

$arg2.Value = 'Snapshot description'

$arg3 = New-Object VMware.Vim.MethodActionArgument

$arg3.Value = $false

$arg4 = New-Object VMware.Vim.MethodActionArgument

$arg4.Value = $false

$spec3.Action.Argument = $arg1,$arg2,$arg3,$arg4


$si = get-view ServiceInstance

$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager


Import-Csv -Path $fileName -UseCulture | %{

    $vm = Get-VM -Name $_.VMName


    # Create the PowerOn Task

    $scheduledTaskManager.CreateScheduledTask($vm.ExtensionData.MoRef, $spec)


    # Create the PowerOff Task

    $scheduledTaskManager.CreateScheduledTask($vm.ExtensionData.MoRef, $spec2)


    # Create the Snapshot Task

    $scheduledTaskManager.CreateScheduledTask($vm.ExtensionData.MoRef, $spec3)

}


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

View solution in original post

7 Replies
LucD
Leadership
Leadership

That should work at first sight.

I would move the creation and setup of the $spec1, $spec and $spec3 outside the Import-Csv loop.

Those specs do not change for a VM.

The comment when you create $spec1 seems to be incorrect.


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

0 Kudos
khalil1974
Enthusiast
Enthusiast

Thank you for replying, i have maid the changes but getting errors. Would  any guidance

updated Script

connect-viserver xxxxx

$Time = Get-Date '21/07/20 20:00'

$fileName = '.\serverlist.csv'

$WeekofMonth = 'Second'

$WeekofDay = 'Sunday'

$emailAddr = 'xxxxx'

$poweroffts = New-TimeSpan -Hours 7 -Minutes 00

(get-date) + $poweroffts

$snapshotts = New-TimeSpan -Hours 7 -Minutes 30

(get-date) + $snapshotts

Import-Csv -Path $fileName -UseCulture | %{

    $vm = Get-VM -Name $_.VMName

    $si = get-view ServiceInstance

    # Create the PowerOn Task

    $scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager

    $spec = New-Object VMware.Vim.ScheduledTaskSpec

    $spec.Name = "Recurring PowerOn of",$vm.Name -join ' '

    $spec.Description = "Recurring PowerOn of VM prior to Patching"

    $spec.Enabled = $true

    $spec.Notification = $emailAddr

    $spec = New-Object -TypeName VMware.Vim.MonthlyByWeekdayTaskScheduler

    $spec.Offset = $WeekofMonth

    $spec.Weekday = $WeekofDay

    $spec.Scheduler.runat = $Time

    $spec.Action = New-Object VMware.Vim.MethodAction

    $spec.Action.Name = "PowerOnVM_Task"

    # Create the PowerOff Task

    $spec2 = New-Object VMware.Vim.ScheduledTaskSpec

    $spec2.Name = "Recurring PowerOff of",$vm.Name -join ' '

    $spec2.Description = "Recurring PowerOff of VM after Patching Completed"

    $spec2.Enabled = $true

    $spec2.Notification = $emailAddr

    $spec2 = New-Object -TypeName VMware.Vim.MonthlyByWeekdayTaskScheduler

    $spec2.Offset = $WeekofMonth

    $spec2.Weekday = $WeekofDay

   $spec2.Scheduler.runat = $poweroffts

    $spec2.Action = New-Object VMware.Vim.MethodAction

    $spec2.Action.Name = "ShutdownGuest"

    # Create the Snapshot Task

    $spec3 = New-Object VMware.Vim.ScheduledTaskSpec

    $spec3.Name = "Recurring Snanpshot of",$vm.Name -join ' '

    $spec3.Description = "Recurring Snapshot of VM after Patching Completed"

    $spec3.Enabled = $true

    $spec3.Notification = $emailAddr

    $spec3 = New-Object -TypeName VMware.Vim.MonthlyByWeekdayTaskScheduler

    $spec3.Offset = $WeekofMonth

    $spec3.Weekday = $WeekofDay

   $spec3.Scheduler.runat = $snapshotts

    $spec3.Action = New-Object VMware.Vim.MethodAction

    $spec3.Action.Name = "CreateSnapshot_Task"

}

$scheduledTaskManager.CreateScheduledTask($vm.ExtensionData.MoRef, $spec)

$scheduledTaskManager.CreateScheduledTask($vm.ExtensionData.MoRef, $spec2)

$scheduledTaskManager.CreateScheduledTask($vm.ExtensionData.MoRef, $spec3)

pastedImage_14.png

above is error on line

$spec.Scheduler.runat = $Time

    $spec.Action = New-Object VMware.Vim.MethodAction

    $spec.Action.Name = "PowerOnVM_Task"

pastedImage_8.png

Next error on following line

   $spec2.Scheduler.runat = $poweroffts

    $spec2.Action = New-Object VMware.Vim.MethodAction

    $spec2.Action.Name = "ShutdownGuest"

pastedImage_24.png

Next error on following line

$spec3.Scheduler.runat = $snapshotts

    $spec3.Action = New-Object VMware.Vim.MethodAction

    $spec3.Action.Name = "CreateSnapshot_Task"

0 Kudos
khalil1974
Enthusiast
Enthusiast

Just an update to make things easier it might best to break down the three action into separate script to make it easier to troubleshoot(and when working i can can merge all together)

Script to Power On

connect-viserver xxxxx

$Time = Get-Date '21/07/20 20:00'

$fileName = '.\serverlist.csv'

$WeekofMonth = 'Second'

$WeekofDay = 'Sunday'

$emailAddr = 'xxxxx'

Import-Csv -Path $fileName -UseCulture | %{

    $vm = Get-VM -Name $_.VMName

    $si = get-view ServiceInstance

    # Create the PowerOn Task

    $scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager

    $spec = New-Object VMware.Vim.ScheduledTaskSpec

    $spec.Name = "Recurring PowerOn of",$vm.Name -join ' '

    $spec.Description = "Recurring PowerOn of VM prior to Patching"

    $spec.Enabled = $true

    $spec.Notification = $emailAddr

    $spec = New-Object -TypeName VMware.Vim.MonthlyByWeekdayTaskScheduler

    $spec.Offset = $WeekofMonth

    $spec.Weekday = $WeekofDay

    $spec.Scheduler.runat = $Time

    $spec.Action = New-Object VMware.Vim.MethodAction

    $spec.Action.Name = "PowerOnVM_Task"  

}

$scheduledTaskManager.CreateScheduledTask($vm.ExtensionData.MoRef, $spec)

Error i get is

pastedImage_0.png

0 Kudos
khalil1974
Enthusiast
Enthusiast

Hi

Updated the script it seems i cannot use the $spec.Scheduler.runat = $Time, here is the updated script that i have added hour and minute. This might be an issue as i need to use the time to work on powering off the vm but i can address that later

connect-viserver xxxx

$fileName = '.\serverlist.csv'

$WeekofMonth = 'Second'

$WeekofDay = 'Sunday'

$emailAddr = 'xxxxx'

Import-Csv -Path $fileName -UseCulture | %{

    $vm = Get-VM -Name $_.VMName

    $si = get-view ServiceInstance

    # Create the PowerOn Task

    $scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager

    $spec = New-Object VMware.Vim.ScheduledTaskSpec

    $spec.Name = "Recurring PowerOn of",$vm.Name -join ' '

    $spec.Description = "Recurring PowerOn of VM prior to Patching"

    $spec.Enabled = $true

    $spec.Notification = $emailAddr

    $spec.scheduler = New-Object VMware.Vim.MonthlyByWeekdayTaskScheduler

    $spec.scheduler.Offset = $WeekofMonth

    $spec.scheduler.Weekday = $WeekofDay

    $spec.scheduler.hour = 20

    $spec.scheduler.minute = 0

    $spec.Action = New-Object VMware.Vim.MethodAction

    $spec.Action.Name = "PowerOnVM_Task" 

    $scheduledTaskManager.CreateScheduledTask($vm.ExtensionData.MoRef, $spec)

}

I am now getting error

pastedImage_1.png

0 Kudos
khalil1974
Enthusiast
Enthusiast

hi, i have moved forward with the script and it working but had to add the

  $spec.scheduler.ActiveTime = $Time

    $spec.scheduler.Interval = 1

    $spec.scheduler.Hour = 20

    $spec.scheduler.Minute = 00

Script so far

connect-viserver xxxx

$Time = Get-Date '22/07/20 20:00'

$fileName = '.\serverlist.csv'

$WeekofMonth = 'Second'

$WeekofDay = 'Sunday'

$emailAddr = 'xxxxx'

Import-Csv -Path $fileName -UseCulture | %{

    $vm = Get-VM -Name $_.VMName

    $si = get-view ServiceInstance

    # Create the PowerOn Task

    $scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager

    $spec = New-Object VMware.Vim.ScheduledTaskSpec

    $spec.Name = "Recurring PowerOn of",$vm.Name -join ' '

    $spec.Description = "Recurring PowerOn of VM prior to Patching"

    $spec.Enabled = $true

    $spec.Notification = $emailAddr

    $spec.scheduler = New-Object VMware.Vim.MonthlyByWeekdayTaskScheduler

    $spec.scheduler.Offset = $WeekofMonth

    $spec.scheduler.Weekday = $WeekofDay

    $spec.scheduler.ActiveTime = $Time

    $spec.scheduler.Interval = 1

    $spec.scheduler.Hour = 20

    $spec.scheduler.Minute = 00

    $spec.Action = New-Object VMware.Vim.MethodAction

    $spec.Action.Name = "PowerOnVM_Task" 

    $scheduledTaskManager.CreateScheduledTask($vm.ExtensionData.MoRef, $spec)

}

It create the schedule poweron

pastedImage_1.png

The question is there a need to have the in the script

$spec.scheduler.ActiveTime = $Time

    $spec.scheduler.Interval = 1

    $spec.scheduler.Hour = 20

    $spec.scheduler.Minute = 00

As the 2nd part of the script is to power off after 7 hours how can i merge the $spec.scheduler.Hour = 20 & $spec.scheduler.Minute = 00

Also as it using UTC, so the time is 1 behind  can i use a .ToUniversalTime() so i dont have to manually remember to add one hour

0 Kudos
LucD
Leadership
Leadership

Try something like this

connect-viserver xxxxx

$fileName = '.\serverlist.csv'

$emailAddr = 'xxxxx'


$now = Get-Date

$lastDayOfPreviousMonth = (Get-Date -Year $now.Year -Month $now.Month -Day 1 -Hour 20 -Minute 0 -Second 0).AddDays(-1)

$poweronTime = $lastDayOfPreviousMonth.AddDays(14 - [int]$lastDayOfPreviousMonth.DayOfWeek).ToUniversalTime()

$poweroffTime = $poweronTime.AddHours(7)

$snapshotTime = $poweroffTime.AddMinutes(30)


# Create the PowerOn Task Spec

$spec = New-Object VMware.Vim.ScheduledTaskSpec

$spec.Name = "Recurring PowerOn of",$vm.Name -join ' '

$spec.Description = "Recurring PowerOn of VM prior to Patching"

$spec.Enabled = $false

$spec.Notification = $emailAddr

$schedule = New-Object -TypeName VMware.Vim.MonthlyByWeekdayTaskScheduler

$schedule.Offset = [VMware.Vim.WeekOfMonth]::second

$schedule.Weekday = $poweronTime.DayOfWeek

$schedule.Hour = $poweronTime.Hour

$schedule.Minute = $poweronTime.Minute

$schedule.Interval = 1              # Once every month

$spec.Scheduler = $schedule

$spec.Action = New-Object VMware.Vim.MethodAction

$spec.Action.Name = "PowerOnVM_Task"


# Create the PowerOff Task Spec

$spec2 = New-Object VMware.Vim.ScheduledTaskSpec

$spec2.Name = "Recurring PowerOff of",$vm.Name -join ' '

$spec2.Description = "Recurring PowerOff of VM after Patching Completed"

$spec2.Enabled = $false

$spec2.Notification = $emailAddr

$schedule = New-Object -TypeName VMware.Vim.MonthlyByWeekdayTaskScheduler

$schedule.Offset = [VMware.Vim.WeekOfMonth]::second

$schedule.Weekday = $poweroffTime.DayOfWeek

$schedule.Hour = $poweroffTime.Hour

$schedule.Minute = $poweroffTime.Minute

$schedule.Interval = 1              # Once every month

$spec2.Scheduler = $schedule

$spec2.Action = New-Object VMware.Vim.MethodAction

$spec2.Action.Name = "ShutdownGuest"


# Create the Snapshot Task Spec

$spec3 = New-Object VMware.Vim.ScheduledTaskSpec

$spec3.Name = "Recurring Snanpshot of",$vm.Name -join ' '

$spec3.Description = "Recurring Snapshot of VM after Patching Completed"

$spec3.Enabled = $false

$spec3.Notification = $emailAddr

$schedule = New-Object -TypeName VMware.Vim.MonthlyByWeekdayTaskScheduler

$schedule.Offset = [VMware.Vim.WeekOfMonth]::second

$schedule.Weekday = $snapshotTime.DayOfWeek

$schedule.Hour = $snapshotTime.Hour

$schedule.Minute = $snapshotTime.Minute

$schedule.Interval = 1              # Once every month

$spec3.Scheduler = $schedule

$spec3.Action = New-Object VMware.Vim.MethodAction

$spec3.Action.Name = "CreateSnapshot_Task"

$arg1 = New-Object VMware.Vim.MethodActionArgument

$arg1.Value = 'Snapshot name'

$arg2 = New-Object VMware.Vim.MethodActionArgument

$arg2.Value = 'Snapshot description'

$arg3 = New-Object VMware.Vim.MethodActionArgument

$arg3.Value = $false

$arg4 = New-Object VMware.Vim.MethodActionArgument

$arg4.Value = $false

$spec3.Action.Argument = $arg1,$arg2,$arg3,$arg4


$si = get-view ServiceInstance

$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager


Import-Csv -Path $fileName -UseCulture | %{

    $vm = Get-VM -Name $_.VMName


    # Create the PowerOn Task

    $scheduledTaskManager.CreateScheduledTask($vm.ExtensionData.MoRef, $spec)


    # Create the PowerOff Task

    $scheduledTaskManager.CreateScheduledTask($vm.ExtensionData.MoRef, $spec2)


    # Create the Snapshot Task

    $scheduledTaskManager.CreateScheduledTask($vm.ExtensionData.MoRef, $spec3)

}


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

View solution in original post

khalil1974
Enthusiast
Enthusiast

Thank you sir for all you help, works perfectly.

0 Kudos