Solution1. Script to make a snapshoots of listed servers. powershell. store password in separate file (/root/vmware.cred in this case).
script itself
#!/usr/bin/pwsh
# Define log file path
$logFile = "/var/log/vm_snapshot.log"
# Start transcript (captures everything displayed on screen)
Start-Transcript -Path $logFile -Append
# Function to write logs
function Write-Log {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logEntry = "[$timestamp] $message"
# Write to log file and console
Add-Content -Path $logFile -Value $logEntry
Write-Host $logEntry
}
# Read the password from the file
$pass = Get-Content -Path "/root/vmware.cred" -ErrorAction Stop
# Start logging
Write-Log "Starting VM snapshot script execution."
# Connect to vCenter server
try {
$connectionOutput = Connect-VIServer -Server "your_server_here" -User "user_with_snapsoting_rights" -Pass $pass -Force 2>&1
Write-Log "Successfully connected to vCenter."
Write-Log $connectionOutput
} catch {
Write-Log "Failed to connect to vCenter: $_"
Stop-Transcript
exit 1
}
# Read the list of VM names from the servers.inv file
$vmNames = Get-Content -Path "/opt/snaps/servers.inv" # Adjust path
# Get the current date and time in the desired format
$currentDateTime = (Get-Date).ToString("yyyy-MM-dd_HH-mm-ss")
# Loop through each VM and create a snapshot
foreach ($vmName in $vmNames) {
# Check if VM exists
$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue
if ($vm) {
$snapshotName = "autopatch_$currentDateTime" + "_$vmName"
try {
$snapshotOutput = New-Snapshot -VM $vm -Name $snapshotName -Quiesce 2>&1
Write-Log "Snapshot created for VM: $vmName with name: $snapshotName"
Write-Log $snapshotOutput
} catch {
Write-Log "Failed to create snapshot for VM: $vmName. Error: $_"
}
} else {
Write-Log "VM not found: $vmName"
}
}
Write-Log "VM snapshot script execution completed."
# Stop transcript
Stop-Transcript
servers.inv content – just list of servers (how they present at VMWare). like this:
server1
server2
server3
server4
Solution2. Cleanup old snapshoots. Just schedule it to run periodically and it will delete all associated to servers snapshoots. Yep, best time to run is after-hrs, as deleting snapshoot is impacting procedure at VMWare.
script:
#!/usr/bin/pwsh
# Define Variables
$serverList = @("/opt/snaps/servers.inv", "/opt/snaps/servers2.inv", "/opt/snaps/servers3.inv", "/opt/snaps/servers4.inv")
# Change snapshotLimit to above zero value if you want to keep some snapshoots (not recommended, as VMWare well-known for having bad snapshooting process).
$snapshotLimit = 0
$logFile = "/var/log/vm_snapshot_cleaning.log"
$vcServer = "your_server"
$vcUser = "user_with_right_to_delete_snapsoots"
$vcPassword = Get-Content -Path "/root/vmware2.cred" -ErrorAction Stop
# Function to Log Messages
function Write-Log {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"$timestamp - $message" | Out-File -Append -FilePath $logFile
}
# Connect to vCenter
try {
$connection = Connect-VIServer -Server $vcServer -User $vcUser -Password $vcPassword -Force -ErrorAction Stop
Write-Log "Connected to vCenter: $vcServer"
} catch {
Write-Log "Failed to connect to vCenter: $_"
exit 1
}
# Process Each VM
foreach ($file in $serverList) {
if (Test-Path $file) {
Get-Content $file | ForEach-Object {
$vmName = $_.Trim()
if ($vmName -eq "") { return }
# Check if VM exists
$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue
if (-not $vm) {
Write-Log "VM not found: $vmName. Skipping."
return
}
# Get Snapshots
$snapshots = Get-Snapshot -VM $vm -ErrorAction SilentlyContinue | Sort-Object Created
$snapshotCount = $snapshots.Count
Write-Log "VM: $vmName has $snapshotCount snapshots."
# Check Snapshot Limit
if ($snapshotCount -gt $snapshotLimit) {
$oldestSnapshot = $snapshots | Select-Object -First 1
try {
$deleteOutput = Remove-Snapshot -Snapshot $oldestSnapshot -Confirm:$false -RunAsync 2>&1
Write-Log "Deleted oldest snapshot '$($oldestSnapshot.Name)' for VM: $vmName"
Write-Log $deleteOutput
} catch {
Write-Log "Failed to delete snapshot for VM: $vmName. Error: $_"
}
}
}
} else {
Write-Log "File not found: $file. Skipping."
}
}
# Disconnect from vCenter
Disconnect-VIServer -Confirm:$false
Write-Log "Disconnected from vCenter."