The Get-VHD PowerShell cmdlet grabs all VHD information associated with the specified VHD. It can be very useful if you want to either quickly gather information about all the VHDs on a host or just a single VHD. The information generated from Get-VHD can also be used in an automated weekly script to display information of selected VHDs.

Obtaining VHD Info from VHDs

One of the easiest ways to obtain VHD information of a VHD is to use the –Path parameter to specify the path of the VHD you want to gather information from:

Get-VHD –Path “C:ClusterSTorageVolume1VHDSTGLAB-BK01.vhdx"

1-vhd

Now we get a display of the VHD information of the specified VHD file:

2-vhddisplay

 

Obtaining VHD info from a VM

To obtain the VHD information of all VHDs attached to a specified VM, use the –VMId parameter. Since the Virtual Machine ID of each VM looks like this format “baaba8b4-a91e-40ff-8464-a40773755870”, it would be very tedious to memorize and keep track of this for every VM. Fortunately, if we use the Get-Help cmdlet, we can find an easier way to obtain the VHD information based on VM:

Get-Help Get-VHD –Full

We can see that the –VMId parameter accepts pipeline input:

3-Parameter

This will allow us to use the ever so useful Get-VM cmdlet to specify the VM that we want. Then, we pipe that through Select-Object to get only the Virtual Machine Identifier property from the VM. Finally, we pipe it through again to Get-VHD’s parameter. In this example, we will get the VHD information on all VHDs that are attached to the TGLAB-DC01 VM:

Get-VM –VMName TGLAB-DC01 | Select-Object VMId | Get-VHD

4-VM

We now get a display of the different properties of each VHD that is attached to the VM TGLAB-DC01:

5-vmdisplay

Getting VHD info from Multiple VMs

To get VHD information from all VMs on a host, simply use the asterix (*) symbol after the –VMName parameter to specify all VMs:

Get-VM -VMName * | Select-Object VMid | Get-VHD

15-multvms

We now get a display of all VHDs associated with all VMs on the host:

7-multvmdisp

To get VMs from multiple hosts, simply use the –ComputerName parameter with the Get-VM cmdlet. In this example we will specify the two hosts TGLAB-HV01 and TGLAB-HV02:

Get-VM –VMname * -Computername TGLAB-HV01,TGLAB-HV02 | Select-Object VMId | Get-VHD

Being able to generate this info for all our VHDs is very useful. However, the list can get lengthy and tedious to look through. Thanks to the magic of PowerShell, we convert this information into a format that is easier to read.

Converting Information to HTML

The benefits of converting information over to HTML format not only provides better readability, but also allows the information to be saved, stored, shared, and emailed. To this, we simply pipe our VHD information to the ConvertTo-HTML cmdlet and then use the redirection operator (>) to send the HTML code to a .htm file. In this example we will name the .htm file “vhdreport.htm” and place it in the C: directory:

Get-VM –VMName * | Select-Object VMid | Get-VHD | ConvertTo-HTML > “C:vhdreport.htm"

8-html

When vhdreport.htm is opened up in a web browser, we now get an HTML table that is much easier to read than the information displayed in the PowerShell console:

9-htmlrep

The HTML document still has a lot of information. If we wanted to take it a step further and have only certain properties be displayed, we can pipe our command to Get-Member, or GM for short, to see which properties are available to display:

Get-VM –VMname * | Select-Object VMid | Get-VHD | Get-Member

10-htmlgm

Let’s say we just want to see the path of our VHDs, the host that each VHD is on, the size of the VHD file, and the VHD type. To do this, we would simply use the –Property parameter with ConvertTo-HTML and list only the properties that we want to see:

Get-VM * | Select-Object VMId | Get-VHD | ConvertTo-HTML –Property path,computername,filesize,vhdtype > “C:SimpleVHDReport.htm"

11-htmlsimple

Now, when we open up simpleVHDReport.htm, we see an HTML table with only the information we specified:

12-htmlsimpreport

Let’s not stop there. The file size information can be a little difficult to interpret into GBs just by looking at it. Thanks to PowerShell we can convert this information into GBs on the fly while we are inputting our command!

We can use a hash table in place of the filesize property to perform the conversion at the same time we are listing the properties:

Get-VM –VMname * | Select-Object VMId | Get-VHD | ConvertTo-HTML –Property path,computername,vhdtype,
@{label=’Size(GB)’;expression={$_.filesize/1gb –as [int]}} > “C:SimpleVHDReport.htm"

13-htmlgb

We now have the file size of our VHDs converted to GBs in the HTML table:

14-htmlgbrep

This could be extremely useful to run as a reoccurring script if you wanted to keep watch of the file size of each VHD, especially in an environment that heavily uses Dynamic disks.

 

Is Your Office 365 Data Secure?

Did you know Microsoft does not back up Office 365 data? Most people assume their emails, contacts and calendar events are saved somewhere but they're not. Secure your Office 365 data today using Altaro Office 365 Backup - the reliable and cost-effective mailbox backup, recovery and backup storage solution for companies and MSPs

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!

14 thoughts on "Getting VHD info using PowerShell with Get-VHD"

  • Thanks, Luke!
    Very useful and detaled info.

  • Thanks, Luke!
    Very useful and detaled info.

  • Jake says:

    Hi Luke, great article! Do you maybe know if there’s a variation of this command that will allow you to see all the VM’s on a host including their VHD locations. The (Get-VM –VMName * | Select-Object VMId | Get-VHD) command lists all the vhd’s against the host but does not actually say which VM’s they are related to.

    • BrainSlugs83 says:

      It’s a little ugly, but add-member doesn’t seem to return the original object so you kind of have to hack it together — I recommend saving it to a cmdlet or a function:

      Get-VM | % { $vhd = Get-VHD -VmId $_.VmId; $vhd | Add-Member -NotePropertyName “Name” -NotePropertyValue $_.Name; $vhd; } | Format-Table

  • Peter Hutchings says:

    Fantastic page!

    I’m new to Powershell, so this was exactly what I was looking for; an easy to read, step-by-step guide that teaches me section-by-section of the code what each part it aiming to achieve.

    I’m now going to try to work on this code and expand it to pull the info for my entire cluster, not just one node.
    Wish me luck 🙂

    Thanks Luke!

  • Emrah Ozdemir says:

    Thanks for Great script and details.

  • Uri Guy says:

    hi,
    from what I see this actually doesn’t work for VMs on multiple hosts (it only works for VMs from the host you are running on). the example in the articles also shows only VMs from one host (tglab-hv01). the error I get for VMs on another host is: “Get-VHD : Hyper-V was unable to find a virtual machine with the given criteria.”

  • Paul says:

    Thanks for the great detail!

    I see you grabbed Get-VM to start, is there a way to keep the VM name (not just the hostname) in the output table? I’d like to link back all the VHDs to the VM they are connected to.

    Thank you again!

    • Hi Paul,
      The Microsoft.Vhd.PowerShell.VirtualHardDisk typename doesn’t contain a VM property, so we would need to create a more complex script using a psobject to display the VM. You can still link back each VHD to their VM by looking at the PATH field. By default the VHD’s are stored under the VM folder.

      -Thanks!

  • Oleg says:

    thx u.
    But this script only for offline VM?
    Whan I tried run this script to all my VM, I see information only offline machine.
    If VM Online: ” Error: ‘The process cannot access the file because it is being used by another process.’.
    The operation cannot be performed while the object is in use.”

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.

Related posts