Создание графического интерфейса PowerShell (часть 12)
- Создание графического интерфейса PowerShell (часть 13)
На данный момент в этой серии статей мы создали сценарий, который позволяет пользователю выбрать виртуальную машину, а затем отображает информацию об этой виртуальной машине. Это все хорошо, но скрипт был бы гораздо полезнее, если бы его можно было использовать для чего-то другого, кроме пассивного отображения информации. В этой статье мы добавим в скрипт некоторый функционал.
Моя цель в этой статье — создать тумблер, который можно использовать для запуска или остановки виртуальной машины. Теперь в PowerShell нет такой вещи, как объект-переключатель, поэтому нам нужно проявить немного творчества. Мой план состоит в том, чтобы создать пару кнопок — одну для запуска виртуальной машины, другую для ее остановки. Затем я могу использовать простую логику для управления отображаемой кнопкой. Если выбранная виртуальная машина в данный момент работает, я покажу кнопку «Стоп». Если в настоящее время виртуальная машина остановлена, я покажу кнопку «Пуск».
Итак, первое, что я хочу сделать, это создать пару кнопок. Это очень просто сделать. Как вы помните, скрипт уже содержит четыре объекта-кнопки. Я собираюсь создать еще два. Вот пример блока кода:
# Define Button 5 — Эта кнопка будет использоваться для запуска виртуальной машины. $Button5 = New-Object System.Windows.Forms.Button $Button5.Location = New-Object System.Drawing.Size(140,260) $Button5.Size = New-Object System.Drawing.Size(150,30) $Button5. BackColor = "Зеленый" $Button5.ForeColor = "Белый" $Button5.Text = "Запустить виртуальную машину" $Button5.Add_Click({$Form.Close()})# Define Button 6 — Эта кнопка выключает виртуальную машину. $Button6 = New-Object System.Windows.Forms.Button $Button6.Location = New-Object System.Drawing.Size(320,260) $Button6.Size = New-Object System.Drawing.Size(150,30) $Button6. BackColor = "Красный" $Button6.ForeColor = "Белый" $Button6.Text = "Остановить ВМ" $Button6.Add_Click({$Form.Close()})Сейчас эти кнопки ничего не делают, но я собираюсь изменить это. Прежде чем я это сделаю, я хочу показать вам, как выглядят кнопки, если я добавлю их в форму. Обратите внимание, что на рисунке А я выделил кнопки красным и зеленым цветом, а текст белым. Мне не нужно было раскрашивать кнопки, но я пошел дальше и использовал цвет, чтобы вы могли видеть, как работают атрибуты BackColor и ForeColor. Вы можете увидеть, как эти атрибуты настроены в блоке кода выше.
Рисунок А
Я создал кнопку Start and Stop.
Итак, теперь, когда кнопки созданы, давайте создадим некоторую логику, которая будет отображать одну или другую кнопку, в зависимости от того, запущена виртуальная машина или нет. Это включает в себя выполнение трех вещей.
Во-первых, нам нужно создать пару операторов If, которые добавляют кнопки в интерфейс в зависимости от состояния виртуальной машины. Как вы помните, ранее мы создали функцию Display-VMInfo, которая отображает всю информацию о виртуальной машине, показанную на рисунке выше. Мы можем легко добавить два оператора if к этой функции. Вот часть функции, которая отображает содержимое экрана:
# Показать содержимое экрана $Form.Controls.Add($Label) $Form.Controls.Add($Label4) $Form.Controls.Add($Label5) $Form.Controls.Add($Label6) $Form.Controls.Add ($Label7) $Form.Controls.Add($Label3) $Form.Controls.Add($Button3) $Form.Controls.Add($Button4) If ($State -eq 'Off') { $Form.Controls. Добавить($Button5) } Если ($State -EQ 'Выполняется') { $Form.Controls.Add($Button6) } }Как вы можете видеть в блоке кода выше, если виртуальная машина выключена, будет отображаться кнопка 5 (Запустить виртуальную машину). Аналогичным образом, если виртуальная машина запущена, будет отображаться кнопка 6 (Остановить виртуальную машину).
Второе, что нам нужно сделать, это добавить код для удаления кнопок из интерфейса везде, где это уместно. Например, функция Return-MainScreen содержит код для удаления с экрана различных графических элементов. Нам нужно добавить строки для удаления Button5 и Button6. Вы можете увидеть, как выглядит этот код ниже:
# ---------- Действия при нажатии кнопки ------
# Определить кнопку возврата Нажмите Функция Function Return-MainScreen {$Form.Controls.Remove($Label) $Form.Controls.Remove($Label3) $Form.Controls.Remove($Label4) $Form.Controls.Remove($Label5) $Form.Controls.Remove($Label6) $Form.Controls.Remove($Label7) $Form.Controls.Remove($Button3) $Form.Controls.Remove($Button4) $Form.Controls.Remove($Button5) $Form.Controls.Remove($Button6) $Form.Refresh() Display-MainScreen }
Наконец, нам, вероятно, следует изменить расположение кнопки 6, чтобы кнопка отображалась в том же месте на экране, что и кнопка 5. Помните, что две кнопки никогда не будут отображаться на экране одновременно. Вместо этого цель состоит в том, чтобы создать иллюзию тумблера, который мы можем использовать для включения или выключения виртуальной машины. Вот как должна выглядеть команда определения местоположения для кнопки 6:
$Button6.Location = Новый объект System.Drawing.Size(140 260)
Итак, теперь давайте посмотрим, как работает скрипт. Если вы посмотрите на рисунок B, вы увидите, что виртуальная машина в настоящее время выключена, а в графическом интерфейсе есть возможность запустить виртуальную машину.
Рисунок Б
Графический интерфейс предоставляет возможность запуска виртуальной машины.
Аналогичным образом, на рис. C показан пример работающей виртуальной машины. Поскольку виртуальная машина в настоящее время включена, есть кнопка, которую мы можем использовать, чтобы остановить виртуальную машину.
Рисунок С
Графический интерфейс предоставляет возможность остановить работающую виртуальную машину.
В нынешнем виде кнопки на самом деле ничего не делают. Нам нужно изменить действие кнопки Start и Stop, чтобы она указывала на функцию, которая может изменить состояние виртуальной машины. Есть несколько разных способов справиться с этим. Мы могли бы создать одну функцию, которая повторно проверяет состояние виртуальной машины, а затем использует операторы If для запуска или остановки виртуальной машины. Код, используемый для этого, будет очень похож на код, используемый для отображения кнопок Start и Stop.
Другой, немного более простой подход — создать две разные функции: одну для запуска виртуальной машины и одну для ее остановки. Таким образом, каждая из двух кнопок вызывает очень простую специальную функцию.
Самый простой способ — просто встроить командлеты Start-VM и Stop-VM непосредственно в действия нажатия кнопки. Для этого необходимо внести одно изменение в функцию. Прямо сейчас функция Display-VMInfo содержит следующую строку кода, которая присваивает имя виртуальной машины переменной с именем $Name:
$Name = $SelectedVM.VMName
Нам нужно сделать $Name глобальной переменной, чтобы ее можно было распознать вне функции. Помните, что действие по нажатию кнопки выхода определяется в основном теле скрипта, где $Name в настоящее время не распознано. Мы можем изменить $Name на глобальную переменную, изменив назначение переменной, чтобы оно выглядело следующим образом:
$Global:Name = $SelectedVM.VMName
Теперь мы можем установить действия по нажатию кнопки:
$Button5.Add_Click({Start-VM $Name})А также
$Button6.Add_Click({Stop-VM $Name})Эта техника работает довольно хорошо, но она не совсем идеальна, по крайней мере, не так, как написано. В настоящее время нажатие кнопки «Запустить виртуальную машину» действительно запускает виртуальную машину, но отображение не обновляется, чтобы отразить новый статус. Нажатие Stop-VM приводит к тому, что окно PowerShell останавливается и ждет подтверждения перед завершением работы виртуальной машины. Следовательно, процесс выключения не является полностью автоматизированным. Итак, вот как мы решаем эти проблемы.
Мы можем решить проблему отключения, добавив параметр -Force к команде Stop-VM. Затем мы можем решить проблему обновления экрана, добавив символ вертикальной черты к обоим действиям щелчка, а затем вызвав функцию Display-VMInfo. При этом обязательно передайте в функцию переменную $Name. Вам также нужно будет добавить в начало функции инструкции по удалению кнопок 5 и 6, чтобы кнопки отображались правильно.
Итак, вот как теперь выглядят действия по нажатию кнопки:
$Button5.Add_Click({Start-VM $Name | Display-VMInfo $Name})А также
$Button6.Add_Click({Stop-VM $Name -Force | Display-VMInfo $Name})Итак, с учетом сказанного, вот весь код:
#Загрузить сборки [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") | Out-Null $net = New-Object -ComObject Wscript.Network# Отображение основного экрана Function Display-MainScreen { $Form.Controls.Add($ListBox1) $Form.Controls.Add($Button1) $Form.Controls.Add($Button2) $Form.Controls.Add($Label2) }# ---------- Действия при нажатии кнопки ------
#Определить функцию нажатия кнопки возврата
Функция Return-MainScreen {$Form.Controls.Remove($Label) $Form.Controls.Remove($Label3) $Form.Controls.Remove($Label4) $Form.Controls.Remove($Label5) $Form.Controls.Remove($Label6) $Form.Controls.Remove($Label7) $Form.Controls.Remove($Button3) $Form.Controls.Remove($Button4) $Form.Controls.Remove($Button5) $Form.Controls.Remove($Button6) $Form.Refresh() Display-MainScreen }
#Определить функцию нажатия кнопки OK
Функция Display-VMInfo ($ ChosenItem) {#Очистить окно ($Button5) $Form.Controls.Remove($Button6) $Form.Refresh()
#Создать вывод
Add-Type -AssemblyName System.Windows.Forms
# Получить информацию о виртуальной машине
$SelectedVM = Get-VM $ChosenItem $Global:Name = $SelectedVM.VMName $State = $SelectedVM.State $RunTime = $SelectedVM.UpTime $Memory = $SelectedVM.MemoryAssigned $CPU = $SelectedVM.ProcessorCount
#Создать текст
$Label.Text = 'Имя виртуальной машины: ' + $Name $Label4.Text = 'Состояние ВМ: ' + $State $Label5.Text = 'Время работы ВМ: ' + $RunTime $Label6.Text = 'Назначенная память: ' + $Memory $Label7.Text = 'Назначенные виртуальные процессоры:' + $CPU
#Показать содержимое экрана
$Form.Controls.Add($Label) $Form.Controls.Add($Label4) $Form.Controls.Add($Label5) $Form.Controls.Add($Label6) $Form.Controls.Add($Label7) $Form.Controls.Add($Label3) $Form.Controls.Add($Button3) $Form.Controls.Add($Button4) If ($State -eq 'Off') { $Form.Controls.Add($Button5) ) } If ($State -EQ 'Выполняется') { $Form.Controls.Add($Button6) } }
#—— Определить все объекты GUI——-
# Define Label — это объект текстового поля, который будет отображать данные виртуальной машины.
$Label = Новый объект System.Windows.Forms.Label $Label.AutoSize = $False $Label.Location = новый объект System.Drawing.Size(50,50) $Label.Size = Новый объект System.Drawing. Размер (200,20) $Label.ForeColor = "Черный" $label.BackColor = "Белый"
# Define Label2 – текст «Пожалуйста, сделайте выбор»
$Label2 = Новый объект System.Windows.Forms.Label $Label2.AutoSize = $True $Label2.Location = новый объект System.Drawing.Size(20,50) $Label2.ForeColor = "DarkBlue" $Label2.Text = "Выберите виртуальную машину из списка."
# Определить Label3 — текст «Это выбранная вами виртуальная машина»
$Label3 = Новый объект System.Windows.Forms.Label $Label3.AutoSize = $True $Label3.Location = новый объект System.Drawing.Size(50,30) $Label3.ForeColor = "DarkBlue" $Label3.Text = "Выбранная вами виртуальная машина:"
# Define Label4 — метка «Это состояние виртуальной машины»
$Label4 = Новый объект System.Windows.Forms.Label $Label4.AutoSize = $False $Label4.Location = новый объект System.Drawing.Size(50,70) $Label4.Size = Новый объект System.Drawing. Размер (200,20) $Label4.ForeColor = "Черный" $Label4.BackColor = "Белый"
# Define Label5 — метка «Это состояние виртуальной машины»
$Label5 = Новый объект System.Windows.Forms.Label $Label5.AutoSize = $False $Label5.Location = новый объект System.Drawing.Size(50,90) $Label5.Size = Новый объект System.Drawing. Размер(200,20) $Label5.ForeColor = "Черный" $Label5.BackColor = "Белый"
# Define Label6 — метка «Это состояние виртуальной машины»
$Label6 = Новый объект System.Windows.Forms.Label $Label6.AutoSize = $False $Label6.Location = новый объект System.Drawing.Size(50,110) $Label6.Size = Новый объект System.Drawing.Size( 200,20) $Label6.ForeColor = "Черный" $Label6.BackColor = "Белый"
# Define Label7 — метка «Это состояние виртуальной машины»
$Label7 = Новый объект System.Windows.Forms.Label $Label7.AutoSize = $False $Label7.Location = новый объект System.Drawing.Size(50,130) $Label7.Size = Новый объект System.Drawing.Size( 200,20) $Label7.ForeColor = "Черный" $Label7.BackColor = "Белый"
# Define List Box — здесь будут отображаться виртуальные машины, которые можно выбрать
$ListBox1 = Новый объект System.Windows.Forms.ListBox $ListBox1.Location = Новый объект System.Drawing.Size(20,80) $ListBox1.Size = Новый объект System.Drawing.Size(260,20) $ ListBox1.Высота = 80
# Этот код заполняет поле списка именами виртуальных машин
$VirtualMachines = Get-VM ForEach ($VM в $VirtualMachines) { [void] $ListBox1.Items.Add($VM.Name) }# Define Button 1 – это кнопка OK на экране выбора.
$Button1 = новый объект System.Windows.Forms.Button $Button1.Location = новый объект System.Drawing.Size(20,170) $Button1.Size = новый объект System.Drawing.Size(70,30) $Button1. BackColor = "LightGray" $Button1.Text = "ОК" $Button1.Add_Click({$ChosenItem=$ListBox1.SelectedItem;Display-VMInfo $ChosenItem})# Кнопка «Определить 2» — это кнопка «Отмена» на экране выбора.
$Button2 = New-Object System.Windows.Forms.Button $Button2.Location = New-Object System.Drawing.Size(120,170) $Button2.Size = New-Object System.Drawing.Size(70,30) $Button2. BackColor = "LightGray" $Button2.Text = "Отмена" $Button2.Add_Click({$Form.Close()})# Define Button 3 — это кнопка возврата на главный экран.
$Button3 = New-Object System.Windows.Forms.Button $Button3.Location = New-Object System.Drawing.Size(50,220) $Button3.Size = New-Object System.Drawing.Size(70,30) $Button3. BackColor = "LightGray" $Button3.Text = "Возврат" $Button3.Add_Click({Return-MainScreen})# Define Button 4 – Эта кнопка пока ничего не делает, но мы будем использовать ее в конечном итоге.
$Button4 = Новый объект System.Windows.Forms.Button $Button4.Location = Новый объект System.Drawing.Size(140,220) $Button4.Size = Новый объект System.Drawing.Size(150,30) $Button4. BackColor = "LightGray" $Button4.Text = "Зарезервировано для будущего использования" $Button4.Add_Click({$Form.Close()})# Define Button 5 — эта кнопка будет использоваться для запуска виртуальной машины.
$Button5 = New-Object System.Windows.Forms.Button $Button5.Location = New-Object System.Drawing.Size(140,260) $Button5.Size = New-Object System.Drawing.Size(150,30) $Button5. BackColor = "Зеленый" $Button5.ForeColor = "Белый" $Button5.Text = "Запустить виртуальную машину" $Button5.Add_Click({Start-VM $Name | Display-VMInfo $Name})# Define Button 6 — Эта кнопка выключает виртуальную машину.
$Button6 = New-Object System.Windows.Forms.Button $Button6.Location = New-Object System.Drawing.Size(140,260) $Button6.Size = New-Object System.Drawing.Size(150,30) $Button6. BackColor = "Красный" $Button6.ForeColor = "Белый" $Button6.Text = "Остановить ВМ" $Button6.Add_Click({Stop-VM $Name -Force | Display-VMInfo $Name})# -------- Это конец раздела определения объекта ------
# ——Нарисуйте пустую форму—-
$Form = New-Object System.Windows.Forms.Form $Form.width = 525 $Form.height = 350 $Form.BackColor = "голубой" $Form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::Fixed3D $Form.Text = "Виртуальные машины Hyper-V" $Form.maximumsize = New-Object System.Drawing.Size(525 350) $Form.startposition = "centerscreen" $Form.KeyPreview = $True $Form.Add_KeyDown({if ($_.KeyCode -eq "Enter") {}}) $Form.Add_KeyDown({if ($_.KeyCode -eq "Escape") {$Form.Close()}})#—-Заполнить форму—-
Дисплей-MainScreen $Form.Add_Shown({$Form.Activate()}) $Form.ShowDialog()Вывод
В этой статье я показал вам, как добавить кнопку, которая переключает состояние виртуальной машины. В следующей статье этой серии я хочу показать вам, как использовать скрипт для изменения конфигурации памяти виртуальной машины.