А АSaturday 26 March 2022

Собираем статистику HyperV в один клик.

Всем привет.

Встала задача оперативно собрать информацию по HyperV виртуалкам. Задействуем Powershell. Оказалось что накидать парочку Get-запросов не проблема. Проблема больше коснулась самого экспорта данных, да так чтобы в Excel и чтобы было все красиво. В двух словах надо было слить воедино то что собирают 5 запросов в одну таблицу.  При этом, как вы понимаете, получается десяток колонок с разными названиями, которые не хотели вливаться в единый CSV-файл. 

В какой-то момент времени я понял, что значения хорошо вливаются если в CSV-файле уже есть колонка с нужным названием. То почему бы не сделать первую строку с нужными названиями  (headers) изначально? Есть. Вторую строку делаем пустой, чуть ниже обьясню почему.

Ну тогда поехали, выполняем Get-запросы и наполняем наш CSV-файл:

 # Get Hypername

$Hyper = $env:computername

# Set filename

$filename1 =  'd:\' + $Hyper + '.csv'

# Set headers

$str0 = '"Host","Host RAM(GB)","Name","State","Notes","Dynamic Memory","Start RAM(GB)","Min RAM(GB)","Max RAM(GB)","Assign RAM(GB)","vhdtype","vhdformat","Size VHD(GB)","path","IP","MacAddress","SwitchName","OperationMode","AccessVlanId","Status"'

# Output headers

$str0 | Out-File $filename1 -Encoding UTF8

',,,,,,,,,,,,,,,,,,,' | Out-File $filename1 -Append -Force -Encoding UTF8


# Get HyperV host 

$str1 = Get-VMHost | Select @{Name="Host";Expression={$_.Name +'.'+ $_.FullyQualifiedDomainName}},@{label='Host RAM(GB)';expression={$_.MemoryCapacity/1gb -as [int]}}


# Get VMs about

$str2 = Get-VM | Select Name,State,notes


# Get VMs RAM

$str3 = Get-VM | Select-Object @{Name="DynamicMemory";Expression={$_.DynamicMemoryEnabled}},

@{label='StartRAM';expression={$_.MemoryStartup/1gb -as [int]}}, 

@{label='MinRAM';expression={$_.MemoryMinimum/1gb -as [int]}}, 

@{label='MaxRAM';expression={$_.MemoryMaximum/1gb -as [int]}}, 

@{label='AssignRAM';expression={$_.MemoryAssigned/1gb -as [int]}} `

| Sort Name  


# Get VMs disk

$str4 = Get-VM | Select-Object Name,VMId | Get-VHD | select vhdtype,vhdformat,path,@{label='Size';expression={$_.filesize/1gb -as [int]}} | Sort Name


# Get MVs NIC

$str5 = Get-VM | get-vmnetworkadapter | Select-Object @{Name="Name";Expression={$_.VMName}},@{Name="Status";Expression={$_.Status}},MacAddress,SwitchName,@{Name="IP";Expression={$_.IPAddresses}} | Sort Name 

$str6 = Get-VMNetworkAdapterVlan | Select OperationMode,AccessVlanId


# Output about

$str1 | Export-Csv $filename1 -Append -Force -Encoding UTF8


# Output all values

$i = 0

foreach ($item in $str6)

    $out = $str6[$i] | Select OperationMode,AccessVlanId, `

    @{Label="Name";Expression={($str2).Name[$i]}}, `

    @{Label="State";Expression={($str2).State[$i]}}, `

    @{Label="Notes";Expression={($str2).notes[$i]}}, `

    @{Label="vhdtype";Expression={($str4).vhdtype[$i]}}, `

    @{Label="vhdformat";Expression={($str4).vhdformat[$i]}},`

    @{Label="Size VHD(GB)";Expression={($str4).size[$i]}},`

    @{Label="Path";Expression={($str4).path[$i]}}, `

    @{Label="status";Expression={($str5).status[$i]}}, `

    @{Label="MacAddress";Expression={($str5).MacAddress[$i]}},`

    @{Label="IP";Expression={($str5).IP[$i]}},`

    @{Label="Switchname";Expression={($str5).Switchname[$i]}},`

    @{Label="Dynamic Memory";Expression={($str3).DynamicMemory[$i]}},`

    @{Label="Start RAM(GB)";Expression={($str3).StartRAM[$i]}},`

    @{Label="Min RAM(GB)";Expression={($str3).MinRAM[$i]}},`

    @{Label="Max RAM(GB)";Expression={($str3).MaxRAM[$i]}},`

    @{Label="Assign RAM(GB)";Expression={($str3).AssignRAM[$i]}}


    $out | Export-Csv $filename1 -Append -Force -Encoding UTF8

    $i++

}

Наш  CSV-файлик с именем  $filename1 уже готов. Далее выполним его экспорт в Excel. Вы будете правы если скажете что это можно легко сделать и руками. Но я зануда, и мне хочется последнюю операцию также сделать в Powershell. Также представим, что это все делается на HyperV-хосте где MS Excel не установлен, поэтому мы не работаем с СОМ-объектами. Мы используем модуль ImportExcel. Если у вас его нет, то разово добавьте его командой Install-Module ImportExcel -Scope CurrentUser.

Собственно сам экспорт выглядит просто:

$filename2 = $filename1.Replace(".csv",".xlsx")

Import-csv -Path $filename1 | Export-Excel -Path $filename2 -AutoSize -WorksheetName HyperV

Но мой $filename2 тоже не пустой изначально, он содержит шапку в две строки (помните, я резервировал для них место в самом начале) под которую ниже красиво импортиуются данные из CSV-файла.

Результат выглядит вот так:

Нравится? Мне так очень.

У предложенного скрипта остались незакрытые  вопросы: удаленное выполнение, и как быть если на некой виртуалке больше одного диска. Тут есть над чем подумать.
Успехов.

Слава Украине!

1 comment:

Anonymous said...

Как из самой ВМ узнать хост ее размещения:
Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters\' -Name HostName
Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters\' -Name PhysicalHostName

Post a Comment

А что вы думаете по этому поводу?

Версия на печать

Популярное