Изменение размера виртуального жесткого диска — операция не то чтобы очень, но довольно часто встречающаяся. И если увеличить размер виртуального диска в Hyper-V достаточно просто (для этого достаточно лишь иметь необходимое количество свободного места), то уменьшение всегда было связано с некоторыми трудностями.
В ранних версиях Hyper-V подобный функционал вообще отсутствовал и для урезания VHD приходилось использовать всякие левые утилиты типа VHD Resizer. Начиная с Windows Server 2012 появилась штатная возможность урезания виртуальных дисков, однако воспользоваться ей по прежнему не очень просто.
Дело в том, что для уменьшения размера VHD необходимо наличие внутри него свободного неразмеченного пространства. В противном случае опция Урезать (Shrink) недоступна отсутствует в графическом интерфейсе, а PowerShell при попытке урезать диск с помощью Resize-VHD выдаст ошибку.
Таким образом, перед урезанием VHD необходимо предварительно урезать логические разделы внутри виртуальной машины. Сделать это можно несколькими различными способами, я опишу наиболее универсальный. Все издевательства 🙂 над диском будут производиться из родительской системы с помощью PowerShell.
В качестве примера возьмем виртуальную машину SRV01 с виртуальным диском 40Гб и урежем ее до 30Гб. Для этого сначала поместим ВМ в переменную и выведем свойства ее виртуального диска:
$vm = Get-VM -Name SRV01
Get-VHD -VMId $vm.VMId
В свойствах VHD нас интересуют такие параметры, как:
• FileSize — текущий размер файла VHD. Показывает реальный объем дискового пространства, который занимает виртуальный диск.
• Size — текущий размер виртуального диска. В случае с динамическим VHD показывает максимальный размер, до которого он может вырасти;
• MinimumSize — минимальный размер виртуального диска, или минимально возможный размер, до которого можно урезать VHD.
Как видно из примера, мы имеем динамически расширяемый VHD размером 40Гб, из которых на данный момент занято чуть больше 20Гб. Свободное место имеется, однако текущий и минимальный размеры практически одинаковы, поэтому урезать диск не получится.
Для последующих манипуляций ВМ должна быть выключена, поэтому проверяем ее состояние и, если надо, выключаем:
$vm.State
$vm | Stop-VM -Force
Затем подмонтируем VHD к родительской системе и выведем свойства получившегося диска:
Mount-VHD -Path $vm.HardDrives.Path -Passthru | Get-Disk
Берем полученный номер диска и выводим все имеющиеся на нем разделы:
Get-Partition -DiskNumber 3
Если на диске вдруг оказалось несколько мелких непонятных разделов, не стоит их трогать. Они содержат важную информацию, необходимую системе для загрузки и восстановления. Нам нужен раздел, имеющий букву диска. Урежем его до 30Гб и проверим, что получилось:
Resize-Partition -DriveLetter E -Size 30GB
Get-Partition -DriveLetter E
Отмонтируем VHD от родительской системы:
Dismount-VHD -Path $vm.HardDrives.Path
И урезаем его до минимально-возможного значения:
Resize-VHD -Path $vm.HardDrives.Path -ToMinimumSize
Как видите, все получилось, виртуальный диск урезан до 30Гб. Остается только запустить ВМ.
В заключение добавлю, что все описанное актуально только для Windows Server 2012 и выше, и только для ВМ с Windows. И еще, хотя данная процедура довольно безопасна, все же стоит предварительно сделать резервную копию.
Resize-VHD -VMId $vm.HardDrives.Path -ToMinimumSize исправьте пожалуйста на Resize-VHD -Path $vm.HardDrives.Path -ToMinimumSize