12 Replies Latest reply on Jul 2, 2020 1:37 AM by vcertify

    Deleting snapshots with wait

    JLogan2016 Enthusiast

      I have a script that deletes snapshots throughout several vCenter environments. The number of snapshots has grown to ~500 every week due to the size of the overall environment. I am beginning by gathering a list of any snapshots older than x days, excluding some that have special wording in the description. This gives me a csv that has the VM name, the vCenter, the snapshot name, creation date, description, server owner (VM tag), and SizeMB. I then sort by date so in the case of a VM with multiple snapshots (rare) I am deleting newest first, and then doing something like this:

       

      Get-VM -Name $VM.Name |
          Get-Snapshot -Name $VM.Snap |
              Remove-Snapshot -Confirm: $false
      

       

      The script works, but I find that there is no method for waiting until one is done before moving on to the next. So what happens, if I have 500 servers that have snapshots, is they all attempt to kick off one after another. I could do a simple sleep, but with the differing size of snapshots that is a crap shoot. I have also tried something like this:

       

      $t = Get-VM -Name $VM.Name | Get-Snapshot -Name $VM.Snap | Remove-Snapshot -Confirm: $false
      
      
      While('Running','Queued' -contains $t.State) {
          Start-Sleep 5
          $t = Get-Task -Id $t.Id
      }
      

       

      But it doesn't seem to work, it still runs them one after another. The net result is I usually have to make a second pass to clean up any snapshots I missed. I am just curious if there is a better way.

        • 1. Re: Deleting snapshots with wait
          a.p. Guru
          User ModeratorsCommunity WarriorsvExpert

          Please see whether Wait-Task cmdlet is what you are looking for.

           

          André

          • 2. Re: Deleting snapshots with wait
            LucD Guru
            vExpertCommunity WarriorsUser Moderators

            You can run the removal of the snapshots in the background with the RunAsync switch.
            Then with Get-Task check how many there are running.

            If that number is higher than your set maximum, just wait till one or more of the background jobs finishes.

             

            $maxJobs = 5

            Get-VM | Get-Snapshot |

               ForEach-Object -Process {

               Remove-Snapshot -Snapshot $_ -Confirm:$false -RunAsync

               $current = Get-Task | where {$_.Name -eq 'RemoveSnapshot_Task' -and 'Running','Queued' -contains $_.State}

               while ($current.count -gt $maxJobs) {

                  sleep 5

                  $current = Get-Task | where {$_.Name -eq 'RemoveSnapshot_Task' -and 'Running','Queued' -contains $_.State}

               }

            }

            Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
            1 person found this helpful
            • 3. Re: Deleting snapshots with wait
              JLogan2016 Enthusiast

              This worked perfectly, thanks.

              • 4. Re: Deleting snapshots with wait
                scorpion20 Lurker

                Hi LucD,

                 

                Thanks for the resolution to the query. I have a bit different query though. I want to delete all snapshot's 7 days older from a particular VC (to which I am connected to) but want to leave snapshot of one or few VM untouched as those are still required. How can we achieve this?

                 

                As of now I am using the below command to delete all the snapshot from the VC.

                 

                Get-VM | Get-Snapshot | Where {$_.Created -lt (Get-Date).AddDays(-7)} | Remove-Snapshot -RunAsync -confirm:$false | Export-Csv C:\tesmp\snapshot.log

                • 5. Re: Deleting snapshots with wait
                  LucD Guru
                  Community WarriorsUser ModeratorsvExpert

                  How do you select the VMs for which the snapshots do not need to be deleted?

                  Is that based on the name or something else?

                  Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
                  • 6. Re: Deleting snapshots with wait
                    scorpion20 Lurker

                    Hi LucD,

                     

                    Yes, need to select the VM with it's name that needs to be excluded from the snapshot deletion.

                    If we select it with the description of the Snapshot in case it's mentioned there "Do not delete the snapshot" that could help us giving the name of the VM for exclusion and will exclude all VM's where the description says "Do not delete the snapshot".

                     

                    Would be good to have command for both the possibilities though :-). Thank you.

                    • 7. Re: Deleting snapshots with wait
                      LucD Guru
                      Community WarriorsUser ModeratorsvExpert

                      You can include multiple Where-clauses in the pipeline.

                       

                      Get-VM | where{$_.Name -notlike "Exclude*" } |

                      Get-Snapshot | where {$_.Description -notlike "*Do not delete*"} |

                      ForEach-Object -Process {

                         Remove-Snapshot -Snapshot $_ -Confirm:$false -RunAsync

                         $current = Get-Task | where {$_.Name -eq 'RemoveSnapshot_Task' -and 'Running','Queued' -contains $_.State}

                         while ($current.count -gt $maxJobs) {

                            sleep 5

                            $current = Get-Task | where {$_.Name -eq 'RemoveSnapshot_Task' -and 'Running','Queued' -contains $_.State}

                         }

                      }

                      Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
                      • 8. Re: Deleting snapshots with wait
                        scorpion20 Lurker

                        Thank you very much LucD. I will try to run this command and see the result.

                        Last query - Should there be a file from which this command can pick the name of the VM from that needs to be excluded from snapshot removal process?

                        • 9. Re: Deleting snapshots with wait
                          LucD Guru
                          User ModeratorsvExpertCommunity Warriors

                          The script above doesn't use an external file, but you can use for example an Import-Csv to pick up the names of the VMs to look at.

                          Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
                          • 10. Re: Deleting snapshots with wait
                            vcertify Lurker

                            Hi LucD,

                             

                            The above script works very well but when I given the VM list from the file, the get-task is getting all the tasks other than we have initiated for remove. And I need to get more details to be capture as when the remove snapshot task started time for a VM and the completion time with who initiated the task.

                            Please help the above.

                            • 11. Re: Deleting snapshots with wait
                              LucD Guru
                              Community WarriorsUser ModeratorsvExpert

                              Do you mean you are not only getting the Remove-Snapshot tasks, but also other tasks that are running or queued in the vCenter?

                              If yes, you can use the Id parameter on the Get-Task cmdlet to specifically specify which tasks you want to retrieve.

                              Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
                              • 12. Re: Deleting snapshots with wait
                                vcertify Lurker

                                Yes. I tried to use the id parameter. Facing an issue with retrieving output. Could you please share a small example with id and display output as vmname, start time, finish time and initiated by details from the task once the state is succes.