Search code examples
powershellwindows-server-2012-r2hyper-v

Grab all VMs in Hyper-V cluster Windows 2012 R2 and their disks sizes


I'm trying to get html report with provisined disks size for all VMs in cluster. I'm trying to list all VMs inside cluster with:

$VMs = get-ClusterGroup | ? {$_.GroupType -eq "VirtualMachine" } | Get-VM

And this works like a charm. However when I'm trying make a loop:

foreach ($VM in $VMs)
{
 Get-VM -VMName $VM.Name | Select-Object VMId | Get-VHD
}

I'm getting error for each VM that is not located on my current cluster node when I'm running this. So per each node I'm running following command:

Get-VM -VMName * | Select-Object VMId | Get-VHD | ConvertTo-HTML -Proprerty path,computername,vhdtype,@{label='Size(GB)');expression={$_.filesize/1gb -as [int]}} > report.html

And this works like a charm also. But this is require to login to each Hyper-V host in cluster. How to make it happened to get output in HTML with all VMs in cluster from one node?


Solution

  • How about something like this?

    $nodes = Get-ClusterNode
    foreach($node in $nodes)
    {
        $VMs=Get-VM -ComputerName $node.name
        foreach($VM in $VMs)
        {
            $VM.VMName
            Get-VHD -ComputerName $node.Name -VMId $VM.VMId | ft vhdtype,path -AutoSize
        }
    }
    

    From what I can tell; you need the node name as -ComputerName and -VMId for each Get-VHD call. Passing the Get-VM to Get-VHD doesn't provide the node name for some reason.

    What you are looking for, the above does not provide the results as a single Object to be formatted (html or otherwise). There is however an inline ForEach-Object that will do the trick.

    This is maybe what you are looking for:

    Get-VM -ComputerName (Get-ClusterNode) | 
    ForEach-Object {Get-VHD -ComputerName $_.ComputerName -VMId $_.VMId} | 
    ConvertTo-HTML -Property path,computername,vhdtype,@{label='Size(GB)';expression={$_.filesize/1gb -as [int]}} > report.html
    

    In a single line:

    Get-VM -ComputerName (Get-ClusterNode) | ForEach-Object {Get-VHD -ComputerName $_.ComputerName -VMId $_.VMId} | ConvertTo-HTML -Property path,computername,vhdtype,@{label='Size(GB)';expression={$_.filesize/1gb -as [int]}} > report.html
    

    Hope this meets your needs. Enjoy!