PowerCLI Automation for VMware Snapshot Cleanup and Retention
Snapshots are one of those VMware features that seem harmless right up until they aren't. A quick pre-upgrade snap becomes a week-old delta file, and a 100 GB virtual disk can quietly balloon into something that fills the datastore and grinds performance to a halt. For systems administrators running vSphere across Sydney, Melbourne and Brisbane offices, the problem often shows up first on shared storage in a colo facility, where a single rogue snapshot can starve every other workload on the array.
The fix is rarely a one-off clean-up. Most environments that struggle with snapshot sprawl have grown organically, with multiple admins, contractors and DevOps pipelines creating and forgetting them. Relying on humans to remember which snaps are safe to delete is a losing strategy, especially when you factor in after-hours change windows across Australian Eastern Standard Time.
PowerCLI gives administrators a way to take the guesswork out of the equation. With a handful of cmdlets and a scheduled task, you can enforce retention rules, log every removal, and stop snapshots from quietly aging into a support ticket at 2am AEDT.
| Approach | Speed | Consistency | Audit Trail | Scalability |
|---|---|---|---|---|
| Manual review in vSphere Client | Slow | Variable | None | Poor |
| Email reminders to admins | Medium | Variable | Partial | Low |
| PowerCLI script run manually | Fast | High | Depends on script | Medium |
| PowerCLI script with scheduled task | Fast | High | Built-in logging | High |
Why Snapshots Accumulate in Growing Environments
The classic offenders are backup products, dev/test workflows and that one engineer who creates a snapshot "just in case" before every patch cycle. Multiply that by a team spread across Australian time zones and you have a recipe for stale snapshots that nobody owns.
Storage capacity planning rarely accounts for snap delta growth either. A 1 TB VM with a 50 GB snapshot is still 1.05 TB on disk, but the SAN administrator won't flag that until the array hits 85 percent utilisation and starts throttling. By then, removing the snapshot can take hours and trigger stun times that ripple across the cluster.
PowerCLI sidesteps the human element. Define what counts as "stale" — older than seven days, or attached to a specific folder — and the script enforces the rule consistently every run.
Preparing the PowerCLI Environment
PowerCLI installs as a module from the PowerShell Gallery, so a single one-liner gets you sorted on a management server or a developer's workstation. Pin the module version in your automation pipeline so an upgrade doesn't quietly break a working script, and always connect to vCenter rather than individual ESXi hosts.
Install-Module -Name VMware.PowerCLI -Scope AllUsers
Connect-VIServer -Server vcenter.yourdomain.local.au
Set the execution policy to RemoteSigned and store credentials in the Windows Credential Manager. Hard-coding passwords is the fastest way to fail a security review and earn a stern email from the CISO's offsider.
Discovering Existing Snapshots Across vCenter
Before automating anything destructive, you need to know what you're dealing with. Get-Snapshot is the workhorse cmdlet, and it pipes straight into Select-Object and Export-Csv for reporting. Running the command against a whole vCenter gives you a flat list of every snapshot, the VM it belongs to, when it was created, and how large it has grown.
Get-VM | Get-Snapshot |
Select-Object VM, Name, Created, SizeMB, Description |
Export-Csv -Path "C:\Reports\snapshots_$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation
Run this once a week and email the CSV to the infrastructure team. Most Australian MSPs archive the report in SharePoint so it doubles as evidence during client audits.
Building the Removal Script with Safety Checks
The removal script should never be a blunt Remove-Snapshot loop. Wrap it in safety checks that confirm snapshot age, verify it isn't part of an active backup, and log every action to a file.
Pre-flight checks before any removal:
- Confirm vCenter connectivity and credentials are valid
- Verify free space on target datastores exceeds the expected delta merge
- Reject any snapshot younger than the retention threshold
- Skip VMs tagged
keep-snapshotor sitting in a protected folder
A solid removal block looks like this:
Get-Snapshot -VM $vm |
Where-Object { $_.Created -lt (Get-Date).AddDays(-7) -and $_.Description -notmatch 'keep-snapshot' } |
ForEach-Object {
Write-Output "Removing snapshot $($_.Name) from $($_.VM)"
Remove-Snapshot -Snapshot $_ -Confirm:$false -RunAsync
}
The -RunAsync switch matters here. Without it, the script blocks waiting for consolidation to finish, and on a busy datastore that can stretch into hours. With it, the script fires each removal and moves to the next VM, which is exactly what you want across dozens of hosts.
Post-run actions worth capturing in logs:
- Record VM name, snapshot name, age and size for every removal
- Capture any errors with full stack traces
- Send a summary email to the operations distribution list
Scheduling Jobs for AEST Business Hours
Australian businesses don't all run on the same clock. Sydney and Melbourne are AEST/AEDT, Perth is AWST, and Brisbane ignores daylight saving. If your script runs at midnight UTC while a Brisbane MSP engineer is still online at 10am AEST, consolidation can stomp on their workload.
The simplest pattern is a scheduled task that triggers at a time agreed with the operations team. A common choice is 02:00 AEST, after-hours for Sydney and Melbourne but still within the working day for Perth, so adjust accordingly. For organisations with sites in Adelaide too, the schedule gets even more interesting because South Australia sits halfway between the eastern states and Western Australia.
Using the Task Scheduler, point the action at powershell.exe with the -File argument pointing to your script, and store the credentials in a managed service account. Test the schedule in a non-production environment first; an infinite snapshot loop in production is the sort of incident that ends up in a post-mortem at the next VMUG Melbourne meetup.
Logging, Reporting and Auditing
A script that deletes data without leaving a trail is a liability. Every run should append to a log file that records the VM name, snapshot name, age, size and outcome. Forward those logs to a SIEM if you have one, or at minimum to a centralised file share that gets backed up nightly.
A useful pattern is to have the script email a summary after each run. The body of the email lists removed snapshots, skipped snapshots and any errors, so the operations team can review without opening vCenter. Over time, that summary becomes a record of hygiene that auditors actually like to see.
Hardening the Workflow for Production Use
Once the basic loop is reliable, focus on hardening. Validate input parameters, wrap the script in try/catch blocks, and add a -WhatIf mode for dry runs. Some Australian shops gate the actual deletion behind a feature flag — the script reports what it would remove, a human reviews the report, and only then is deletion enabled.
Finally, document the workflow and put it in the change management system. Automation that nobody understands doesn't survive the next audit or the next round of staff turnover. Treat the script as production code: version it, review it, and revisit it whenever VMware releases a new build of PowerCLI.