Save to My DOJO
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.
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= "[email protected]" $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= "[email protected]" From= "[email protected]" 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.
Not a DOJO Member yet?
Join thousands of other IT pros and receive a weekly roundup email with the latest content & updates!
71 thoughts on "A PowerShell Based Hyper-V Health Report"
Very nice! Thank you…
Very nice. It would be nice if the screenshot images opened up into a larger/full version when clicked, and not the same slightly reduced size, which are rather hard to see/read.
Cheers, Morten
I knew screenshots were going to be difficult no matter what I tried which is why I include links to full reports which you should find in the article.
Very nice. It would be nice if the screenshot images opened up into a larger/full version when clicked, and not the same slightly reduced size, which are rather hard to see/read.
Cheers, Morten
Your Health report script is amazing. It’s exactly what I need.
Thank you. How do you plan on using it?
Sweet script! I really like the hyper-V image on the report, it makes it so official. Thanks for sharing!!
Thank you. You can always change the image as well if you want to use a corporate logo or something.
Any idea why every time I run this script it tells me “WARNING: Failed to find a VM or VMs with a name like *”. I am running from a Windows 8.1 computer. I am a domain admin and have rights to all the Hyper-V hosts we manage.
Make sure you are running in an elevated session. If you run Get-VM and get nothing, then the script won’t work either. But if you run Get-VM and it works, running the script in the same session, should work. If you are trying to run this as a scheduled task, make sure you add the option to run elevated.
Running from an elevated session, Get-VM returns all the VM’s. The script still returns the same error, from within the same session.
If I run the script directly on the host from an elevated prompt, the issue doesn’t occur.
Are there any running virtual machines? The script can only get health from running VMs.
Yes, there are 5 running VM’s on this particular host.
Hmm. Well I can’t look at this until Monday when I’m back at my desk on Monday. Are you running the script ON the Hyper-V server or remotely from a client? I am assuming you are testing this interactively and not through a scheduled task or anything. What OS is running on the Hyper-V server?
It is very nice as I was working on it and made but could not as it is. Shall I extract for all the hyper-v node of a cluster or all hyper-v host in a domain? Please reply.
I am not sure what your question is. It shouldn’t matter if you have a cluster. Use the script and use the cluster name for the server name, just as if you were using Get-VM to get virtual machines on a remote server. If you have multiple servers, you can use a ForEach loop to create a report for each one.
$computers = get-content computers.txt
foreach ($computer in $computers) {
C:scriptsNew-HVHealthReport.ps1 -Computername $computer -Path “C:work$computer-health.htm”
}
You can only have one report per Hyper-V server.
Where in the code would you place this loop for I also have multiple remote servers in a .txt file that I would like to generate a report for. Thank you in advance!
You don’t edit the file. What I’m showing is how you would loop through a list of names and call this script.
Jeff –
I am running this from my Windows 8.1 desktop. If I run Get-VM -VMHost HostName it returns a list of running VM’s on the host. If run the script from the same desktop, with the same host, it returns the message “WARNING: Failed to find a VM or VMs with a name like *”. If I run the script while I am logged into the host itself, it works fine. The host is Windows 2012 R2.
Somehow this didn’t get saved the first time so let me try this again.
I am running this from my Windows 8.1 desktop. If I run Get-VM -VMHost Hostname, it returns 5 running VMs. If I run the report from my desktop, with the same host name, it returns the warning that “WARNING: Failed to find a VM or VMs with a name like *” . If I run the report from the host itself (Server 2012 R2) it runs with no problems.
I took this up offline with Jacob and tracked down the problem. He is using the System Center Virtual Machine Manager module on his desktop which also has a Get-VM command. Well, technically it is an alias for Get-SCVirtualMachine which is a completely different cmdlet. That explains why the script fails when run from his desktop. To get the script to work, he will need to start a PowerShell session and make sure the Hyper-V module gets loaded. I may also need to see what changes I can make to the script to make it a bit more bulletproof. I don’t use the System Center products yet so this didn’t come up in my testing.
This report looks really, really fantastic. This is a great asset for the community, it also provides a great jumping off point for other similar HTML/CSS reports.
I know I feel like I need to upgrade my own reports now!
Thanks. I have a number of other posts on my blog (http://jdhitsolutions.com/blog) about creating html reports in PowerShell. Search for HTML and you should get a number of articles.
Hi,
i am getting the error ” the = operator is missing after a named argument”.
Any idea what this could be?
Sounds like a syntax error. Exactly what command are you typing to run the script? Look at full help for the script to see examples.
This is fantastic. Thanks a lot. It would be great if It could creat one HTML file for the cluster rather than one per node….
I could add an option to create a single HTML report for multiple virtual servers. I don’t have access to a Hyper-V cluster to develop anything cluster-specific. But it is in the to-do list for the next script revision.
I just ran into this in a couple of scripts I’m developing. The loading behavior of the VMM cmdlets is a bit inconsistent.
I took the easy way out and just modified my scripts so that Get-VM is now fully qualified as Hyper-VGet-VM. The cheat sheet for when this is necessary was pretty easy to generate:
Get-Command -Module Hyper-V | % { Get-Alias -Name $_.Name -ErrorAction SilentlyContinue } | ft Name
Name
—-
Get-VM
Get-VMHost
Move-VM
New-VM
Remove-VM
Repair-VM
Resume-VM
Set-VM
Set-VMHost
Start-VM
Stop-VM
Suspend-VM
I was looking for a way to get a status report on Hyper-V Replication so I could ensure that replication is happening continuously. Is there a way to do this in PowerShell and add to the report? Or perhaps another tool? I find the ‘right-click, view Replication Health’ to be way too cumbersone and manual.
There is a Get-VMReplication cmdlet you could use. I don’t have a replication setup. You can also get the replication information with Get-VM like this:
get-vm | select Name,Replication*
You could then filter for problems:
get-vm | Where {$_.ReplicationHealth -eq ‘Critical’} | select Name,Replication*
That is something I could put on the list for a future version.
Should this report work when querying Windows 2012 NOT R2 Hyper-V servers?
This script relies on the PowerShell Hyper-V module and was originally developed and tested with Windows 8 and Windows Server 2012. If you have Hyper-V running on Windows Server 2008 or later, I honestly am not sure if it will work since I don’t have that setup. I would suggest on a client with the Hyper-V module, open a prompt and run a few commands against your Hyper-V server.
get-vmhost -ComputerName YOUSERVERNAME
get-vm -computername YOURSERVERNAME
If the commands work without error, then there is a good chance my script will work and is worth a try.
Excellent job, great script and nice interface.
Hi Altaro,
The script is missing. Please share it. At least, send it by an email.
It’s still there but something is wrong with the link. I’ll get with the admins and see what’s going on.
The script i download it doesn’t had the performances. Can i had the script with the Performances of the VMs.
Hi Altaro,
The script is missing. Please share it. At least, send it by an email.
Hello,
I am not able to run your script getting multiples error, can you please confirm or give me the standalone servers script, as i have 12 standalone server.
Advance thanks if you give me the good script
I try running the script but it seems that I cannot load hyper-v module. Any idea of why and how can I fix it?
On Windows 10 you need to add the Hyper-V Management tools feature.
Dear Jeffery,
I went through the screenshots and complete articles, tho couldn’t find any link to download this ps1 file. Any help on downloading it please ?
There are no direct download links. You should be able to copy code from page.
Hi, I want to know that how we can automate the health check on VMAX server using PowerShell and how we can health check on SAN switch.
I want to know that how we can apply automation on network and switch, san, router using the PowerShell.
Eagerly waiting for your reply.
I’m not aware off the top of my head of cmdlets for managing those things. This is the kind of thing that is vendor dependent.
how can I apply PowerShell script on the backup servers and fetch their details and also I need the script like how to automatically health check the VMAX server and health check on switches using the PowerShell script and can you provide me the scripts for these. I really want to know that how we can automate the switch, san devices, and routers for fetching the information using PowerShell.
Eagerly waiting for your reply.
get-vmhost : vmNtNat cannot resolve with DNS. (Error ID: 404, Detailed Error: No such host is known)
Ensure there is network communication with the DNS server. If the problem persists, contact your net
At line:1 char:1
get-vmhost -ComputerName vmNtNat
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : ReadError: (:) [Get-SCVMHost], CarmineException
FullyQualifiedErrorId : 404,Microsoft.SystemCenter.VirtualMachineManager.Cmdlets.GetHostCmdlet
i,m getting this error while running GET-vmhost , if so your script well work or not.
My commands are designed for the native Hyper-V cmdlets. Looks like you are using the System Center commands which share the same name but are different commands.
Good Day, I have been getting into some Powershell on our physical servers and developed a routine that would get the hard drive space and the Event Viewer Warning messages to work for all of our servers.
Now we are getting into the Hyper-V server building and of course I have now been asked to see about providing information on then in a morning email as well.
This Hyper-V Reporting script with the email script listed is coming close to what I am needing but not being a Powershell expert by any means I am having a problem with getting our second Hyper-V server to be evaluated. It does the Server1 twice.
My c:scriptsNew-HVHealthReport.ps1 is on Server1 and Server2 does not have any PS scripts on it.
I maybe messing up on the email line of: $computers = $env:computername,”chi-hvr2.globomantics.local”
In my old PS script, I had a text file that had my server names that I used to gather the information on each server remotely. We have the two Hyper-V servers with two VM’s on each for now and 6 other physical servers.
Please help point me in the error Tm not getting the second HV server to get reported. Thank you for your time in not only developing this very nice script but in taking the time to help out those of us that only do server admin as a secondary job.
I would not be running the scripts ON the server. They are written to be run from an admin desktop. You could be running into 2nd hop issues or authentication. You should be able to run the last code listing from your desktop,. changing variables as needed.
Did you ever get a chance to go back and add in Hyper-V Replication check in to your Health Report Powershell Script
I don’t use replication, so I haven’t gotten around to adding it.