VMware Cloud Community
hguthrie
Contributor
Contributor

VM Snapshot Consolidation -- Excluding specific clusters

I am working on a script to delete snapshots older than a specific time period, but I need it to exclude specific clusters (Citrix). Since we have thousands to VMs to check, I'm trying to make this as efficient as possible, and in the past, this means using Get-View.  I've found many people who've done similar things, but none who've done exactly this.

Also, this is a follow-up to an earlier thread that I posted on Disk Consolidation.

I've tried using -SearchRoot, but am not having luck excluding specific clusters.

Get-View -ViewType VirtualMachine -Filter @{"Snapshot"=''} -SearchRoot (Get-Cluster | Where-Object {$_.Name -notlike "Citrix_Cluster"}) -Property 'Name','Parent','Snapshot' | ForEach-Object {Get-VM -Name $_.Name | select Name}

Get-View : Cannot convert 'System.Object[]' to the type 'VMware.Vim.ManagedObjectReference' required by parameter 'SearchRoot'. Specified method is not supported.

At line:1 char:72

+ ... -SearchRoot (Get-Cluster | Where-Object {$_.Name -notlike "Citrix_Cluster"})  ...

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

    + CategoryInfo          : InvalidArgument: (:) [Get-View], ParameterBindingException

    + FullyQualifiedErrorId : CannotConvertArgument,VMware.VimAutomation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIView

Could this be because we actually have two clusters named "Citrix_Cluster" (one in each datacenter)?

PS H:\> Get-Cluster Citrix_Cluster

Name                           HAEnabled  HAFailover DrsEnabled DrsAutomationLevel

                                          Level

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

Citrix_Cluster                         True       1          True       FullyAutomated

Citrix_Cluster                         True       1          True       FullyAutomated

Any suggestions on how to accomplish this? Thanks.

0 Kudos
5 Replies
LucD
Leadership
Leadership

The SearchRoot parameter only accepts one value, and it has to be of the type ManagedObjectReference (MoRef).
You could do this like this.
I used splatting to keep the Get-View parameters legible

Get-Cluster |

Where-Object { $_.Name -notlike "Citrix_Cluster" } |

ForEach-Object -Process {

   $sView = @{

   ViewType = 'VirtualMachine'

   Filter = @{"Snapshot" = '' }

   SearchRoot = $_.ExtensionData.MoRef

   Property = 'Name', 'Parent', 'Snapshot'

   }

   Get-View @sView | Select-Object -Property Name

}


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

0 Kudos
hguthrie
Contributor
Contributor

LucD,

Thanks for the quick response! That helps a lot.

Here's what I have right now:

Get-Cluster |

Where-Object { $_.Name -notlike "Citrix_Cluster" } |

ForEach-Object -Process {

  $sView = @{

    ViewType = 'VirtualMachine'

    Filter = @{"Snapshot" = '' }

    SearchRoot = $_.ExtensionData.MoRef

    Property = 'Name', 'Parent', 'Snapshot'

  }

  Get-View @sView | Select-Object -Property Name,Parent,@{N='SnapshotName';E={$_.Snapshot.RootSnapshotList.Name}},@{N = 'SnapshotDescription'; E = {$_.Snapshot.RootSnapshotList.Description}}

} | ft -a

Several followup questions:

1. How do I get the cluster name for each VM? It seems as though Parent is actually the parent folder object?

2. How would I delete snapshots that are older than N days?

3. I'm also trying to build a report to log what the script found and any actions taken.  Do you have any recommendations on good ways to structure this?

0 Kudos
LucD
Leadership
Leadership

I'm wondering why you decided to go for the Get-View cmdlet in this case.
Is your environment that big?
By using Get-View, retrieving the list of snapshots is more complex compared to just using Get-VM and Get-Snapshot


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

0 Kudos
hguthrie
Contributor
Contributor

I have no attachment to Get-View other than I thought it would be more efficient.

0 Kudos
LucD
Leadership
Leadership

It is  more effificient, but adds complexity.
I normally prefer to do my PoC with straight-forward PowerCLI cmdlets and preferably everything in one long pipeline construct.

Then when performance turns out to be bad, I start looking at where I can optimise by eventually going to Get-View.

In anyy case, the basic report can be done like this

Get-Cluster -PipelineVariable cluster |

Where-Object { $_.Name -notlike "Citrix_Cluster" } |

Get-VM -PipelineVariable vm | Get-Snapshot |

Select @{N = 'Cluster'; E = { $cluster.Name } },

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

Name, Created, Description

When you want to remove snapshots, it would require adding a Where-clause, and using the Remove-Snapshot cmdlet.

$olderThanDays = 10

$tgtDate = (Get-Date).AddDays(- $olderThanDays)


Get-Cluster -PipelineVariable cluster |

Where-Object { $_.Name -notlike "Citrix_Cluster" } |

Get-VM -PipelineVariable vm | Get-Snapshot |

where { $_.Created -lt $tgtDate } |

Remove-Snapshot -Confirm:$false

I'm not too sure what you mean by the 'reporting' part.

Do you want to combine everything in 1 script, and produce for example 1 CSV file with all snapshot, but also which ones were deleted?


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

0 Kudos