Недавно я обнаружил расхождение в данных о занимаемом виртуальными машинами дисковом пространстве, отображаемыми в консоли System Center Virtual Machine Manager и полученными при помощи Get-SCVirtualMachine и решил выяснить, в чем дело. Данные о занимаемом дисковом пространстве я получал при помощи распространенного командлета Get-SCVirtualMachine. Для этого я использовал цикл, в котором перебирал все виртуальные машины и накапливал размер их дисков в переменной:
$totalhdd = 0 $vms = Get-SCVirtualMachine #| where {$_.Name -eq "VM Name"} # Для отладки foreach ($vm in $vms) { $totalhdd += ($vm.VirtualHardDisks.Size -as [double]) / 1TB} }
Похожие конструкции многократно тиражируются на форумах technet и во всяких блогах, поэтому сомнений в их корректности у меня не возникало. После обнаружения расхождений я добавил в цикл вывод отладочной информации: $vm.VirtualHardDisks.Size для каждой ВМ и её имя. Вывод измененного скрипта показал, что у некоторых ВМ объём был равен 0. Я был уверен, что $vm.VirtualHardDisks.Size показывает сумму, но это оказалось не так — команда возвращала два числа (для двух vhd). Очевидно, powershell не смог поделить массив на 1TB, поэтому и отдавал 0:
PS D:\Scripts\IT_git> $vm.VirtualHardDisks.Size 3547332608 4194304 PS D:\Scripts\IT_git> ($vm.VirtualHardDisks.Size -as [double]) / 1TB 0
Даже не знаю в этом случае, сказать спасибо гибкости повершелла за то, что не ERROR, или сказать ему антиспасибо за подобную медвежью услугу. Очень много ошибок прощает.
Тогда я решил перебирать все диски циклом и изменил первоначальную конструкцию на чуть более сложную, но при этом и более корректную:
foreach ($vm in $vms) { $vhds = $vm.VirtualHardDisks foreach ($vhd in $vhds) { $totalhdd += ($vhd.Size -as [double]) / 1TB} }
Отлично! Теперь ВМ с двумя или более виртуальными дисками считались корректно, НО! Сумма по всем виртуалкам всё равно не совпадала, хоть и приблизилась к показаниям консоли.
Погонял свой скрипт и так, и эдак. Посмотрел, посравнивал и увидел, что по некоторым ВМ сумма совпадает до копейки, а по некоторым наблюдается значительное расхождение. Полез в свойства, а там… снапшоты! Их-то мы и не посчитали.
Далее опять гугл, опять сомнительные скрипты вплоть до очень экзотических методов с поиском файлов по маске.
Пришлось писать самому. Сначала я пробовал выбирать все диски при помощи Get-SCVirtualHardDisk не прибегая к перебору виртуальных машин, однако мне удалось перечислять лишь те диски, которые я получал при помощи $vm.VirtualHardDisks. Поэтому пришлось копнуть чуть глубже. У виртуальной машины есть свойство VMCheckpoints, в котором перечислены все контрольные точки. Из этого свойства можно получить, собственно, объект VMSnapshot (я так и не понял чем Snapshot отличается от Checkpoint в терминах SCVMM). У этого объекта также есть свойство VirtualDiskDrives, но у него почему-то нет свойства Size, поэтому пришлось вставить костыль: из VirtualDiskDrives мы берём свойство VirtualHardDiskID и с помощью этого ID делаем Get-SCVirtualHardDisk:
... # Snapshots search foreach ($vmc in $vm.VMCheckpoints) { foreach ($vdd in $vmc.VirtualDiskDrives) { $vhd = Get-SCVirtualHardDisk -ID $vdd.VirtualHardDiskID $snapshotshdd += ($vhd.Size -as [double]) / 1TB } } ...
После этого небольшое расхождение всё-таки осталось, и коллега подсказал мне посчитать также служебные файлы .bin и .vsv, в которых хранится служебная информация навроде дампа оперативной памяти. В очередной раз просматривая список доступных параметров виртуальной машины я наткнулся на… $vm.TotalSize. Кто бы мог подумать, что всю работу за меня уже сделали и нужно всего лишь просуммировать этот параметр для всех виртуальных машин!
Вот так через тернии, костыли и грабли я нашёл действительно красивое решение:
$totalhdd = 0 $vms = Get-SCVirtualMachine #| where {$_.Name -eq "VM Name"} # Для отладки foreach ($vm in $vms) { $totalsize += ($vm.TotalSize -as [double]) / 1TB }
Было так смешно, что решил не удалять из скрипта данные о снапшотах, полученные таким трудом.
Залил вот сюда gallery.technet.microsoft.com/scriptcenter/Script-to-calculate-the-36a9314f
ссылка на оригинал статьи http://habrahabr.ru/post/266097/
Добавить комментарий