Заметки о Windows и других программных продуктах Microsoft...

Hyper-V: управление виртуальными дисками с помощью PowerShell

Hyper-V: управление виртуальными дисками с помощью PowerShell

Hyper-V использует 2 основных типа виртуальных дисков (VHD) — динамические и фиксированного размера. С фиксированными дисками все просто — сразу создается VHD файл нужного размера и в процессе работы он не изменяется. Размер же динамического VHD напрямую зависит от места, занимаемого на нем виртуальной машиной (ВМ) и может меняться как в большую так и в меньшую сторону. Динамические диски позволяют сэкономить дисковое пространство, но имеют ряд особенностей.

Динамический диск имеет 2 параметра — текущий и максимальный размер диска.

параметры VHD

 

Текущий размер определяет размер VHD файла и теоретически должен быть равен месту, занятому на диске виртуальной машиной. Однако довольно часто при удалении информации в ВМ объем занимаемого места уменьшается, а размер VHD файла при этом остается прежним. Для борьбы с этим явлением в Hyper-V есть специальная процедура сжатия (compact), которая удаляет из VHD файла пустое место, оставшееся после удаления файлов.

операции с VHD в Hyper-V

 

Процедура сжатия достаточно проста, однако с учетом того, что все манипуляции с VHD можно проводить только при остановленной ВМ, выглядит довольно громоздко:

  1. Подключиться к ВМ и проверить занимаемое ей дисковое пространство;
  2. Посмотреть размер VHD и сравнить с п. 1;
  3. Остановить ВМ;
  4. Зайти в Hyper-V Manager и провести процедуру сжатия;
  5. Включить ВМ.

Один раз все эти операции проделать несложно, но при наличии большого количества ВМ стоит задуматься о написании скрипта, который будет делать это за вас. Поэтому обратимся к 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

}

Теперь остается только объединить все части, поместить их в скрипт и запустить его, или добавить скрипт в планировщик заданий для запуска по расписанию.

 
 
Комментарии
Игорь

В Windows Server 2012 и Windows Server 2012 R2 в PowerShell 4.0 появился командлет Resize-VHD, позволяющий изменять размер VHD-, VHDX-дисков и сжимать их до минимума с помощью параметра -ToMinimumSize.

Подробнее можно посмотреть на technet’е.
http://technet.microsoft.com/en-us/library/hh848535.aspx