Automated VMware snapshot management for Windows patching workflows. Takes snapshots of VMs before patching begins, and cleans them up afterward.
Designed to integrate with WSUS patch groups - give it a group name and it snapshots every VM in that group, skipping physical servers and VMs that already have snapshots.
Creates snapshots for all VMs in a WSUS computer target group.
# Take snapshots for a patch group
.\Invoke-PrePatchSnapshot.ps1 `
-PatchGroup "Servers_Patch_Group_1" `
-VCenterServers "vcenter01.corp.local","vcenter02.corp.local" `
-VCenterCredentialPath ".\vcenter-cred.xml"
# Dry run
.\Invoke-PrePatchSnapshot.ps1 `
-PatchGroup "SQL_Servers" `
-VCenterServers "vcenter01.corp.local" `
-WhatIfWhat it does:
- Connects to one or more vCenter servers
- Queries WSUS for all computers in the specified patch group
- For each computer:
- Skips it if it's not found as a VM (likely physical)
- Skips it if it already has a snapshot
- Creates a named snapshot with a timestamp
- Sends an HTML email report (optional)
Cleans up pre-patch snapshots after the retention period.
# Remove snapshots older than 3 days (default)
.\Remove-ExpiredSnapshots.ps1 `
-VCenterServers "vcenter01.corp.local" `
-VCenterCredentialPath ".\vcenter-cred.xml"
# Custom retention, dry run
.\Remove-ExpiredSnapshots.ps1 `
-VCenterServers "vcenter01.corp.local" `
-RetentionDays 5 `
-WhatIf=== Pre-Patch Snapshot Manager ===
Patch Group : Servers_Patch_Group_1
vCenters : vcenter01.corp.local, vcenter02.corp.local
WSUS Server : WSUS01
Connected to 2 vCenter(s)
Found 24 computers in group
Found 812 powered-on VMs
Processing snapshots...
OK: SQLSERVER01
OK: WEBSERVER01
SKIP (existing snapshot): APPSERVER03
SKIP (not a VM): PHYSICALHOST07.corp.local
FAIL: DVLSERVER02 - Insufficient disk space on datastore
--- Summary ---
Snapshotted : 19
Skipped (exists): 2
Skipped (phys) : 2
Failed : 1
Run the snapshot script before each patch window and the cleanup script a few days after:
# Pre-patch: run 1 hour before patching starts
$preAction = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-NoProfile -File C:\scripts\Invoke-PrePatchSnapshot.ps1 -PatchGroup 'Group_1' -VCenterServers 'vcenter01.corp.local' -VCenterCredentialPath 'C:\scripts\vcenter-cred.xml' -SmtpServer 'smtp.corp.local' -EmailFrom 'ops@corp.local' -EmailTo 'team@corp.local'"
$preTrigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Tuesday -At "8:00PM"
# Post-patch cleanup: run 3 days later
$postAction = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-NoProfile -File C:\scripts\Remove-ExpiredSnapshots.ps1 -VCenterServers 'vcenter01.corp.local' -VCenterCredentialPath 'C:\scripts\vcenter-cred.xml'"
$postTrigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Friday -At "6:00AM"- VMware PowerCLI (
Install-Module VMware.PowerCLI) - WSUS Administration tools (RSAT or installed on WSUS server)
- Network access to vCenter and WSUS
- Credentials with snapshot permissions in vCenter
# Save vCenter credentials to an encrypted file (one-time setup, per-user)
Get-Credential | Export-CliXml ".\vcenter-cred.xml"The credential file is encrypted using Windows DPAPI and can only be decrypted by the same user on the same machine.