A colleague was asking around for a PowerShell script that would fetch some inventory data for VMs on a Hyper-V cluster the other day. Not knowing too much about Hyper-V and having only ever briefly looked at what was out there in terms of PowerShell cmdlets for managing Hyper-V, I decided to dive in tonight after I got home.
Here is a function that will fetch Inventory data for all VMs in a specified Failover Cluster. This is what it fetches:
- VM Name
- VM CPU Count
- VM CPU Socket Count
- VM Memory configuration
- VM State (Up or Down)
- Cluster Name the VM resides on
- Hyper-V Host name the VM resides on
- Network Virtual Switch Name
- NIC Mac Address
- Total VHD file size in MB
- Total VHD Count
Being a function, you can pipe in the name of the cluster you want, for example Get-Cluster | Get-HyperVInventory. Or you could do Get-HyperVInventory -ClusterName “ExampleClusterName”. You could also send it to an HTML Report by piping it to “ConvertTo-HTML | Out-File example.html”
Download here, or copy it out from the script block below:
[download id=”15″]
# Requires: Imported HyperV PowerShell module (http://pshyperv.codeplex.com/releases/view/62842)
# Requires: Import-Module FailoverClusters
# Requires: Running PowerShell as Administrator in order to properly import the above modules
function Get-HyperVInventory {
<#
.SYNOPSIS
Fetches Hyper-V VM Inventory from a specified Hyper-V Failover cluster
.DESCRIPTION
Fetches Hyper-V VM Inventory from a specified Hyper-V Failover cluster
.PARAMETER ClusterName
The Name of the Hyper-V Failover Cluster to inspect
.EXAMPLE
PS F:\> Get-HyperVInventory -ClusterName "dev-cluster1"
.EXAMPLE
PS F:\> Get-Cluster | Get-HyperVInventory
.LINK
http://www.shogan.co.uk
.NOTES
Created by: Sean Duffy
Date: 09/07/2012
#>
[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=$true,HelpMessage="Name of the Cluster to fetch inventory from",
ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[System.String]
$ClusterName
)
process {
$Report = @()
$Cluster = Get-Cluster -Name $ClusterName
$HVHosts = $Cluster | Get-ClusterNode
foreach ($HVHost in $HVHosts) {
$VMs = Get-VM -Server $HVHost
foreach ($VM in $VMs) {
[long]$TotalVHDSize = 0
$VHDCount = 0
$VMName = $VM.VMElementName
$VMMemory = $VM | Get-VMMemory
$CPUCount = $VM | Get-VMCPUCount
$NetSwitch = $VM | Get-VMNIC
$NetMacAdd = $VM | Get-VMNIC
# VM Disk Info
$VHDDisks = $VM | Get-VMDisk | Where { $_.DiskName -like "Hard Disk Image" }
foreach ($disk in $VHDDisks) {
$VHDInfo = Get-VHDInfo -VHDPaths $disk.DiskImage
$TotalVHDSize = $TotalVHDSize + $VHDInfo.FileSize
$VHDCount += 1
}
$TotalVHDSize = $TotalVHDSize/1024/1024
$row = New-Object -Type PSObject -Property @{
Cluster = $Cluster.Name
VMName = $VMName
VMMemory = $VMMemory.VirtualQuantity
CPUCount = $CPUCount.VirtualQuantity
CPUSocketCount = $CPUCount.SocketCount
NetSwitch = $NetSwitch.SwitchName
NetMACAdd = $NetMacAdd.Address
HostName = $HVHost.Name
VMState = $HVHost.State
TotalVMDiskSizeMB = $TotalVHDSize
TotalVMDiskCount = $VHDCount
} ## end New-Object
$Report += $row
}
}
return $Report
}
}
Example use cases – load the function into your PowerShell session, or place it in your $profile for easy access in future, and run the following:
# Example 1
Get-HyperVInventory -ClusterName "mycluster1"
# Example 2
Get-Cluster | Get-HyperVInventory
# Example 3
Get-HyperVInventory -ClusterName "mycluster1" | ConvertTo-HTML | Out-File C:\Report.html
The function includes help text and examples, so you can also issue the normal “Get-Help Get-HyperVInventory” or “Get-Help Get-HyperVInventory -Examples”. It is by no means perfect and could do with some improvements, for example if there is more than one Virtual Switch Network associated with a VM these would be listed in a row multiple times for each. Feel free to suggest any improvements or changes in the comments.