ITOperations

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

Posted on Updated on

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.csv in C:\Temp\VMSnapshots\.

The CSV should look like this: | Host | Location | | :— | :— | | Server01 | Datacenter1 | | Server02 | Datacenter2 |


Part 1: Creating Snapshots

  1. Open PowerShell ISE with vCenter Administrator credentials.
  2. Load the functions by running the full script (provided below).
  3. Run the following command:
PowerShell
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:

  1. Use the same snapshot_servers.csv list.
  2. Run the following command:
PowerShell
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.

PowerShell
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
}
}
}