Table of contents
Over the course of the last year I’ve written a great deal about managing Hyper-V with Windows PowerShell. If you haven’t started tinkering with PowerShell to see what it can do for you, take a look at my articles here and get started! As I was writing all of these articles there was a long term project I had in the back of my mind and after a period of development and testing I think I’m ready to share it with you.
PowerShell not only makes it very easy to retrieve all types of useful information, but it can also create some pretty sharp looking reports, especially using HTML. So I decided to create a PowerShell script that would assemble all sorts of Hyper-V related data and create an HTML based health report. The script is rather long to post as a code sample, so you can open the text file here, or right click on the link and download. Save the file as New-HVHealthReport.ps1. You can give it a different name, but if you do so you will want to modify the comment-based help to reflect your new name.
The script requires at least PowerShell 3.0 and the Hyper-V, Storage and NetAdapter modules. The best thing to do is run this from a Windows 8 client with Remote Server Administration tools installed. You will also need admin rights on any Hyper-V server you want to check. The script creates a single report for a Hyper-V server. It will also work for client Hyper-V on Windows 8.x. Even though it is a script, you can ask for help like any other command.

Figure 1: Displaying Help
The report will default to the local computer and it can be run on the Hyper-V server if you really have to. If you do, you’ll still need the Storage and NetAdapter modules. Also by default the script will create the html file in your Documents folder with the name HyperV-health.htm. But you can use the –Path parameter to specify a different file name and location. PowerShell doesn’t really care what you use for a file extension. That’s really the minimum you need to know to run the script.
But what do you get? The report will include basic server information pulled from WMI displaying operating and computer system information, including memory utilization. For me memory utilization is critical. If the amount of free memory drops too low, that value will be highlighted in red. Or if getting close to my danger threshold it will be highlighted in yellow. Likewise disk space is critical so using WMI I get logical disk information for the server and display size, free space and utilization, again highlighting warnings and danger thresholds. I want to be able to tell at a glance where I have a problem.
Of course, the main part of the report is on the state of the virtual machines. The script will get basic information about running virtual machines using the Get-VM cmdlet. For each running machine the script displays the value of Hyper-V Integration services so you can see if any virtual machines are out of date. The script also displays detailed disk information for each virtual machine.
Using code from an earlier article I also show virtual machines created in the last 30 days. You can modify the number of days with the –RecentCreated parameter. I also show virtual machines that haven’t been turned on in a given time frame. Again the default is 30 days but you can use the –LastUsed parameter to change that value.
Finally, by default the script will query the event logs, including Hyper-V operational logs, for errors and warnings in the last 24 hours. You can use the –Hours parameter to specify a different value. Errors will be written in red so that they jump out at you.
All of this is what I consider basic usage. Here’s how easy it is to run the script.
PS C:> c:scriptsNew-HVHealthReport.ps1 -Computername chi-hvr2 -Path c:workchi-hvr2-health.htm
I’m using the default values for everything else. The script will display a progress bar letting you know what it is doing. When finished, open the file in your browser. When opening the file in Internet Explorer you might get a warning about running protected content. Go ahead and allow it.
Because there is a lot here, I added links to each adding that will collapse each section. If you click on the +/- at the top, you can toggle expanding and collapsing all sections. If you want to see the real report, click here.
But, as they say on late night television in the US, wait there’s more!
I also added two optional parameters to the script. One of them, -Performance, will query the server for all Hyper-V related performance counters. I’ve also included core operating performance counters for the host for things like processor, disk, memory and system. It is up to you to determine if a value is good or bad.
Related to performance, at least in my mind, I’ve also included an option to capture resource metering data, assuming you have it enabled. But if you do, use the –Metering parameter. Normally, resource meter data is use for things like charge back. But because it reflects usage, I think it is provides another glimpse into a virtual machine’s work load which I can use to gauge the overall health of the Hyper-V server.
Adding performance and metering data obviously creates a larger report and isn’t always required which is why I made them optional. Click here if you want to see a sample full report.
I use this script myself as part of a scheduled PowerShell job to run the report weekly and email it using Send-MailMessage. My mail server requires a credential so I create that in my script. In a domain environment you probably won’t need to do this.
Write-Host "$(Get-Date) Starting Send Weekly HV Health" -ForegroundColor Green $securepass= ConvertTo-SecureString -String "PASSWORD" -AsPlainText -Force $username= "me@company.com" $mailCred = New-Object System.Management.Automation.PSCredential $username,$securepass $mailCred = New-Object System.Management.Automation.PSCredential $username,$securepass #define a hash table of parameters to splat to Send-MailMessage $mailParams=@{ To= "me@company.com" From= "me@jcompany.com" Subject= $Null SMTPServer= "XXX.XXX.com" Body= $Null BodyAsHTML=$True Credential=$mailCred } $computers = $env:computername,"chi-hvr2.globomantics.local" foreach ($computer in $computers) { $file= Join-Path $env:temp "$computer-hvhealth.htm" c:scriptsNew-HVHealthReport.ps1 -Computername $computer -path $file -hours (24*4) if (test-path -Path $file) { #email the report Write-Host "Emailing report for $computer" -foreground Cyan $mailParams.subject="Weekly Hyper-V Health Report: $($computer.Toupper())" $mailParams.body= Get-Content $file | out-string Send-MailMessage @mailParams #remove the file Remove-Item -Path $file -Force } else { Write-Warning "Failed to create a report for $computer" } } Write-Host "$(Get-Date) Ending Send Weekly HV Health" -ForegroundColor Green
The script goes through my array of computers running Hyper-V and creates a report for each one. I then get the content of the file as one long string and use it as the body. When I call Send-MailMessage I’m also using the BodyAsHTML parameter. The end result is that I get a nicely formatted email once a week that shows me how my Hyper-V boxes are running. Certainly you could run this as often as you like, even daily.
Thanks to Eric Siron for providing feedback and testing a number of versions of this script. The script doesn’t make changes to anything so it should be safe to run, but please test it out in a non-production environment first. To keep the lawyers happy, this script is offered as-is with no warranty or guarantee. Use at your own risk.
That said, I think you’ll find this quite useful. I hope you’ll provide some feedback on how it works for you and what other health-related items you think I should add.