VMware Cloud Community
Treikayan
Contributor
Contributor

PowerCLI Help: Code to Remove Snapshot Task with Remove-Snapshot cmdlet

Hello,

I am trying to write a script which will remove a snapshot task once the remove-snapshot has run and completed.  I am having some problem creating the commands.  Please can someone assist.  I have a script which creates the snapshot tasks but can't figure out how to make one to remove the snapshot task.  Please can someone help me fix this?  Thank you for your assistance.

Here is an example of my code below.  The first one doesn't remove the task.  The second works and creates the task.

# Remove Snapshots after Windows Patching

Param(

    [Parameter(Mandatory=$true)]

    [string]$name, # Description of the snapshot "Windows Patching Staging 1" or "Windows Patching Staging 2"

    [string]$path  # Path to the host file used for creating the snapshots prior to patching

);

$vms = (Get-Content $path).Split("`n");

$inLine = @();

foreach ($vm in $vms) {

    $inLine += Get-VM $vm | Get-Snapshot | fl

    if (Get-VM $vm | Get-Snapshot | Where-Object {$_.Description -eq $name} | select VM,Description,Created) {

        Get-Snapshot -VM $vm -Name $name | Remove-Snapshot -Confirm:$false

        $inLine += Write-Host $vm ": Removed snapshot"}

        else {

        (Get-VM $vm | Get-Snapshot | Where-Object {$_.Description -eq $name} | select VM,Description,Created)

        $inLine += Write-Host $vm ": Could not locate snapshot with that description"}

    };

foreach ($vm in $vms) {

     if ((Get-View ScheduledTaskManager).ScheduledTask | %{ (Get-View $_).Info } | Where-Object {$_.Name -match ".*$vm.*"}) {

        $inLine += (Get-View ScheduledTaskManager).ScheduledTask | %{ (Get-View $_).Info } | Where-Object {$_.Name -match ".*$vm.*"}

        ((Get-View ScheduledTaskManager).ScheduledTask | %{ (Get-View $_).Info } | Where-Object {$_.Name -match ".*$vm.*"}).RemoveScheduledTask

        }

        else {

        $inLine += Write-Host $vm ": Could not locate snapshot task with that description"}

    };

$inline;

# Create Scheduled Task for Snapshots

# Windows Patching

param (

    [Parameter(Mandatory=$true)]

    [string]$path, # Example: "H:\Scripts\hosts.csv"

    [string]$date, # Example: "11/11/2016 05:00"

    [string]$name  # Example: "Windows Patching Staging 1 or 2"

);

$snapTime = (Get-Date $date); # [datetime]$date;

$snapName = $name;

$snapDescription = $name;

$snapMemory = $false;

$snapQuiesce = $true;

$emailAddr = 'name@somewhere.com';

$vms = (Get-Content $path).Split("`n");

$interval = "30";

foreach ($vm in $vms) {

    $vm = Get-VM -Name $vm

    $instance = get-view ServiceInstance

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

    # Task Specifics

    $spec = New-Object VMware.Vim.ScheduledTaskSpec

    $spec.Name = "PowerCLI: Snapshot of " + $($vm.Name)

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

    $spec.Enabled = $true

    $spec.Notification = $emailAddr

    # Schedule Task Once

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

    $spec.Scheduler.runat = $snapTime

    # Create Snapshot Task

    $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.CreateScheduledTask($vm.ExtensionData.MoRef, $spec) #

    Write-Host "--------";

    Write-Host "Run At: " $snapTime

    Write-Host "VM Name: " $vm

    Write-Host "Snapshot Name: " $name

    Write-Host "--------";

    $snapTime = $snapTime.AddMinutes($interval)

};

Tags (2)
0 Kudos
10 Replies
LucD
Leadership
Leadership

Try changing this line

if (Get-VM $vm | Get-Snapshot | Where-Object {$_.Description -eq $name} | select VM,Description,Created) {

into this

if (Get-VM $vm | Get-Snapshot | Where-Object {$_.Description -eq $name}) { 

Or is the problem somewhere else?


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

0 Kudos
Treikayan
Contributor
Contributor

Hello LucD,

Thank you for responding.  I'm having a problem Removing the Scheduled Task from vCenter after the I remove the snapshot.  I can't get it to work.

0 Kudos
LucD
Leadership
Leadership

You can call RemoveScheduledTask method the to remove a Scheduled Task.

Sample code

$taskName = 'Windows Patching Staging 1'

$si = Get-View ServiceInstance

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

$t = Get-View -Id $scheduledTaskManager.ScheduledTask | where{$_.Info.Name -eq $taskName}

$t.RemoveScheduledTask()


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

0 Kudos
Treikayan
Contributor
Contributor

Hi LucD,

Does this remove all Scheduled Tasks with the name "Windows Patching Staging 1" in vCenter or do I need to add this to a for/each vm loop?  Thank you for your help.  I will try this out.

Thank you,

Eric.

0 Kudos
LucD
Leadership
Leadership

If there are more scheduled tasks with the same name, yes.

It would perhaps be better to add extra info in the scheduled task name, like for example the name of the VM.

That would make it easier to determine the exact scheduled task to remove.


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

0 Kudos
Nordvs
Contributor
Contributor

Sorry for asking in the old topic, but I have a kind of related question. How do you specify vms for this script? For example I haver 3 vms that I got from a csv file.

$vms = (Get-Content D:\tmp\vms.csv).Split("`n")

Now I want to remove scheduled tasks only for these 3 VMs 

Thanks

0 Kudos
LucD
Leadership
Leadership

You could do something like this

$vmObj = Get-VM -Name $vms

$si = Get-View ServiceInstance

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

Get-View -Id $scheduledTaskManager.ScheduledTask |

where{$vmObj.ExtensionData.MoRef -contains $_.Info.Entity} | %{

    $_.RemoveScheduledTask()

}


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

0 Kudos
Nordvs
Contributor
Contributor

Thank you LucD for the quick response. Let me explain what I am trying to do. I have list of all the tasks with VM names:

Function Get-VIScheduledTasks {

  (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}}

    }

Now I want to "filter" the list only with VMs in the csv file and then remove tasks that have NextRuntime=$null

(Get-View ScheduledTaskManager).ScheduledTask | %{(Get-View $_).Info} | Select Name,NextRunTime |    ?{$_.NextRunTime -eq $null}

Is there a way to do that?

Thanks!

0 Kudos
LucD
Leadership
Leadership

Try like this.
It depends how the VM names are stored in the CSV file.

I assume there is a column Name

$vms = Get-VM -Name (Import-Csv -Path .\vmnames.csv -UseCulture).Name

Get-View -Id (Get-View ScheduledTaskManager).ScheduledTask |

where{$vms.ExtensionData.MoRef -contains $_.Info.Entity -and -not $_.Info.NextRuntime} | %{

    $_.RemoveScheduledTask()

}


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

0 Kudos
Nordvs
Contributor
Contributor

Thank you sir, that is awesome! I think I can use the Name filed in the CSV.

0 Kudos