Introduction
Infrastructure teams spend hours each week chasing repeatable issues: old snapshots, invalid VMs, disconnected hosts, and unused templates. Many of these problems can be detected and remediated with PowerCLI. By automating checks and responses, you reduce manual effort and improve environment stability.
In this article, you’ll learn how to:
- Detect and delete old snapshots
- Power off and archive idle VMs
- Identify and clean up orphaned or invalid objects
- Remove stale templates or ISOs
- Restart or flag hosts with intermittent disconnection
Step 1: Detect and Remove Snapshots Older Than 14 Days
Get-VM | Get-Snapshot | Where-Object {$_.Created -lt (Get-Date).AddDays(-14)} | Remove-Snapshot -Confirm:$false
Automate via scheduled job and report count:
$oldSnapshots = Get-VM | Get-Snapshot | Where-Object {$_.Created -lt (Get-Date).AddDays(-14)}
"$($oldSnapshots.Count) snapshots removed on $(Get-Date)" | Out-File "C:\Reports\SnapshotCleanup.log" -Append
Step 2: Identify Orphaned and Invalid VMs
Get-VM | Where-Object {$_.PowerState -eq "Unknown" -or $_.ExtensionData.Summary.Runtime.ConnectionState -eq "invalid"}
Auto-remove from inventory (not storage):
Get-VM | Where-Object {$_.PowerState -eq "Unknown"} | Remove-VM -DeletePermanently:$false -Confirm:$false
Step 3: Archive or Power Off Idle VMs
Get-VM | Where-Object {$_.PowerState -eq "PoweredOn" -and $_.ExtensionData.Summary.QuickStats.OverallCpuUsage -lt 50} | Stop-VM -Confirm:$false
Mark VMs with notes for review:
Set-VM -VM (Get-VM -Name "WebDev01") -Notes "Archived due to inactivity on $(Get-Date)"
Step 4: Remove Stale ISO Mounts
Get-VM | Where-Object {$_.ExtensionData.Config.Hardware.Device | Where-Object {
$_.DeviceInfo.Label -like "CD/DVD*" -and $_.Backing.IsoFile
}} | Set-CDDrive -NoMedia -Confirm:$false
Step 5: Detect and Restart Disconnected Hosts
$disconnectedHosts = Get-VMHost | Where-Object {$_.ConnectionState -eq "Disconnected"}
foreach ($host in $disconnectedHosts) {
Restart-VMHost -VMHost $host -Force -Confirm:$false
}
Optional: Email or alert for review before restart.
Diagram: Remediation Workflow with PowerCLI

Bonus: Weekly Self-Healing Script
$logPath = "C:\Reports\WeeklyRemediation_$(Get-Date -Format yyyyMMdd).log"
# Remove stale snapshots
Get-VM | Get-Snapshot | Where-Object {$_.Created -lt (Get-Date).AddDays(-10)} | Remove-Snapshot -Confirm:$false | Out-File $logPath -Append
# Flag invalid VMs
Get-VM | Where-Object {$_.PowerState -eq "Unknown"} | ForEach-Object {
"$($_.Name) is invalid. Review required." | Out-File $logPath -Append
}
# Unmount ISOs
Get-VM | Get-CDDrive | Where-Object {$_.IsoPath} | Set-CDDrive -NoMedia -Confirm:$false | Out-File $logPath -Append
Schedule this script with Task Scheduler or PowerShell Job Scheduler module.
Troubleshooting
| Problem | Solution |
|---|---|
| Snapshot removal fails | Confirm no backup tasks or disk locks present |
| Invalid VM removal error | Use -DeletePermanently:$false to keep files and remove only from inventory |
| CD-ROM state not updated | Ensure Set-CDDrive module is loaded and VMware Tools are up to date |
| Host restart unsafe | Add checks for running workloads or automate host evacuation |