All About Windows - SS67/project-docs GitHub Wiki
# vSphere-SnapshotReport.ps1
$vCenter = "vcenter.company.local"
Import-Module VMware.PowerCLI -ErrorAction Stop
Set-PowerCLIConfiguration -Scope User -InvalidCertificateAction Ignore -ParticipateInCEIP $false -DisplayDeprecationWarnings $false -Confirm:$false | Out-Null
$user = Read-Host "Username"
$pass = Read-Host "Password" -AsSecureString
$cred = New-Object System.Management.Automation.PSCredential($user, $pass)
Connect-VIServer -Server $vCenter -Credential $cred -ErrorAction Stop | Out-Null
function Get-SnapReport {
param($VMs, $Tenant)
foreach ($vm in $VMs) {
$snaps = Get-Snapshot -VM $vm -ErrorAction SilentlyContinue
$owner = (Get-TagAssignment -Entity $vm -Category "VM Owner" -ErrorAction SilentlyContinue).Tag.Name -join ","
if (-not $owner) { $owner = "N/A" }
$t = if ($Tenant) { $Tenant } else { (Get-ResourcePool -VM $vm -ErrorAction SilentlyContinue).Name -join "," }
[PSCustomObject]@{
Tenant = $t
VMName = $vm.Name
IPAddress = ($vm.Guest.IPAddress -join ",")
Owner = $owner
SnapshotCount = @($snaps).Count
Snapshots = if ($snaps) { ($snaps | ForEach-Object { "$($_.Name) [$($_.Created)] $([math]::Round($_.SizeGB,2))GB" }) -join " | " } else { "None" }
}
}
}
Write-Host "1. Query entire Tenant (Resource Pool)"
Write-Host "2. Query a specific VM"
$choice = Read-Host "Select option (1/2)"
switch ($choice) {
"1" {
$tenant = Read-Host "Enter Tenant / Resource Pool name"
$rp = Get-ResourcePool -Name $tenant -ErrorAction SilentlyContinue
if (-not $rp) {
Write-Host "Resource Pool '$tenant' not found." -ForegroundColor Red
Disconnect-VIServer -Confirm:$false; return
}
$vms = Get-VM -Location $rp
if (-not $vms) {
Write-Host "No VMs found in '$tenant'." -ForegroundColor Yellow
Disconnect-VIServer -Confirm:$false; return
}
$report = Get-SnapReport -VMs $vms -Tenant $rp.Name
}
"2" {
$vmName = Read-Host "Enter VM name"
$vms = Get-VM -Name $vmName -ErrorAction SilentlyContinue
if (-not $vms) {
Write-Host "VM '$vmName' not found." -ForegroundColor Red
Disconnect-VIServer -Confirm:$false; return
}
$report = Get-SnapReport -VMs $vms
}
default {
Write-Host "Invalid option." -ForegroundColor Red
Disconnect-VIServer -Confirm:$false; return
}
}
$report | Format-List
$report | Export-Csv -Path ".\SnapshotReport_$(Get-Date -f yyyyMMdd_HHmm).csv" -NoTypeInformation
Disconnect-VIServer -Server $vCenter -Confirm:$false
version 2
# vSphere-SnapshotReport.ps1
$vCenter = "vcenter.company.local"
Import-Module VMware.PowerCLI -ErrorAction Stop
Set-PowerCLIConfiguration -Scope User -InvalidCertificateAction Ignore -ParticipateInCEIP $false -DisplayDeprecationWarnings $false -Confirm:$false | Out-Null
$user = Read-Host "Username"
$pass = Read-Host "Password" -AsSecureString
$cred = New-Object System.Management.Automation.PSCredential($user, $pass)
Connect-VIServer -Server $vCenter -Credential $cred -ErrorAction Stop | Out-Null
function Get-SnapReport {
param($VMs, $Tenant)
foreach ($vm in $VMs) {
$snaps = @(Get-Snapshot -VM $vm -ErrorAction SilentlyContinue)
$owner = (Get-TagAssignment -Entity $vm -Category "VM Owner" -ErrorAction SilentlyContinue).Tag.Name -join ","
if (-not $owner) { $owner = "N/A" }
$t = if ($Tenant) { $Tenant } else { (Get-ResourcePool -VM $vm -ErrorAction SilentlyContinue).Name -join "," }
[PSCustomObject]@{
Tenant = $t
VMName = $vm.Name
IPAddress = ($vm.Guest.IPAddress -join ",")
Owner = $owner
SnapshotCount = $snaps.Count
OldestSnapshot = if ($snaps) { ($snaps | Sort-Object Created | Select-Object -First 1).Created } else { $null }
NewestSnapshot = if ($snaps) { ($snaps | Sort-Object Created | Select-Object -Last 1).Created } else { $null }
Snapshots = if ($snaps) { ($snaps | ForEach-Object { "$($_.Name) [$($_.Created)] $([math]::Round($_.SizeGB,2))GB" }) -join " | " } else { "None" }
}
}
}
Write-Host "1. Query entire Tenant (Resource Pool)"
Write-Host "2. Query a specific VM"
$choice = Read-Host "Select option (1/2)"
switch ($choice) {
"1" {
$tenant = Read-Host "Enter Tenant / Resource Pool name"
$rp = Get-ResourcePool -Name $tenant -ErrorAction SilentlyContinue
if (-not $rp) {
Write-Host "Resource Pool '$tenant' not found." -ForegroundColor Red
Disconnect-VIServer -Confirm:$false; return
}
$vms = Get-VM -Location $rp
if (-not $vms) {
Write-Host "No VMs found in '$tenant'." -ForegroundColor Yellow
Disconnect-VIServer -Confirm:$false; return
}
$scopeName = $rp.Name
$report = Get-SnapReport -VMs $vms -Tenant $rp.Name
}
"2" {
$vmName = Read-Host "Enter VM name"
$vms = Get-VM -Name $vmName -ErrorAction SilentlyContinue
if (-not $vms) {
Write-Host "VM '$vmName' not found." -ForegroundColor Red
Disconnect-VIServer -Confirm:$false; return
}
$scopeName = $vmName
$report = Get-SnapReport -VMs $vms
}
default {
Write-Host "Invalid option." -ForegroundColor Red
Disconnect-VIServer -Confirm:$false; return
}
}
$report | Format-List
$reportName = "SnapshotReport_$($scopeName)_$(Get-Date -f yyyyMMdd_HHmm).csv"
$reportPath = Join-Path (Get-Location).Path $reportName
$report | Export-Csv -Path $reportPath -NoTypeInformation
$now = Get-Date
$withSnaps = @($report | Where-Object { $_.SnapshotCount -gt 0 })
$olderMonth = @($withSnaps | Where-Object { $_.OldestSnapshot -lt $now.AddMonths(-1) })
$recentWeek = @($withSnaps | Where-Object { $_.NewestSnapshot -ge $now.AddDays(-7) })
$multiSnap = @($withSnaps | Where-Object { $_.SnapshotCount -gt 1 })
Write-Host ""
Write-Host "================ SUMMARY ================"
Write-Host "Scope : $scopeName"
Write-Host "VMs scanned : $(@($report).Count)"
Write-Host "VMs with snapshots : $($withSnaps.Count)"
Write-Host "Total snapshots : $(($report | Measure-Object SnapshotCount -Sum).Sum)"
Write-Host "VMs with snapshots > 1 mo : $($olderMonth.Count)"
Write-Host "VMs with snapshots < 1 wk : $($recentWeek.Count)"
Write-Host "VMs with >1 snapshot : $($multiSnap.Count)"
Write-Host "-----------------------------------------"
if ($olderMonth) { Write-Host "Older than a month : $(($olderMonth.VMName) -join ', ')" -ForegroundColor Red }
if ($multiSnap) { Write-Host "Multiple snapshots : $(($multiSnap.VMName) -join ', ')" -ForegroundColor Yellow }
Write-Host "-----------------------------------------"
Write-Host "Report name : $reportName"
Write-Host "Report location : $reportPath"
Write-Host "========================================="
Disconnect-VIServer -Server $vCenter -Confirm:$false