PowerCLI

 View Only
Expand all | Collapse all

Scheduled Task for server snaps with email sent

Dilwert

DilwertMay 21, 2020 06:06 PM

  • 1.  Scheduled Task for server snaps with email sent

    Posted May 18, 2020 06:33 PM

    I found this real nice script here and wanted to see if someone can help me modify it to do what I need.

    I want to task schedule from a csv file to snap servers at a certain time and date.

    I want an email sent out to requestor stating servers have been scheduled to snap. Also I want to check to see if there is a previous scheduled snap and deleted it if so.

    I tried different methods but keep running into errors. Any help is much appriciated!

     

    ###############

    # 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)



  • 2.  RE: Scheduled Task for server snaps with email sent

    Posted May 18, 2020 06:55 PM

    What kind of errors are you seeing?

    And on which vSphere version are you trying this?



  • 3.  RE: Scheduled Task for server snaps with email sent

    Posted May 18, 2020 07:00 PM

    I am on VSphere 6 Enterprise.

    Here is one if the errors:

    Exception calling "CreateObjectScheduledTask" with "2" argument(s): "The name 'Snapshot of VMTEST01' already exists."

    At H:\Desktop\Shed Snap May15.ps1:85 char:5

    +     $scheduledTaskManager.CreateObjectScheduledTask($vm.ExtensionData ...

    +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

        + FullyQualifiedErrorId : VimException



  • 4.  RE: Scheduled Task for server snaps with email sent

    Posted May 18, 2020 07:04 PM

    That seems to say there is already a scheduled task with the same name.

    You should remove those before running the script above.



  • 5.  RE: Scheduled Task for server snaps with email sent

    Posted May 18, 2020 07:15 PM

    I tried to input the following commands but they dont seem to work.

    They run but continue to fail for same error.

    $taskName = 'Snapshot of'

        Get-View -Id $scheduledTaskManager.ScheduledTask |

    ForEach-Object -Process {

       if ($_.Info.Name -like $taskName)

       {

       $_.RemoveScheduledTask()

       }



  • 6.  RE: Scheduled Task for server snaps with email sent

    Posted May 18, 2020 07:28 PM

    That will not work with the -like operator like that.

    I prefer to use the -match operator.

    $taskName = 'Snapshot'

    $si = Get-View ServiceInstance

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


    Get-View -Id $scheduledTaskManager.ScheduledTask |

    where{$_.Info.Name -match $taskName} |

    ForEach-Object -Process {

        $_.RemoveScheduledTask()

    }



  • 7.  RE: Scheduled Task for server snaps with email sent

    Posted May 18, 2020 07:35 PM

    The -match actually worked but only one of the two servers listed in the csv.

    It doesn't display an error for troubleshooting.

    Eventually I will add several servers to the csv.

    How can I get it to process all servers listed in the csv ?



  • 8.  RE: Scheduled Task for server snaps with email sent

    Posted May 18, 2020 08:04 PM

    You can combine those 2 scripts and then run this in a loop for all rows in a CSV

    $taskNameTemplate = 'Scheduled snapshot of $($vm.Name)'

    $snapNameTemplate = 'Snapshot of $($vm.Name)'

    $emailAddr = 'lucd@lucd.info'

    $snapTime = Get-Date '06/15/2020 12:30'

    $snapMemory = $false

    $snapQuiesce = $true


    $si = Get-View ServiceInstance

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


    # CSV layout

    # Name

    # vm1

    # vm2


    Import-Csv -Path .\vmnames.csv -UseCulture -PipelineVariable row |

    ForEach-Object -Process {

    # Get the target VM

        $vm = Get-VM -Name $row.Name


    # Remove an existing scheduled task for the VM


        $scheduledTaskManager.RetrieveEntityScheduledTask($vm.ExtensionData.MoRef) |

        ForEach-Object -Process {

            Get-View -Id $_ | where{$_.Info.Name -match 'Snapshot of'} |

            ForEach-Object -Process {

                $_.RemoveScheduledTask()

            }

        }


    # Create a new scheduled task


        $spec = New-Object VMware.Vim.ScheduledTaskSpec

        $spec.Name = $ExecutionContext.InvokeCommand.ExpandString($taskNameTemplate)

        $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 = $ExecutionContext.InvokeCommand.ExpandString($snapNameTemplate)

        $snapDescription = "Take a snapshot of $($vm.Name)"


        @($snapName,$snapDescription,$snapMemory,$snapQuiesce) | %{

            $arg = New-Object VMware.Vim.MethodActionArgument

            $arg.Value = $_

            $spec.Action.Argument += $arg

        }

     

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

    }



  • 9.  RE: Scheduled Task for server snaps with email sent

    Posted May 18, 2020 08:38 PM

    Scheduled snapshots, hopefully not being used as a form of “backup”?



  • 10.  RE: Scheduled Task for server snaps with email sent

    Posted May 18, 2020 08:44 PM

    Only for the VMs that are organised in specific resourcepools :smileygrin:



  • 11.  RE: Scheduled Task for server snaps with email sent

    Posted May 19, 2020 12:25 PM

    Thanks for all your help on this. I ran the script and got the following error message again. I got this error message for the two servers on my csv list.

    Exception calling "CreateObjectScheduledTask" with "2" argument(s): "The name 'Scheduled snapshot of VMTEST01' already exists."

    At line:101 char:5

    +     $scheduledTaskManager.CreateObjectScheduledTask($vm.ExtensionData ...

    +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

        + FullyQualifiedErrorId : VimException



  • 12.  RE: Scheduled Task for server snaps with email sent

    Posted May 19, 2020 12:35 PM

    The RegEx in the Where-clause was incorrect, hence existing scheduled tasks were not removed.
    I updated the code above.



  • 13.  RE: Scheduled Task for server snaps with email sent

    Posted May 19, 2020 12:42 PM

    That works like a charm. It fixed the issue. I appreciate it very much.

    Do you have a tutorial somewhere I can read about how to email the result to the requestor stating snaps have been scheduled.



  • 14.  RE: Scheduled Task for server snaps with email sent

    Posted May 19, 2020 12:48 PM

    The Scheduled Task includes an email notification.

    Or do you mean something else?



  • 15.  RE: Scheduled Task for server snaps with email sent

    Posted May 19, 2020 01:48 PM

    I want to see if I can email out the summary of this script to the requestor stating all servers are now scheduled to be snap at a certain time.

    the body of the email would like something like this.

    SERVER NAME             DESCRIPTION                       SCHEDULED DATE

    ---------------------------------------------------------------------------

    VMTEST01---------- Take a snapshot of VMTEST01---------- 05/25/2020 14:00:00

    VMTEST02---------- Take a snapshot of VMTEST02---------- 05/25/2020 14:00:00

    VMTEST03---------- Take a snapshot of VMTEST03---------- 05/25/2020 14:00:00

    VMTEST04---------- Take a snapshot of VMTEST04---------- 05/25/2020 14:00:00

    VMTEST05---------- Take a snapshot of VMTEST05---------- 05/25/2020 14:00:00

    VMTEST06-----------Take a snapshot of VMTEST06---------- 05/25/2020 14:00:00

    VMTEST07---------- Take a snapshot of VMTEST07---------- 05/25/2020 14:00:00

    VMTEST08---------- Take a snapshot of VMTEST08---------- 05/25/2020 14:00:00

    VMTEST09---------- Take a snapshot of VMTEST09---------- 05/25/2020 14:00:00

    ---------------------------------------------------------------------------



  • 16.  RE: Scheduled Task for server snaps with email sent

    Posted May 19, 2020 02:21 PM

    Sure, try like this

    $taskNameTemplate = 'Scheduled snapshot of $($vm.Name)'

    $snapNameTemplate = 'Snapshot of $($vm.Name)'

    $emailAddr = 'lucd@lucd.info'

    $snapTime = Get-Date '06/15/2020 12:30'

    $snapMemory = $false

    $snapQuiesce = $true


    $report = @()


    $si = Get-View ServiceInstance

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


    # CSV layout

    # Name

    # vm1

    # vm2


    Import-Csv -Path .\vmnames.csv -UseCulture -PipelineVariable row |

    ForEach-Object -Process {

    # Get the target VM

        $vm = Get-VM -Name $row.Name


    # Remove an existing scheduled task for the VM

        $scheduledTaskManager.RetrieveEntityScheduledTask($vm.ExtensionData.MoRef) |

        ForEach-Object -Process {

            Get-View -Id $_ | where{$_.Info.Name -match 'Snapshot of'} |

            ForEach-Object -Process {

                $_.RemoveScheduledTask()

            }

        }


    # Create a new scheduled task

        $spec = New-Object VMware.Vim.ScheduledTaskSpec

        $spec.Name = $ExecutionContext.InvokeCommand.ExpandString($taskNameTemplate)

        $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 = $ExecutionContext.InvokeCommand.ExpandString($snapNameTemplate)

        $snapDescription = "Take a snapshot of $($vm.Name)"


        @($snapName,$snapDescription,$snapMemory,$snapQuiesce) | %{

            $arg = New-Object VMware.Vim.MethodActionArgument

            $arg.Value = $_

            $spec.Action.Argument += $arg

        }

        $report += New-Object -TypeName PSObject -Property ([ordered]@{

            Server = $vm.Name

            Description = "Take a snapshot of $($vm.Name)"

            'Scheduled Date' = $snapTime

        })

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

    }


    $sMail = @{

        From = 'script@my.domain'

        To = 'me@my.domain'

        Subject = 'Scheduled Task Report'

        SmtpServer = 'mail.my.domain'

        BodyAsHtml = $true

        Body = $report | ConvertTo-Html | Out-String

    }

    Send-MailMessage @sMail



  • 17.  RE: Scheduled Task for server snaps with email sent

    Posted May 19, 2020 03:36 PM

    Wow ... works like a charm. That is perfect!

    Thanks for all your help! I really appreciate it !

    This made things alot easier for me.



  • 18.  RE: Scheduled Task for server snaps with email sent

    Posted May 21, 2020 03:35 PM

    Question:  How can I add more email addresses to the following fields:

    $emailAddr = 'lucd@lucd.info'

    To = 'me@my.domain'

    $taskNameTemplate = 'Scheduled snapshot of $($vm.Name)'

    $snapNameTemplate = 'Snapshot of $($vm.Name)'

    $emailAddr = 'lucd@lucd.info'

    $snapTime = Get-Date '06/15/2020 12:30'

    $snapMemory = $false

    $snapQuiesce = $true

    $sMail = @{

        From = 'script@my.domain'

        To = 'me@my.domain'

        Subject = 'Scheduled Task Report'

        SmtpServer = 'mail.my.domain'

        BodyAsHtml = $true

        Body = $report | ConvertTo-Html | Out-String

    }

    Send-MailMessage @sMail



  • 19.  RE: Scheduled Task for server snaps with email sent

    Posted May 21, 2020 05:24 PM

    The To parameter on the Send-MailMessage cmdlet accepts an array.

    So you can just provide multiple addresses separated by a comma.

    To = 'me1@my.domain','me2@my.domain','me3@my.domain'



  • 20.  RE: Scheduled Task for server snaps with email sent

    Posted May 21, 2020 05:32 PM

    thanks for that info.

    Is there a way to add more email addresses to the line listed below?

    $emailAddr = 'lucd@lucd.info'



  • 21.  RE: Scheduled Task for server snaps with email sent

    Posted May 21, 2020 06:03 PM

    Like this



  • 22.  RE: Scheduled Task for server snaps with email sent

    Posted May 21, 2020 06:06 PM

    Thanks you . Much appreciated !!



  • 23.  RE: Scheduled Task for server snaps with email sent

    Posted May 29, 2020 02:00 PM

    How can I get the script to pull the following fields from the cvs so I can keep the script from being modified?

    from csv file:

    server name

    snap description

    scheduled time to run



  • 24.  RE: Scheduled Task for server snaps with email sent

    Posted May 29, 2020 02:37 PM

    Something like this?

    $taskNameTemplate = 'Scheduled snapshot of $($vm.Name)'

    $snapNameTemplate = 'Snapshot of $($vm.Name)'


    $emailAddr = 'lucd@lucd.info'

    $snapMemory = $false

    $snapQuiesce = $true


    $report = @()


    $si = Get-View ServiceInstance

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


    # CSV layout

    # Name,Description,DateTime

    # vm1,'Snapshot of VM1','06/15/2020 12:30'

    # vm2,'Snapshot of VM2','06/16/2020 13:30'


    Import-Csv -Path .\vmnames.csv -UseCulture -PipelineVariable row |

    ForEach-Object -Process {

    # Get the target VM

        $vm = Get-VM -Name $row.Name


    # Remove an existing scheduled task for the VM

        $scheduledTaskManager.RetrieveEntityScheduledTask($vm.ExtensionData.MoRef) |

        ForEach-Object -Process {

            Get-View -Id $_ | where{$_.Info.Name -match 'Snapshot of'} |

            ForEach-Object -Process {

                $_.RemoveScheduledTask()

            }

        }


    # Create a new scheduled task

        $spec = New-Object VMware.Vim.ScheduledTaskSpec

        $spec.Name = $ExecutionContext.InvokeCommand.ExpandString($taskNameTemplate)

        $spec.Description = "Take a snapshot of $($vm.Name)"

        $spec.Enabled = $true

        $spec.Notification = $emailAddr

        $spec.Scheduler = New-Object VMware.Vim.OnceTaskScheduler

        $spec.Scheduler.runat = [DateTime]$row.DateTime

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

        $spec.Action.Name = "CreateSnapshot_Task"

        $snapName = $ExecutionContext.InvokeCommand.ExpandString($snapNameTemplate)

        $snapDescription = $row.Description


        @($snapName,$row.Description,$snapMemory,$snapQuiesce) | %{

            $arg = New-Object VMware.Vim.MethodActionArgument

            $arg.Value = $_

            $spec.Action.Argument += $arg

        }

        $report += New-Object -TypeName PSObject -Property ([ordered]@{

            Server = $vm.Name

            Description = "Take a snapshot of $($vm.Name)"

            'Scheduled Date' = [DateTime]$row.DateTime

        })

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

    }


    $sMail = @{

        From = 'script@my.domain'

        To = 'me@my.domain'

        Subject = 'Scheduled Task Report'

        SmtpServer = 'mail.my.domain'

        BodyAsHtml = $true

        Body = $report | ConvertTo-Html | Out-String

    }

    Send-MailMessage @sMail



  • 25.  RE: Scheduled Task for server snaps with email sent

    Posted May 29, 2020 03:43 PM

    I am getting the following error message:

    Cannot convert value "" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."

    At line:73 char:5

    +     $spec.Scheduler.runat = [DateTime]$row.DateTime

    +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        + CategoryInfo          : InvalidArgument: (:) [], RuntimeException

        + FullyQualifiedErrorId : InvalidCastParseTargetInvocationWithFormatProvider

    Cannot convert value "" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."

    At line:102 char:45

    +         Description = "Take a snapshot of $($vm.Name)"

    +                                             ~~~~~~~~

        + CategoryInfo          : InvalidArgument: (:) [], RuntimeException

        + FullyQualifiedErrorId : InvalidCastParseTargetInvocationWithFormatProvider



  • 26.  RE: Scheduled Task for server snaps with email sent

    Posted May 29, 2020 04:11 PM

    You have to provide the timestamp in the CSV in a format that is accepted by your local settings.

    To test the validity, you can do (insert your datetime string)

    [DateTime]'05/31/2020 19:45'