PowerCLI for Inventory Management: VMs, Hosts, Datastores, and Reports

Introduction

A solid automation foundation begins with mastering inventory visibility. Whether you’re building reports, generating audits, or feeding automation workflows, PowerCLI provides deep access into your vSphere inventory with consistent object models.

In this article, we’ll cover:

  • Discovering VMs, hosts, clusters, datastores, and networks
  • Filtering objects with precision
  • Exporting to CSV, HTML, and JSON
  • Grouping and reporting by custom fields
  • Common pitfalls and edge cases

My Personal Repository on GitHub

VMware Repository on GitHub


Listing Core Inventory Objects

Once connected via Connect-VIServer, use Get-* cmdlets to extract the environment’s current state.

# List all VMs
Get-VM

# List all hosts
Get-VMHost

# List all datastores
Get-Datastore

# List all networks and port groups
Get-VirtualPortGroup

For clusters and folders:

Get-Cluster
Get-Folder -Name "Production"

Filtering VMs with Specific Criteria

# Find powered off VMs
Get-VM | Where-Object {$_.PowerState -eq "PoweredOff"}

# Find VMs by name pattern
Get-VM | Where-Object {$_.Name -like "*SQL*"}

# VMs with more than 4 CPUs and over 16GB memory
Get-VM | Where-Object { $_.NumCPU -gt 4 -and $_.MemoryGB -gt 16 }

This enables rapid root-cause analysis or sizing validation.


Exporting VM Inventory Reports

Generate a standardized CSV report for audits or documentation.

$vmReport = Get-VM | Select-Object Name, PowerState, NumCPU, MemoryGB, VMHost, @{N="Datastore";E={($_ | Get-Datastore).Name}}  
$vmReport | Export-Csv -Path "C:\Reports\VM_Inventory.csv" -NoTypeInformation

Alternate formats:

# HTML
$vmReport | ConvertTo-Html | Out-File "C:\Reports\VM_Inventory.html"

# JSON
$vmReport | ConvertTo-Json | Out-File "C:\Reports\VM_Inventory.json"

Grouping and Aggregation

Example: Show VM counts by host.

Get-VM | Group-Object -Property VMHost | Select Name, Count

Sample Output:

Name                Count
---- -----
esxi01.lab.local 42
esxi02.lab.local 39

Use Measure-Object to check resource allocation:

Get-VM | Measure-Object -Property MemoryGB -Sum

Advanced Filtering: Tags, Guest OS, Custom Attributes

# VMs running Windows
Get-VM | Where-Object {$_.Guest.OSFullName -like "*Windows*"}

# VMs tagged with 'Production'
Get-TagAssignment | Where-Object {$_.Tag.Name -eq "Production"} | Select Entity

# With a specific annotation
Get-VM | Where-Object {$_.Notes -like "*database*"}

Host and Cluster Inventory Reports

Extract host-level configuration and export:

Get-VMHost | Select-Object Name, ConnectionState, Manufacturer, Model, ProcessorType, MemoryTotalGB, Version | Export-Csv -Path "C:\Reports\Host_Inventory.csv" -NoTypeInformation

Grouped by cluster:

Get-VMHost | Group-Object -Property Parent | Select Name, Count

Diagram: Inventory Object Relationships


Common Mistakes and Fixes

IssueFix
Get-VM returns nothingEnsure connection to vCenter, not individual ESXi host
CSV missing datastore or hostUse calculated properties (@{N=;E=} blocks)
Output includes system VMs or templatesFilter with Where-Object { -not $_.ExtensionData.Config.Template }
Script fails on large environmentsUse -PipelineVariable and streaming with Export-Csv -Append

Sample Use Case: Datastore Utilization Summary

Get-Datastore | Select Name, CapacityGB, FreeSpaceGB, @{N="UsedPercent";E={[math]::Round((($_.CapacityGB - $_.FreeSpaceGB)/$_.CapacityGB)*100,2)}} | Export-Csv "C:\Reports\Datastore_Utilization.csv" -NoTypeInformation

What’s Next

In the next article, we’ll explore bulk VM operations, including:

  • Powering on/off large groups of VMs
  • Automating snapshots and removals
  • Batch tagging, notes, and updates
  • Graceful shutdown/startup sequences

Leave a Reply

Discover more from Digital Thought Disruption

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

Continue reading