Updated – 29/09/2023 – The tool was updated to include the disk identifier for each VM/VHDX in the Hyper-V Cluster.
Updated – 06/03/2023 – The tool was updated to include memory, CPU, and network IP addresses for each VM in the Hyper-V Cluster.
In this article, we will share with you how to get the list of all VMs in the Hyper-V Cluster and their Virtual Hard Disks with PowerShell.
Table of Contents
Introduction
A while ago, I published a PowerShell script that will query System Center Virtual Machine Manager (SCVMM) to get all Virtual Machines including their Virtual Hard Disks, then it will calculate the size and percentage used for each VHD(X), and finally send you a nicely formatted HTML report. You can read all about it here.
In this blog post, we will share with you how to get the same report in comma-separated value (CSV) format and without SCVMM.
This comes in handy when working with a large Hyper-V cluster with many VMs, and you want to know the type of each virtual hard disk attached to every VM including their footprint size on the disk, and the remaining disk space so you know before the VM runs out of disk space.
Prerequisites
To run the function below successfully, you should note the following points:
1) You need to have Failover Cluster Module for Windows PowerShell installed on your machine:
Install-WindowsFeature -Name RSAT-Clustering-PowerShell
2) You need to have Hyper-V Module for Windows PowerShell installed on your machine:
Install-WindowsFeature -Name Hyper-V-PowerShell
3) Make sure to run (execute) the entire script first before you run it against your Cluster because this is a PowerShell function.
If you are working interactively in the console then the entire function can be copied and pasted into that session, then it will be available for the duration of that session.
I find this easier to do via the PowerShell ISE or Visual Studio Code than the standard PowerShell console.
So, you need to copy the function into the script pane, then click the Green Run Script or hit the F5 button. The function will be available for use and if using the ISE will appear interactively when you start typing the name as shown in the figure below:

Now, if the function below is something that you wish to use regularly in your interactive PowerShell sessions, then you can place it in your PowerShell Profile and it will be available every time you open your PowerShell console.
Learn more about PowerShell profiles and how to create one. Once you have created a PowerShell profile, place the function below in your profile and save it. Now every time you open your PowerShell console, the function will be available to use.
Another option is you store the function in a module. Using a PowerShell module is a more advanced significantly more structured and powerful method.
4) Last, you can run the function as follows:
Get-VMVHDs -ClusterName "HyperV-Cluster-Name"
Get The List of All VMs in a Hyper-V Cluster
Here is the PowerShell function that will do the job for you:
Function Get-VMVHDs {
<#
.Synopsis
A script used to find all VHD(X) files for all VMs in a Hyper-V Cluster
.DESCRIPTION
A function used to find all VHD(X) files for all VMs in a Hyper-V Cluster,
including the type of each virtual hard disk attached to every VM with their footprint size on disk,
and the remaining disk space, so you know before the VM runs out of disk space.
Finally, it will export the report into a CSV file.
The report will also include the IP addresses, virtual memory and virtual CPU for each VM.
.Notes
Created : 03-12-2018
Updated : 29-09-2023
Version : 3.2
OS : Windows Server 2016, 2019, 2022 Hyper-V or later
Author : Charbel Nemnom
Twitter : @CharbelNemnom
Blog : https://charbelnemnom.com
Disclaimer: This script is provided "AS IS" with no warranties.
.EXAMPLE
. .\Get-VMVHDs.ps1
Get-VMVHDs -Cluster "Cluster-Name"
#>
[CmdletBinding(SupportsShouldProcess = $true)]
Param(
[string]$ClusterName
)
Get-ClusterGroup -Cluster $ClusterName | ? { $_.GroupType -eq 'VirtualMachine' } | Get-VM | `
% { $vhd = Get-VHD -ComputerName $_.ComputerName -VmId $_.VmId; $vhd | `
Add-Member -NotePropertyName "Name" -NotePropertyValue $_.Name; $vhd | `
Add-Member -NotePropertyName "ProcessorCount" -NotePropertyValue $_.ProcessorCount; $vhd | `
Add-Member -NotePropertyName "MemoryStartup" -NotePropertyValue $_.MemoryStartup; $vhd | `
Add-Member -NotePropertyName "NetworkAdapters" -NotePropertyValue $_.NetworkAdapters.IPAddresses; $vhd } | `
Select-Object @{label = 'VM Name'; expression = { $_.Name } }, `
@{label = 'vCPU'; expression = { $_.ProcessorCount } }, `
@{label = 'vMem (GB)'; expression = { $_.MemoryStartup / 1gb –as [int] } }, `
@{label = 'IP Addresses'; expression = { $_.NetworkAdapters } }, `
@{label = 'Host Name'; expression = { $_.ComputerName } }, `
Path, VhdFormat, VhdType, `
@{label = 'Size On Physical Disk (GB)'; expression = { $_.FileSize / 1gb –as [int] } }, `
@{label = 'Max Disk Size (GB)'; expression = { $_.Size / 1gb –as [int] } }, `
@{label = 'Remaining Space (GB)'; expression = { ($_.Size / 1gb - $_.FileSize / 1gb) –as [int] } }, `
@{label='Disk Identifier'; expression={$_.DiskIdentifier}} | `
Export-Csv -Path "C:\$($ClusterName)-VHDReport.csv" -NoTypeInformation -Force
}
And here is the final report in CSV format:

This is version 3.2, do you want additional features? Please feel free to leave a comment below.
Make sure to check my recent Windows Server Hyper-V Cookbook for in-depth details about Hyper-V!
Enjoy :)
__
Thank you for reading my blog.
If you have any questions or feedback, please leave a comment.
-Charbel Nemnom-
Hi Charbel,
Looking at this it has most of the info I need, the rest is specific for us so no need to add to the script.
But the problem is that I don’t get it to work. :(
It runs without any errors at all but it doesn’t create the CSV file
I’ve run the prerequisites first and I tried running it with the code as it is and as a .ps1 file
Regards Christian
Hello Christian, thanks for the comment and feedback!
Could you please confirm that you run the script as administrator?
Open the PowerShell console as admin.
From where are you running the script, on the C:\ drive?
Try to change the location and ensure that you have enough permissions for the CSV file to be created.
Hope it helps!
Hi Charbel,
I’m running it as a domain admin and tried it both in elevated mode and later in normal mode.
The folder I’m running it from is C:\PowerShell and I’m running it on one node of our Hyper-V Cluster.
I also tried changing where the CSV is created from C:\ that’s in your script to C:\PowerShell just to be sure that it isn’t permission thing.
Hello Christian, thanks for the update!
To be honest, this is really strange.
Maybe you have done that, could you please confirm that you ran (executed) the entire script first before you ran it against your Hyper-V Cluster?
Could you please try again running the function, I have updated the tool to include the -Force parameter as follows:
I am not sure if that makes sense in your environment, but it’s worth to give it a try.
Hope it helps!
Hi Charbel!
Script works great! I was wondering how I could modify this to also return the DiskIdentifier attribute?
Hello Marti, thanks for the feedback!
I am happy to hear that the script is working for you.
Please note that the tool was updated to return the ‘Disk Identifier’ attribute for all Virtual Hard Disks.
Give it another try and let know if it works for you.