четверг, 25 января 2018 г.

PowerCLI. Использование Get-View. Часть 2.

Во второй части я рассмотрю различные варианты совместного использования Get-View и Get-VM, приведу пример как можно реализовать выполнения одной и тоже задачи с помощью этих командлетов, затрону вопросы их производительности.

Командлеты Get-View и Get-VM совершенно разные, т.е. их выходные данные несовместимы между собой. А имеются ли способы как-то "подружить" их? Ответ: Да, есть! Рассмотрим их.

Если мы выполним
$VM = get-view –viewtype VirtualMachine –filter @{“Name”=”DHCP”}
$VM | Start-VM
То получим ошибку.
Но если используем Get-VIObjectByVIView, 
$VM | Get-VIObjectByVIView | Start-VM
Команда успешно выполнится.




Примечание: Get-VIObjectByVIView - это командлет, который конвертирует  vSphere View object в VIObject

Теперь давайте узнаем включена или нет наша ВМ
$VM.Runtime.PowerState
Команда выдаст результат poweredOff.
Но не спешите проверять что пошло не так. 
Дело в том, что "Runtime.PowerState" не проверяет статус ВМ, а извлекает соответствующие данные из конвейера команды get-view –viewtype VirtualMachine –filter @{“Name”=”DHCP”}, которая выполнялась до включения ВМ...
Значит нам нужно обновить данные
$VM.UpdateViewData()
После чего получаем актуальный статус ВМ.



Следующий вопрос, на котором я хочу остановиться, это ExtensionData.
Выполним командлеты из прошлой статьи:
$VM.Summary
$VM.Summary.Guest
Затем вместо Get-View присвоим нашей переменной результат выполнения команды Get-VM 
$VM = Get-VM -Name DHCP
Снова выполним 
$VM.Summary
Упс...
Тогда просто добавим ExtensionData
$VM.ExtensionData.Summary
$VM.ExtensionData.Summary.Guest
Результат выполнения этих шести команд

Нетрудно заметить, что у соответствующих команд вывод идентичен. 
И это не удивительно, ведь оба этих командлета используют VMware vSphere application programming interface (API). 

Если говорить о времени, то при использовании Get-VM мы имеем 9 мс, а извлечение данных из результата выполнения get-view - 8 миллисекунд. 



Везде я использую переменную VM, потому что так проще. Но если если нужно выполнить одну или две команды, то быстрее будет передавать данные непосредственно 
(Get-VM DHCP).Extensiondata
(Get-View -viewtype virtualmachine -filter @{'name'='DHCP'}).guest
И продолжая тему альтернативных вариантов записи команлдетов:

$vm = Get-VM DHCP
Get-View $vm
(Get-View $vm).Guest
$vm = Get-VM DHCP | Get-view
А теперь давайте попробуем узнать в каких не выключенных ВМ, какой статус vmware tools, а также стоит галочка Сheck and upgrade vmware tools before each power on в свойствах ВМ или нет? Про данную политику обновления можно почитать в моей прошлой статье Использование PowerCLI для установки "Сheck and upgrade vmware tools before each power on"

Вспомним, где содержится информация о vmware tools

(Get-View -viewtype virtualmachine -filter @{'name'='DHCP'}).guest
(Get-View -viewtype virtualmachine -filter @{'name'='DHCP'}).config.tools

Но не забываем, что есть еще одно условие - не выключенные ВМ.

Эту информацию проще всего получить через команду 
Get-VM -Name DHCP
Значит для вывода всех данных нам нужно объединить вывод Get-VM и Get-View. Но можно ли их объединить? Вполне. Сначала выполняем get-vm с фильтром  where {$_.powerstate -ne "PoweredOff" }
Ключ -ne означает "не равен", т.е. статус ВМ "не выключен"
Затем используем ForEach-Object.

Примечание:
Командлет ForEach-Object выполняет операцию для каждого из последовательности объектов ввода. Объекты ввода можно передать командлету по конвейеру или указать в параметре InputObject.
Выполняемая операция описывается в блоке скрипта, который передается командлету в качестве значения параметра Process. Блок скрипта может содержать любой скрипт Windows PowerShell.
В пределах блока скрипта текущий объект ввода представлен переменной $_.

