Использование PowerShell для поиска виртуальной машины Hyper-V
Hyper-V — это динамическая среда, и виртуальные машины могут легко перемещаться с одного хоста на другой. Однако иногда вам может понадобиться знать, на каком хосте Hyper-V работает конкретная виртуальная машина, чтобы вы могли выполнять какую-либо задачу управления в отношении виртуальной машины. PowerShell позволяет относительно легко найти одну виртуальную машину среди большого количества хостов Hyper-V.
Поиск виртуальной машины Hyper-V: быстрый и грязный метод
Существует несколько различных способов выполнения работы, и метод, который вам нужно будет использовать, зависит от того, сколько у вас хостов и как часто вам нужно находить конкретную виртуальную машину. Если вы просто ищете быстрый и грязный способ найти конкретную виртуальную машину, вы можете использовать команду, подобную этой:
Get-VM -ComputerName,, -VMName -ErrorAction SilentlyContinue | Select-Object VMName, ComputerName
Если бы вы запускали эту команду в реальной жизни, вы бы заменили <Host1>, <Host2> и <Host3> именами ваших хостов Hyper-V (IP-адреса работают только при очень специфических обстоятельствах). Вы также можете заменить <имя виртуальной машины> именем виртуальной машины, которую вы ищете.
Когда вы запускаете эту команду, она проверяет каждый из ваших хостов Hyper-V, чтобы узнать, существует ли указанная виртуальная машина. Если виртуальная машина не существует на определенном хосте, PowerShell скрывает сообщение об ошибке, которое обычно отображается. Если виртуальная машина существует, PowerShell отображает имя виртуальной машины и имя хоста, на котором находится виртуальная машина. Вы можете увидеть пример этого на рисунке ниже.
Как вы можете видеть на рисунке, эта техника работает очень хорошо. Тем не менее, у этого метода есть несколько недостатков. Прежде всего, команда требует, чтобы вы вводили имена или IP-адреса ваших хостов Hyper-V. Это, вероятно, не имеет большого значения, если у вас всего несколько хостов, но если у вас более трех или четырех хостов, это может быстро стать утомительной рутиной.
Другим недостатком этого подхода является то, что команда дает нам необходимую информацию, но ничего с ней не делает. Этот подход был бы намного полезнее, если бы имя виртуальной машины и имя хоста записывались в переменные, чтобы мы могли запускать дополнительные команды. Например, может быть, мы хотим установить удаленный сеанс с хостом или инициировать динамическую миграцию или что-то в этом роде. Все это можно было бы автоматизировать, если бы мы могли поместить имя виртуальной машины и имя ее хоста в переменные.
Использование текстового файла
Один из способов сэкономить время на наборе текста — создать текстовый файл, содержащий имена ваших хостов Hyper-V. Затем вы можете указать PowerShell прочитать имена из этого файла, чтобы вам не приходилось вводить их каждый раз.
Для целей этой статьи я создал файл с именем C:ScriptsHostList.txt. В этом файле указано имя или IP-адрес каждого из моих хостов Hyper-V. Каждый хост отображается на отдельной строке. Затем я написал короткий сценарий, который делает то же самое, что и команда, показанная ранее, за исключением того, что он извлекает имена хостов из моего текстового файла. Вот как выглядит скрипт:
$HyperVHosts = Get-Content 'c:scriptsHostList.txt' ForEach ($IndividualHost в $HyperVHosts) { Get-VM -ComputerName $IndividualHost -VMName <имя виртуальной машины> -ErrorAction SilentlyContinue | Select-Object VMName, ComputerName }
Первая строка кода указывает PowerShell прочитать содержимое файла в переменную с именем $HyperVHosts. Затем я создал цикл, который проверяет каждый хост, указанный в текстовом файле. На хост, который в данный момент проверяется, ссылается переменная $IndividalHost. Вы можете увидеть мой код и вывод скрипта на следующем рисунке.
Использование переменных
До сих пор мы решили проблему ввода длинного списка хостов, но нам все еще нужно поместить имя виртуальной машины и имя ее текущего хоста в переменные, которые мы можем использовать для других целей. Если вы посмотрите на предыдущий снимок экрана, вы увидите, что я жестко запрограммировал имя виртуальной машины, которую ищу, но было бы так же просто принять имя виртуальной машины в качестве входных данных.
Я добился этого, добавив одну строку кода в начало скрипта:
$VM = Read-Host «Пожалуйста, введите имя виртуальной машины, которую вы ищете».
Эта строка предлагает пользователю ввести имя виртуальной машины, а затем записывает это имя в переменную с именем $VM. Затем я сослался на эту переменную в команде Get-VM. Вы можете увидеть скрипт и его вывод на рисунке ниже.
Итак, теперь у нас есть переменная, содержащая имя виртуальной машины. Последнее, что нам нужно сделать, это записать имя хоста виртуальной машины в переменную. Вот как это делается:
$VM = Read-Host "Пожалуйста, введите имя виртуальной машины, которую вы ищете." $HyperVHosts = Get-Content 'c:scriptsHostList.txt' ForEach ($IndividualHost в $HyperVHosts) { Get-VM -ComputerName $IndividualHost -VMName $VM -ErrorAction SilentlyContinue | Tee-Object - Переменная температура | Out-Null $VMHost = $Temp.ComputerName } Write-Host "Виртуальная машина " $VM " размещена на " $VMHost
Как видите, я значительно изменил команду Get-VM. Сначала команда Get-VM пытается получить указанную виртуальную машину с хост-сервера, который в данный момент проверяется. Ошибки также подавляются, как и раньше. Однако теперь я использую команду Tee-Object для записи вывода в переменную. Затем я добавил командлет Out-Null, чтобы результаты командлета Get-VM не отображались на экране.
Командлет Tee-Object создает переменную с именем $Temp, содержащую содержимое командлета Get-VM. В том же цикле я также создаю переменную с именем $VMHost. Этой переменной присваивается содержимое $Temp.ComputerName, которое в какой-то момент будет хранить имя хоста, на котором работает указанная ВМ. Вы можете увидеть скрипт и его вывод на рисунке ниже.
Окончательная проверка
Сценарий, который я создал, достаточно прост, поэтому у вас не должно возникнуть особых проблем с ним. Однако, если вы столкнетесь с проблемами, вам следует проверить три вещи.
1. Убедитесь, что в текстовом файле списка хостов хосты указаны по имени, а не по IP-адресу.
2. Убедитесь, что компьютер, на котором работает PowerShell, может разрешать имена хостов.
3. Убедитесь, что на всех хостах (и машине, на которой выполняется сценарий) установлены одинаковые версии Windows. Я столкнулся с проблемами при запуске сценария на компьютере с Windows Server 2016, но указанная мной виртуальная машина была размещена на Windows Server 2012 R2 Hyper-V.