PowerCLI Script to Find Idle or Powered Off VMs for Cleanup

Introduction

Virtual machines that are powered off, inactive, or forgotten still consume storage, licenses, and management resources. Identifying these VMs across a large vSphere environment can be challenging. PowerCLI allows you to audit and report idle or unused VMs, making cleanup and cost optimization easier.

In this article, you will learn how to:

  • Detect VMs that are powered off
  • Identify VMs with low or no CPU/memory activity
  • Tag, annotate, or export these VMs for review
  • Build an audit-friendly CSV report
  • Prepare for cleanup actions with safe scripts

Step 1: List Powered-Off VMs

Get-VM | Where-Object {$_.PowerState -eq "PoweredOff"} | Select Name, VMHost, @{N="DaysSincePoweredOff";E={(Get-Date) - $_.ExtensionData.Runtime.BootTime}}

Export to CSV:

Get-VM | Where-Object {$_.PowerState -eq "PoweredOff"} | Export-Csv "C:\Reports\PoweredOffVMs.csv" -NoTypeInformation

Step 2: Detect Low CPU and Memory Usage VMs

Query recent performance stats:

$lowUsageVMs = Get-VM | Where-Object {
$_.PowerState -eq "PoweredOn" -and
$_.ExtensionData.Summary.QuickStats.OverallCpuUsage -lt 100 -and
$_.ExtensionData.Summary.QuickStats.GuestMemoryUsage -lt 100
}

Export for audit:

$lowUsageVMs | Select Name, VMHost, PowerState | Export-Csv "C:\Reports\IdleVMs.csv" -NoTypeInformation

Step 3: Annotate Candidates for Cleanup

$lowUsageVMs | ForEach-Object {
Set-VM -VM $_ -Notes "Marked for review: low CPU/memory usage"
}

Tag if using vSphere tags:

$tag = Get-Tag -Name "ReviewForCleanup"
$lowUsageVMs | New-TagAssignment -Tag $tag

Step 4: Combine Idle and Powered-Off Report

$combined = Get-VM | Where-Object {
$_.PowerState -eq "PoweredOff" -or
($_.ExtensionData.Summary.QuickStats.OverallCpuUsage -lt 50 -and $_.ExtensionData.Summary.QuickStats.GuestMemoryUsage -lt 50)
}

$combined | Select Name, PowerState, VMHost | Export-Csv "C:\Reports\Combined_IdleVMs.csv" -NoTypeInformation

Diagram: Idle VM Audit Process

PowerCLI audit process identifies idle and powered-off virtual machines, combines the results, annotates cleanup candidates, and exports a report for owner review.

Use Case: Quarterly Cleanup Review

  1. Export list of all idle and off VMs
  2. Send to application owners for review
  3. Apply tags to VMs approved for deletion
  4. Schedule removal script with snapshot fallback

Bonus: Schedule Audit with Logging

$log = "C:\Logs\IdleVMScan_$(Get-Date -Format yyyyMMdd).log"
$combined | Export-Csv "C:\Reports\IdleVMs_$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation
"$($combined.Count) idle VMs detected on $(Get-Date)" | Out-File $log

Troubleshooting

ProblemFix
GuestMemoryUsage returns nullEnsure VMware Tools is installed and running
CPU usage shows zero but VM is activeExtend performance query range with Get-Stat
Notes field not savingEnsure Set-VM command is used with correct parameters
No idle VMs foundAdjust thresholds or widen time window for CPU/memory averages

Leave a Reply

Discover more from Digital Thought Disruption

Subscribe now to keep reading and get access to the full archive.

Continue reading