Automation

 View Only
Expand all | Collapse all

Listing all snapshots per vm using get-view

  • 1.  Listing all snapshots per vm using get-view

    Posted May 23, 2018 11:49 AM

    Hi everyone

    I am in the process of developing a script to cleanup after our backup software.

    One of the tasks will be to find snapshots of a certain name and remove them. This is pretty straight forward.

    However, since we have several vCenters linked and since, when a backup job dies, there can be quite a number of of snapshots to work through AND people sometimes don't notice for a few days that something was amiss, I would like to optimise this in a few key aspects:

    When a vm has nothing but backup snaps to be deleted, I would like to tell it to delete them all at once, which should be way easier than doing one at a time.

    To do that, I need to check all snapshots per vm and group the vms and or their snapshots into either the "delete all" category or the "delete individually" category.

    I would like to use views to drill down the data and only work with objects when it is clear what has to be done where. For this I need a way to find all snapshots of a certain vm. I have no trouble finding all vms with snapshots but I have so far only found a way to find the active snapshot and the root snapshot.

    I can of course traverse the snapshot chains in code but I find this rather inelegant...

    So in short: Is there a quick way in get-view to find all snapshots belonging to a vm? Or is there a much easier way to do what I want in the first place?

    Regards,

    Marco



  • 2.  RE: Listing all snapshots per vm using get-view

    Posted May 23, 2018 12:18 PM

    The fastest way to find VMs with snapshot is something like this

    Get-View -ViewType VirtualMachine -Property Name,Snapshot -Filter @{Snapshot = ''} |

    select Name



  • 3.  RE: Listing all snapshots per vm using get-view

    Posted May 23, 2018 12:39 PM

    Hi LucD

    That gives me a list of all the vms that have snapshots.

    I need to have a list of all the snapshots for each of the vms returned.

    Regards,

    Marco



  • 4.  RE: Listing all snapshots per vm using get-view
    Best Answer

    Posted May 23, 2018 01:20 PM

    Ok, that requires a few more lines of code.

    Try like this

    function Get-SnapChild{

       param(

      [VMware.Vim.VirtualMachineSnapshotTree]$Snapshot

       )


       process{

       $snapshot.Name

       if($Snapshot.ChildSnapshotList.Count -gt 0){

       $Snapshot.ChildSnapshotList | %{

       Get-SnapChild -Snapshot $_

      }

      }

      }

    }


    foreach($vm in Get-View -ViewType VirtualMachine -Property Name,Snapshot -Filter @{'Snapshot' = ''}){

       $vm.Snapshot.RootSnapshotList | %{

       Get-SnapChild -Snapshot $_ | Select @{N='VM';E={$vm.name}},@{N='Snapshot';E={$_}}

      }

    }



  • 5.  RE: Listing all snapshots per vm using get-view

    Posted May 23, 2018 01:27 PM

    Thank you, this works. I have no idea why it works but that's more due to my being a novice when it comes to coding and powershell in particular :smileygrin:.

    I'll be staring at this code in total incomprehension some more now.



  • 6.  RE: Listing all snapshots per vm using get-view

    Posted May 23, 2018 01:36 PM

    Lol!


    To minimise the staring, some annotations:

    • To filter the VMs that have a snapshot, the Get-View Filter parameter checks if the Snapshot property is $null or not. This translates to checking for an empty string, which is Get-View/RegEx speak for -not $null
    • On a VM there is the RootSnapShotList which points to the snapshot that make up the roots of all snapshot trees. For each root snapshot, we recursively traverse the snapshot tree via the Get-SnapChild function
    • In the Get-SnapChild function we avoid the issue with a Foreach loop that runs once, even with an empty array, by testing for the number of entries in the ChildSnapshotList array
    • when a child snapshot has children, the function calls itself again. This is the recursive part


  • 7.  RE: Listing all snapshots per vm using get-view

    Posted May 23, 2018 01:39 PM

    I may now understand your code. If you have the time I'd live for you to verify this:

    Am I correct in assuming that the process block is more good coding style than strictly necessary?

    Anyway as far as I can tell, you take the rootsnapshotlist which has an attribute childsnapshotlist (THIS is exactly the piece of linking information I was unable to find so far) and if it has more than 0 entries you traverse through those snapshots by calling your function inside itself.

    The function then returns everything it has found through the first line after process{ and all you have to do is clean the output up a bit through the select statement.

    Am I understanding this somewhat correctly? :smileyhappy:

    And thanks again for the help.



  • 8.  RE: Listing all snapshots per vm using get-view

    Posted May 23, 2018 01:41 PM

    Oh, you were faster than I was :smileyhappy:

    Thanks, I believe I've got it!

    You're an invaluable source of info... but I'm sure I'm not telling you anything new.



  • 9.  RE: Listing all snapshots per vm using get-view

    Posted May 23, 2018 01:44 PM

    Correct, the function could be done without the Process block
    Strictly speaking Begin-Process-End blocks are when objects are passed over the pipeline to the function.

    The function just returns the names of all the snapshots it finds.

    The Select is to combine that info with the VM name.



  • 10.  RE: Listing all snapshots per vm using get-view

    Posted May 20, 2019 03:46 PM
    How would i add Date created, created by and description? 


  • 11.  RE: Listing all snapshots per vm using get-view

    Posted May 20, 2019 04:00 PM

    Like this.
    For the user that created the snapshot, you will have to search the events.

    See for example Re: snapshot who created it

    function Get-SnapChild

    {

       param(

       [VMware.Vim.VirtualMachineSnapshotTree]$Snapshot

       )


       process

       {

       $snapshot | Select Name, Description, CreateTime

       if ($Snapshot.ChildSnapshotList.Count -gt 0)

       {

       $Snapshot.ChildSnapshotList | % {

       Get-SnapChild -Snapshot $_

       }

       }

       }

    }


    foreach ($vm in Get-View -ViewType VirtualMachine -Property Name, Snapshot -Filter @{'Snapshot' = '' })

    {

       $vm.Snapshot.RootSnapshotList | % {

       Get-SnapChild -Snapshot $_ |

      Select @{N = 'VM'; E = { $vm.name } },

       @{N = 'Snapshot'; E = { $_.Name } },

       @{N = 'Description'; E = { $_.Description } },

       @{N = 'CReated'; E = { $_.CreateTime } }

       }

    }



  • 12.  RE: Listing all snapshots per vm using get-view

    Posted May 20, 2019 04:23 PM
    Thank you very much for the quick responce. Much appriciated. 


  • 13.  RE: Listing all snapshots per vm using get-view

    Posted Dec 26, 2019 05:26 PM
    This function works perfectly.  On a related subject, we require all scripts to be signed.  It seems that a function is basically a script in disguise.  Is there a way to require functions to be signed or to restrict their use by the 400 users on our network?


  • 14.  RE: Listing all snapshots per vm using get-view

    Posted Dec 26, 2019 08:04 PM

    Yes, set the execution policy, by a command in for example a profile for All Usersa

    Set-ExecutionPolicy -ExecutionPolicy AllSigned

    Or do it in a GPO.



  • 15.  RE: Listing all snapshots per vm using get-view

    Posted Mar 10, 2021 08:53 AM

    Hello,

    regarding this script, I have 4 points that I request a help:

    1/ How can I catch the creator/author of the snapshot with this script?

    I try this but without success:

    @{N = 'Creator'; E= {

    $event = Get-VIEvent | where {$_ -is [VMware.Vim.TaskEvent] -and $_.Info.descriptionId -eq "VirtualMachine.createSnapshot"} | Select Username

    $event.Info.Reason.userName} }

    2/ I have a difference with the time of 1 hour between the result of this part of the script  {N = 'Created'; E = { $_.CreateTime } }, it's 1 hour less if I compare with the time display in VMware web management. How can I display the correct time in the scipt result?

    3/ How can I display the VMhost where the vm is located in the script result ?

    4/ How can I output in CSV file?

     

    regards



  • 16.  RE: Listing all snapshots per vm using get-view

    Posted Oct 27, 2018 11:21 PM
    Get-View -ViewType VirtualMachine -Filter @{"snapshot" = ""} -Property Name | % {Get-VM -id $_.MoRef | Get-Snapshot}