Таким образом мы для каждого из переданных объектов ($_), т.е. для всех не выключенных ВМ выполняем командлет Get-View, после чего извлекаем значения полей config.tools.ToolsUpgradePolicy и Guest.ToolsVersion Status.
get-vm | where {$_.powerstate -ne "PoweredOff" } | ForEach-Object { get-view $_ } | select Name, @{ Name="ToolsUpgrade"; Expression={$_.config.tools.ToolsUpgradePolicy}}, @{ Name="ToolStatus"; Expression={$_.Guest.ToolsVersionStatus}} | Format-Table -AutoSize
Чтобы все данные помещались в столбцы используем Format-Table -AutoSize


Как видим, данная составная конструкция вполне работоспособна.
Изучив ее, мы можем использовать совместно командлеты Get-Vm и Get-View, объединять в одном выводе данные из разных уровней вложенности. 

От теоретических, так сказать учебных вопросов, перейдем к более практическим. И сразу озаботимся вопросом: а можно ли сделать тоже самое только используя Get-VM?
Можно, и этот командлет выглядит так:
get-vm | where {$_.powerstate -ne "PoweredOff" } |  Select Name,@{Name="ToolsUpgrade";Expression={$_.ExtensionData.config.tools.ToolsUpgradePolicy}},@{Name="ToolsStatus";Expression={$_.ExtensionData.Guest.ToolsVersionStatus}} | Format-Table -AutoSize

Теперь, нам конечно же интересно узнать, а за сколько выполняются эти команды?

Measure-Command -Expression {get-vm | where {$_.powerstate -ne "PoweredOff" } | ForEach-Object { get-view $_ } | select Name, @{ Name="ToolsUpgrade"; Expression={$_.config.tools.ToolsUpgradePolicy}}, @{ Name="ToolStatus"; Expression={$_.Guest.ToolsVersionStatus}} | Format-Table -AutoSize}

Measure-Command -Expression {get-vm | where {$_.powerstate -ne "PoweredOff" } |  Select Name,@{Name="Tools Upgrade";Expression={$_.ExtensionData.config.tools.ToolsUpgradePolicy}},@{Name="ToolsStatus";Expression={$_.ExtensionData.Guest.ToolsVersionStatus}} | Format-Table -AutoSize}

960 мс в случае с Get-view против 1 сек. 184 мс у Get-VM.
Но Get-view не "чистый". 
И наш следующий вопрос: а можно ли реализовать команду только на Get-view?
У Get-view довольно сложно использовать в выражениях фильтры, например "не равно", т.е. -ne, но если допустимо использовать фильтр по соответствию, т.е. например "все включенные ВМ", то команда будет выглядеть следующим образом

Get-View -ViewType VirtualMachine -Filter @{"Runtime.PowerState"="poweredOn"} | select Name, @{ Name="ToolsUpgrade"; Expression={$_.config.tools.ToolsUpgradePolicy}}, @{ Name="ToolStatus"; Expression={$_.Guest.ToolsVersionStatus}} | Format-Table -AutoSize
Теперь мы можем сравнить за сколько выполняются "чистый" Get-View и Get-VM
Measure-Command -Expression {Get-View -ViewType VirtualMachine -Filter @{"Runtime.PowerState"="poweredOn"} | select Name, @{ Name="ToolsUpgrade"; Expression={$_.config.tools.ToolsUpgradePolicy}}, @{ Name="ToolStatus"; Expression={$_.Guest.ToolsVersionStatus}} | Format-Table -AutoSize}
Measure-Command -Expression {get-vm | where {$_.powerstate -eq "PoweredOn" } |  Select Name,@{Name="ToolsUpgrade";Expression={$_.ExtensionData.config.tools.ToolsUpgradePolicy}},@{Name="ToolsStatus";Expression={$_.ExtensionData.Guest.ToolsVersionStatus}} | Format-Table -AutoSize}


На этот раз 529 мс в случае с Get-View против 1 сек. 279 мс у Get-VM.
Разница - больше чем в два раз. 
Если мы имеем большую инфраструктуру, то разница в выполнении весьма существенна. 

В связи с чем в целях ускорения выполнения скриптов рекомендуется по возможности использовать get-view.

Комментариев нет:

Отправить комментарий