ITOperations
Automation: Bulk Create and Delete VM Snapshots Across Linked vCenters | Lazy Admin Blog

In a large environment, taking snapshots before a major patch or application update is a standard safety net. But if you have servers spread across multiple vCenters in Linked Mode (e.g., Datacenter1 and Datacenter2), clicking through the vSphere Client is a waste of time.
Today, I’m sharing a “Lazy Admin” script that allows you to bulk create, check, and remove snapshots using a simple CSV list.
Prerequisites
- VMware PowerCLI: Ensure the PowerCLI module is installed on the machine running the script.
- CSV Setup: Create a file named
snapshot_servers.csvinC:\Temp\VMSnapshots\.
The CSV should look like this: | Host | Location | | :— | :— | | Server01 | Datacenter1 | | Server02 | Datacenter2 |
Part 1: Creating Snapshots
- Open PowerShell ISE with vCenter Administrator credentials.
- Load the functions by running the full script (provided below).
- Run the following command:
Create-VMSnapshots -SS_CSV "C:\Temp\VMSnapshots\snapshot_servers.csv" -SS_Name "Pre-Patching" -SS_Description "Requested by App Team"
The script will iterate through your CSV and create snapshots sequentially. You can monitor the progress in the vSphere Tasks console.
Part 2: Deleting Snapshots
Once your changes are verified, don’t let those snapshots linger and bloat your datastores! To remove them:
- Use the same
snapshot_servers.csvlist. - Run the following command:
Remove-VMSnapshots -SS_CSV "C:\Temp\VMSnapshots\snapshot_servers.csv"
Note: This is a sequential script; it will wait for one snapshot removal to finish before moving to the next to avoid pinning your storage I/O.
The Script: VMSnapshots.ps1
Save this code to C:\Temp\VMSnapshots\VMSnapshots.ps1.
function Create-VMSnapshots { param ( [string]$SS_CSV = $(Read-Host "Enter path to CSV"), [string]$SS_Name = $(Read-Host "Enter name for snapshots"), [string]$SS_Description = $(Read-Host "Enter description for snapshots") ) # Import VMware PowerCLI Module If ( !(Get-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) ) { import-module VMware.VimAutomation.Core } $Servers = Import-CSV $SS_CSV $WLM_vCenter = Connect-VIServer vCenter1 -WarningAction SilentlyContinue $EDN_vCenter = Connect-VIServer vCenter2 -WarningAction SilentlyContinue ForEach($Server in $Servers){ If($Server.Location -eq 'Datacenter1'){ New-Snapshot -VM $Server.Host -Name $SS_Name -Description $SS_Description -Quiesce -Server $WLM_vCenter -WarningAction SilentlyContinue } ElseIf($Server.Location -eq 'Datacenter2'){ New-Snapshot -VM $Server.Host -Name $SS_Name -Description $SS_Description -Quiesce -Server $EDN_vCenter -WarningAction SilentlyContinue } } }function Check-VMSnapshots { param ( [string]$SS_CSV = $(Read-Host "Enter path to CSV"), [string]$SS_Name = $(Read-Host "Enter snapshot name") ) # Import VMware PowerCLI Module If ( !(Get-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) ) { import-module VMware.VimAutomation.Core } $Servers = Import-CSV $SS_CSV $WLM_vCenter = Connect-VIServer vCenter1 -WarningAction SilentlyContinue $EDN_vCenter = Connect-VIServer vCenter2 -WarningAction SilentlyContinue ForEach($Server in $Servers){ If($Server.Location -eq 'Datacenter1'){ Get-Snapshot -VM $Server.Host -Name $SS_Name -Server $WLM_vCenter | Select VM, Name, @{ n="SpaceUsedGB"; e={[math]::round( $_.SizeGB )}} -WarningAction SilentlyContinue } ElseIf($Server.Location -eq 'Datacenter2'){ Get-Snapshot -VM $Server.Host -Name $SS_Name -Server $EDN_vCenter | Select VM, Name, @{ n="SpaceUsedGB"; e={[math]::round( $_.SizeGB )}} -WarningAction SilentlyContinue } } } function Remove-VMSnapshots { param ( [string]$SS_CSV = $(Read-Host "Enter path to CSV") ) # Import VMware PowerCLI Module If ( !(Get-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) ) { import-module VMware.VimAutomation.Core } $Servers = Import-CSV $SS_CSV $WLM_vCenter = Connect-VIServer vCenter1 -WarningAction SilentlyContinue $EDN_vCenter = Connect-VIServer vCenter2 -WarningAction SilentlyContinue ForEach($Server in $Servers){ If($Server.Location -eq 'Datacenter1'){ Get-Snapshot $Server.Host -Server $WLM_vCenter | Remove-Snapshot -Confirm:$false -WarningAction SilentlyContinue } ElseIf($Server.Location -eq 'Datacenter2'){ Get-Snapshot $Server.Host -Server $EDN_vCenter | Remove-Snapshot -Confirm:$false -WarningAction SilentlyContinue } } }