Tuesday, 18 October 2011

Use powershell to document your Hyper-V installation

I want the share this little script I wrote that helped me to document Hyper-V R2 cluster installation. This particular installation had more than 30 virtual machines and I had to document virtual machines properties and disk configuration.

The benefit of this script is that it merges output from two powershell commands, Get-VM and Get-VirtualHardDisk.

$vmmserver = Get-VMMServer -ComputerName SCVMMSERVER

$vms =  Get-VM | Sort-object Name | where {$_.HostGroupPath -like "All Hosts*"}

foreach ($vm in $vms)
{
    $disks = $vm | Get-VirtualHardDisk
        foreach($d in $disks) {

        new-object PSObject -prop @{
        VMName = $vm.Name
        Type = $d.VHDType
        "Disk name" = $d.Name
        "Size GB" = [math]::truncate($d.Size / 1GB)
        }

        }

}

The script generates this output:

Size GB  Type                  Disk name               VMName
-------  ----                  ---------               ------
     20  FixedSize             9002D_SERVER1_disk_1    9002D-SERVER1
      9  DynamicallyExpanding  9021D-TESTVM_disk_1     9021D-MGMTSERVER
     40  FixedSize             _CBBMSERVER
     40  FixedSize             HQVM-PRINTSERVER_C      PRINTSERVER
     20  FixedSize             HQVM-PRINTSERVER_D      PRINTSERVER
      6  DynamicallyExpanding  TEST_disk_1             TEST
     40  FixedSize             _CTest
     15  FixedSize             HQVMAC01_HQVMAC01_C     HQVMAC01
     21  FixedSize             HQVMAC01_D              HQVMAC01
     15  FixedSize             HQVMAC02_C              HQVMAC02
     21  FixedSize             HQVMAC02_D              HQVMAC02



With a little modification to the script you could include additional columns in the output. Let's say that you need CPU count and Memory included in the output:

$vmmserver = Get-VMMServer -ComputerName SCVMMSERVER

$vms =  Get-VM | Sort-object Name | where {$_.HostGroupPath -like "All Hosts*"}

foreach ($vm in $vms)
{
    $disks = $vm | Get-VirtualHardDisk
        foreach($d in $disks) {

        new-object PSObject -prop @{
        VMName = $vm.Name
        Type = $d.VHDType
        "Disk name" = $d.Name
        "Size GB" = [math]::truncate($d.Size / 1GB)
        Memory = $vm.Memory
        "CPU Count" = $vm.CPUCount
        }
        }
}

Note that I have added two rows in the script:

        Memory = $vm.Memory
        "CPU Count" = $vm.CPUCount

The output now looks like this:

Size GB   : 9
CPU Count : 1
Memory    : 1024
Type      : DynamicallyExpanding
Disk name : 9021D-TESTVM_disk_1
VMName    : 9021D-SERVER1

Size GB   : 40
CPU Count : 1
Memory    : 1024
Type      : FixedSize
Disk name : _C
VMName    : HQVM-BBM

Size GB   : 40
CPU Count : 1
Memory    : 1024
Type      : FixedSize
Disk name : HQVM-PRINTSERVER_C
VMName    : HQVM-PRINTSERVER

Size GB   : 20
CPU Count : 1
Memory    : 1024
Type      : FixedSize
Disk name : HQVM-PRINTSERVER_D
VMName    : HQVM-PRINTSERVER

Size GB   : 6
CPU Count : 4
Memory    : 512
Type      : DynamicallyExpanding
Disk name : TEST_disk_1
VMName    : TEST

Size GB   : 40
CPU Count : 1
Memory    : 1024
Type      : FixedSize
Disk name : _C
VMName    : Test

Size GB   : 15
CPU Count : 1
Memory    : 1024
Type      : FixedSize
Disk name : HQVMAC01_HQVMAC01_C
VMName    : HQVMAC01

Size GB   : 21
CPU Count : 1
Memory    : 1024
Type      : FixedSize
Disk name : HQVMAC01_D
VMName    : HQVMAC01

Size GB   : 15
CPU Count : 1
Memory    : 2048
Type      : FixedSize
Disk name : HQVMAC02_C
VMName    : HQVMAC02

Size GB   : 21
CPU Count : 1
Memory    : 2048
Type      : FixedSize
Disk name : HQVMAC02_D
VMName    : HQVMAC02


This is good, but not exactly the table we expected and it's hard to convert it into a configuration table that we could copy/paste into installation document.

So the solution is to create a function from our script like this:

function Global:Get-VMConfiguration()
{
$vmmserver = Get-VMMServer -ComputerName SCVMMSERVER
$vms =  Get-VM | Sort-object Name | where {$_.HostGroupPath -like "All Hosts\Production*"}

foreach ($vm in $vms)
{
    $disks = $vm | Get-VirtualHardDisk
        foreach($d in $disks) {
        new-object PSObject -prop @{
        VMName = $vm.Name
        Type = $d.VHDType
        "Disk name" = $d.Name
        "Size GB" = [math]::truncate($d.Size / 1GB)
        Memory = $vm.Memory
        "CPU Count" = $vm.CPUCount
        }
        }
}
}


And call that function:

Get-VMConfiguration | Format-Table -Property vmname,memory,"cpu count","disk name",type,"size gb"

This would give you a nicely formatted table that you could paste into a Word document.
Or even better, you could use export-csv function:

Get-VMConfiguration | export-csv -Path c:\Export.csv
Now you can import this comma separated file into Excel and format it as you wish.

1 comment:

  1. Hi friend! Best script!!
    look i can group by vmhost and vm?

    I have vm with 2 or more disks and i display in html and group!!


    Tks Carlos

    ReplyDelete