A PowerShell Based Hyper-V Health Report

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.

Figure 2: A sample basic report

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.

Figure 3 Performance Counter Data

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.

Figure 4 Resource Meter Data

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
 [email protected]{
  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.

 

Threat Monitor
Share this post

Not a DOJO Member yet?

Join thousands of other IT pros and receive a weekly roundup email with the latest content & updates!

55 thoughts on "A PowerShell Based Hyper-V Health Report"

  • Stephen Barash says:

    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

  • 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

  • Mark Coffey says:

    Your Health report script is amazing. It’s exactly what I need.

  • Sweet script! I really like the hyper-V image on the report, it makes it so official. Thanks for sharing!!

  • Jacob Benson says:

    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.

  • Jacob Benson says:

    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.

  • Jacob Benson says:

    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?

  • Vishwajeet Shamra says:

    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.

  • Jacob Benson says:

    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.

  • Jacob Benson says:

    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.

  • Stephen Owen says:

    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!

  • gary says:

    Hi,

    i am getting the error ” the = operator is missing after a named argument”.

    Any idea what this could be?

  • Ray says:

    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.

      • Eric Siron says:

        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

  • Joe Aiello says:

    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.

  • Adam says:

    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.

  • Alpanama says:

    Excellent job, great script and nice interface.

  • Mushthaq says:

    Hi Altaro,

    The script is missing. Please share it. At least, send it by an email.

    • Eric Siron says:

      It’s still there but something is wrong with the link. I’ll get with the admins and see what’s going on.

  • Mushthaq says:

    Hi Altaro,

    The script is missing. Please share it. At least, send it by an email.

  • Vijay says:

    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

  • Andrew says:

    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?

  • Nazakat says:

    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 ?

  • Shweta Agarwal says:

    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.

  • Shweta Agarwal says:

    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.

  • narendra says:

    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.

  • Mark56 says:

    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.

  • Tim says:

    Did you ever get a chance to go back and add in Hyper-V Replication check in to your Health Report Powershell Script

Leave a comment or ask a question

Your email address will not be published. Required fields are marked *

Your email address will not be published. Required fields are marked *

Notify me of follow-up replies via email

Yes, I would like to receive new blog posts by email

What is the color of grass?

Please note: If you’re not already a member on the Dojo Forums you will create a new account and receive an activation email.