Hyper-V: управління віртуальними дисками за допомогою PowerShell.
Hyper-V використовує 2 основних типи віртуальних дисків (VHD) - динамічні і фіксованого розміру. З фіксованими дисками все просто - відразу створюється VHD файл потрібного розміру і в процесі роботи він не змінюється. Розмір же динамічного VHD безпосередньо залежить від місця, займаного на ньому віртуальною машиною (ВМ) і може змінюватися як у велику так і в меншу сторону.Динамічні диски дозволяють заощадити дисковий простір, але мають ряд особливостей.
Динамічний диск має 2 параметри - поточний і максимальний розмір диска.
Поточний розмір визначає розмір VHD файлу і теоретично має дорівнювати місця, зайнятого на диску віртуальною машиною.Однак досить часто при видаленні інформації в ВМ обсяг займаного місця зменшується, а розмір VHD файлу при цьому залишається тим самим. Для боротьби з цим явищем в Hyper-V є спеціальна процедура стиснення (compact), яка видаляє з VHD файлу порожнє місце, що залишилося після видалення файлів.
Процедура стиснення досить проста, однак з урахуванням того, що всі маніпуляції з VHD можна проводити тільки при зупиненій ВМ, виглядає досить громіздко:
Один раз все ці операції виконати нескладно, але при наявності великої кількості ВМ варто задуматися про написання скрипта, який буде робити це за вас. Тому звернемося до PowerShell, в якому для Hyper-V є спеціальний модуль.
Спочатку імпортуємо модуль:
Import-Module -Name HyperVТепер напишемо функцію compress, яка буде зупиняти ВМ, стискати VHD і знову запускати ВМ, попутно роблячи запис про проведені маніпуляціях в файл. Аргументи на функцію передаються за допомогою стандартної змінної $ args:
function compress {Invoke-VMShutdown -VM "$ args" -force Compress-VHD -VHDPaths "D: \ Hyper-V \ VHD \ $ args.vhd "-force -wait Start-VM -VM" $ args "-force -wait [string] $ date +" $ args.vhd compressed ">> C: \ PSHiper-V \ log.txt}На той випадок, якщо стиск не потрібно, використовуємо функцію notcompress, яка просто зробить запис про це в файл:
function notcompress {[string] $ date + "$ args.vhd not compressed" >> C: \ PSHiper-V \ log.txt}Вибираємо всі запущені віртуальні машини і за допомогою командлета Get-VMKVP отримуємо їх параметри, з яких відбираємо FQDN і ім'я віртуальної машини.Результати помістимо в змінну $ names:
$ names = Get-VM -Running | Get-VMKVP | select FullyQualifiedDomainName, VMElementNameТепер нам треба перевірити, чи потребують віртуальні диски в стисненні. Створюємо цикл foreach, в якому спочатку за допомогою WMI визначаємо обсяг, реально займаний кожною віртуальною машиною, потім порівнюємо його з розміром VHD файлу.Визначаємо різницю і поміщаємо її в змінну $ diff:
foreach ($ name in $ names) {$ disk = Get-WmiObject win32_logicaldisk -ComputerName $ name.FullyQualifiedDomainName `-filter" drivetype = 3 "$ disksize = $ disk. size $ freespace = $ disk.freespace $ vdhsize = (Get-VHDInfo ( "D: \ Hyper-V \ VHD \" + $ name.VMElementName + ". vhd")). filesize $ diff = ($ vdhsize - ($ disksize - $ freespace))/1GB}Якщо різниця більше 10 Гб, то стискаємо віртуальний диск, інакше просто робимо запис в файл:
if ($ diff -ge 10) {compress $ name.VMElementName} else {notcompress $ name.VMElementName}Тепер залишається тільки об'єднати всі частини, помістити їх в скрипт і запустити його, або додати скрипт в планувальник завдань для запуску за розкладом.
.