How to Retrieve a Comprehensive List of All VM Snapshots Across vCenter-Managed ESXi Hosts Using PowerCLI


1 views

When managing large VMware environments with multiple ESXi hosts through vCenter, administrators often need to audit existing snapshots across all VMs. Snapshots left running for extended periods can consume significant storage and impact performance. Having a centralized way to list all snapshots is crucial for proper virtual infrastructure maintenance.

VMware PowerCLI provides the most comprehensive solution for this task. Here's a robust script that connects to vCenter and retrieves snapshot information from all managed hosts:

# Connect to vCenter
Connect-VIServer -Server your-vcenter.example.com -User admin@vsphere.local -Password "securepassword"

# Get all VMs with snapshots
$snapshotReport = Get-VM | Get-Snapshot | Select-Object VM, Name, Description, 
    @{Name="SizeGB";Expression={[math]::Round($_.SizeGB,2)}},
    Created,
    @{Name="AgeDays";Expression={(New-TimeSpan -Start $_.Created -End (Get-Date)).Days}},
    PowerState,
    @{Name="ParentVM";Expression={$_.VM.Name}}

# Output to CSV
$snapshotReport | Export-Csv -Path "C:\temp\vCenter_Snapshots_Report.csv" -NoTypeInformation

# Disconnect when done
Disconnect-VIServer -Confirm:$false

For more detailed reporting, we can expand the script to include datastore information and sort by snapshot size:

# Extended snapshot report with datastore info
$snapshotDetails = @()
$allVMs = Get-VM

foreach ($vm in $allVMs) {
    $snaps = $vm | Get-Snapshot
    foreach ($snap in $snaps) {
        $snapshotDetails += [PSCustomObject]@{
            VMName = $vm.Name
            SnapshotName = $snap.Name
            Created = $snap.Created
            AgeDays = (New-TimeSpan -Start $snap.Created -End (Get-Date)).Days
            SizeGB = [math]::Round($snap.SizeGB, 2)
            Description = $snap.Description
            PowerState = $vm.PowerState
            Host = $vm.VMHost.Name
            Datastore = ($vm | Get-Datastore).Name -join ","
            Folder = $vm.Folder.Name
        }
    }
}

# Export sorted by largest snapshots
$snapshotDetails | Sort-Object SizeGB -Descending | 
    Export-Csv -Path "C:\temp\vCenter_Snapshots_Detailed.csv" -NoTypeInformation

For environments with thousands of VMs, we should optimize performance by:

  • Using parallel processing where possible
  • Limiting property collection to only what we need
  • Implementing error handling for disconnected VMs

For those preferring REST API approaches, vCenter's API (available since 6.5) offers snapshot enumeration:

GET https://{vcenter}/api/vcenter/vm/{vm}/snapshot

This returns JSON data that can be processed with standard tools like Python or PowerShell.

Consider setting up a scheduled task to run the snapshot report weekly and email results to administrators. This helps maintain visibility into snapshot usage patterns over time.


When administering large VMware environments through vCenter Server, one common pain point is obtaining comprehensive visibility into VM snapshots across multiple ESXi hosts. Left unchecked, snapshots can consume significant storage resources and impact performance.

VMware's PowerCLI module provides the most efficient way to query snapshot information across your entire vCenter inventory. Here's how to get started:

# First, install PowerCLI if you haven't already
Install-Module VMware.PowerCLI -Scope CurrentUser

# Connect to your vCenter server
Connect-VIServer -Server vcenter.example.com -User admin@vsphere.local -Password "YourSecurePassword"

The core cmdlets we'll use are:

# Basic snapshot listing
Get-VM | Get-Snapshot | Select-Object VM, Name, Created, SizeGB

# More detailed output including parent snapshot
Get-VM | Get-Snapshot | Select-Object VM, Name, Created, 
    @{N="Parent";E={$_.ParentSnapshot.Name}},
    @{N="SizeGB";E={[math]::Round($_.SizeGB,2)}}

For production environments, you'll want to filter results and generate actionable reports:

# Find snapshots older than 7 days
$reportDate = (Get-Date).AddDays(-7)
Get-VM | Get-Snapshot | Where-Object {$_.Created -lt $reportDate} |
    Select-Object VM, Name, Created, 
    @{N="AgeInDays";E={(New-TimeSpan $_.Created (Get-Date)).Days}}

# Export to CSV for analysis
Get-VM | Get-Snapshot | Export-Csv -Path "C:\temp\vcenter_snapshots.csv" -NoTypeInformation

For environments with thousands of VMs, consider these performance optimizations:

# Process VMs in parallel (PowerShell 7+)
$vmList = Get-VM
$snapshotReport = $vmList | ForEach-Object -Parallel {
    $snaps = $_ | Get-Snapshot
    foreach ($snap in $snaps) {
        [PSCustomObject]@{
            VM = $_.Name
            Snapshot = $snap.Name
            Created = $snap.Created
            SizeGB = [math]::Round($snap.SizeGB,2)
        }
    }
} -ThrottleLimit 10

$snapshotReport | Export-Csv -Path "C:\temp\parallel_snapshots.csv"

If you're working in a Linux environment or prefer REST APIs:

# Using vSphere Automation SDK for Python
from pyVmomi import vim
from pyVim.connect import SmartConnectNoSSL, Disconnect

si = SmartConnectNoSSL(host="vcenter.example.com", user="admin@vsphere.local", pwd="YourSecurePassword")
content = si.RetrieveContent()

for vm in content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True).view:
    if vm.snapshot:
        for snapshot in vm.snapshot.rootSnapshotList:
            print(f"VM: {vm.name}, Snapshot: {snapshot.name}, Created: {snapshot.createTime}")