Get Virtual Machine Inventory from a Hyper-V Failover Cluster using PowerShell

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.

 

PowerCLI – Fetch Interesting stats or configuration for a list of VMs

Now and then I find that I need to retrieve some useful information from a variety of VMs, this usually involves me doing a Get-VM with some selections and criteria to search for. However sometimes the information I require about a VM is listed in the advanced configuration and not as easy to get to with a single cmdlet. I thought it would be really handy to have a PowerCLI function that would easily pull the useful information out for me and summarise it for any given VM or set of VMs.

 

With that said, I recently read a great blog post by Jonathan Medd (Basic VMware Cluster Compatibility Check), and after reading it I thought it would be a great idea to create a set of functions that provide me with the information I often use. To start, I thought I would do a function that lists the most useful or common information about VMs that I often search for. As well as speeding up the process of retrieving information about VMs, I thought it would also be good PS/PowerCLI practise for me to write more functions. The reason being that I often tend to do PowerCLI reporting scripts rather than actual functions that accept input from the pipeline or other parameters. Below is my function to collect some useful information about Virtual Machines – you can specify a VM with the -VM parameter or pipe a list of VMs to it, using Get-VM | Get-VMUsefulStats. Jonathan’s post also had an interesting section about the order in which output is displayed. You’ll need to pipe the output to Select-Object to change the order the information is fed back in, otherwise it will list the information in the default order. This is not really a problem anyway, just good to know if you are fussy about the order in which the output comes back in!)

 

So, here is the first function (Get-VMUsefulStats):

 

[download id=”7″]

 

function Get-VMUsefulStats {
<#
.SYNOPSIS
Fetches interesting or useful stats about VMware Virtual Machines

.DESCRIPTION
Fetches interesting or useful stats about VMware Virtual Machines

.PARAMETER VM
The Name of the Virtual Machine to fetch information about

.EXAMPLE
PS F:\> Get-VMUsefulStats -VM FS01

.EXAMPLE
PS F:\> Get-VM | Get-VMUsefulStats

.EXAMPLE
PS F:\> Get-VM | Get-VMUsefulStats | Where {$_.Name -match "FS"}

.LINK
http://www.shogan.co.uk

.NOTES
Created by: Sean Duffy
Date: 18/01/2012
#>

[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=$true,HelpMessage="Name of the VM to fetch stats about",
ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[System.String]
$VMName
)

process {

$VM = Get-VM $VMName

$VMHardwareVersion = $VM.Version
$VMGuestOS = $VM.OSName
$VMvCPUCount = $VM.NumCpu
$VMMemShare = ($VM.ExtensionData.Config.ExtraConfig | Where {$_.Key -eq "sched.mem.pshare.enable"}).Value
$VMMemoryMB = $VM.MemoryMB
$VMMemReservation = $VM.ExtensionData.ResourceConfig.MemoryAllocation.Reservation
$VMUsedSpace = [Math]::Round($VM.UsedSpaceGB,2)
$VMProvisionedSpace = [Math]::Round($VM.ProvisionedSpaceGB,2)
$VMPowerState = $VM.PowerState

New-Object -TypeName PSObject -Property @{
Name = $VMName
HW = $VMHardwareVersion
VMGuestOS = $VMGuestOS
vCPUCount = $VMvCPUCount
MemoryMB = $VMMemoryMB
MemoryReservation = $VMMemReservation
MemSharing = $VMMemShare
UsedSpaceGB = $VMUsedSpace
ProvisionedGB = $VMProvisionedSpace
PowerState = $VMPowerState
}
}
}

 

You can use the cmdlet to very easily retrieve information about a single VM or list of VMs. Examples:

 

Get-VMUsefulStats -VM NOOBS-VC01

Get-VM | Get-VMUsefulStats

 

To format the output in a neat table, pipe the above to Format-Table (ft) like so:

 

Get-VM | Get-VMUsefulStats | ft

 

The “MemShare” value is interesting – it is something I was specifically interested in, as some VMs I have worked with in the past have needed memory sharing to be specifically disabled, and this is something that needs to be changed with an advanced parameter on the VM. Therefore most (default) VMs will not have this entry at all and will appear blank in the output. (the parameter I am referring to for those interested is sched.mem.pshare.enable). Of course this most likely won’t be of any use to you, so feel free to omit this bit from the function, or feel free to customise the function to return information useful to your VMware deployment VMs. Here is an example of the output for one VM.

 

 

Anyway, I hope someone finds this useful, and please do let me know if you think of any improvements or better way of achieving a certain result.

 

Hello PowerCLI

 

So today is the first time I am trying out PowerCLI for vSphere. Yes, I know I am late to the game in the VMware scene, but I hope to start learning more about PowerCLI and start automating some tasks that are currently being done manually where I work.

 

Here is my first try at connecting to my lab vCenter server 🙂

 

Pretty simple really, just as the banner text says, use:
Connect-VIServer servername and
Get-VM

to connect and get a list of VMs. I guess this is my “Hello World” start out with PowerCLI then. If anyone has any tips or quick and easy cmdlets to run in PowerCLI to get information back, please drop a comment with them below. I would also love to know how to iterate through a list of VMs and check whether they have snapshots or not! That would be a great start to what I am looking to achieve.

Cheers!