Взятие под контроль разрастания виртуальных машин (часть 15)

Опубликовано: 18 Апреля, 2023

  • Взятие под контроль разрастания виртуальных машин (часть 2)
  • Взятие под контроль разрастания виртуальных машин (часть 3)
  • Взятие под контроль разрастания виртуальных машин (часть 4)
  • Взятие под контроль разрастания виртуальных машин (часть 5)
  • Взятие под контроль разрастания виртуальных машин (часть 6)
  • Взятие под контроль разрастания виртуальных машин (часть 7)
  • Взятие под контроль разрастания виртуальных машин (часть 8)
  • Взятие под контроль разрастания виртуальных машин (часть 9)
  • Взятие под контроль разрастания виртуальных машин (часть 10)
  • Взятие под контроль разрастания виртуальных машин (часть 11)
  • Взятие под контроль разрастания виртуальных машин (часть 12)
  • Взятие под контроль разрастания виртуальных машин (часть 13)
  • Взятие под контроль разрастания виртуальных машин (часть 18)

В предыдущей статье мы были невероятно близки к завершению сценария, который будет анализировать данные о создании и удалении виртуальных машин за год на наборе серверов. Осталось закончить несколько дел. Это включает:

  • Напишите код для подсчета общего количества событий создания и удаления ВМ на всех серверах.
  • Пересмотрите код, чтобы анализировать весь год (сейчас мы изучаем данные только за два месяца).
  • Вывод данных на график

На первый взгляд, эти задачи обманчиво просты. Например, для подсчета общего количества событий создания ВМ за год может показаться, что нужно создать переменную, затем сложить все события создания за разные месяцы и присвоить значение этой переменной. Возможно, код будет выглядеть примерно так:

$NumTotalCreateEvents = $NumTotalCreateEvents + $NumJanCreateEvents + $NumFebCreateEvents

К сожалению, все далеко не так просто, как кажется. Есть две проблемы, из-за которых ранее упомянутый подход будет работать некорректно. Во-первых, чтобы зафиксировать события создания и удаления виртуальной машины, мы используем удаленные сеансы. Таким образом, переменные, которые мы назначаем, недействительны вне этих сеансов.

Предположим, например, что я должен установить удаленный сеанс с сервером с именем Hyper-V-1, а затем использовать команду $VMs=Get-VM для захвата имен всех виртуальных машин, работающих на этом сервере. Как только удаленный сеанс завершается, переменная становится недействительной. Причина этого в том, что переменная существовала в удаленном сеансе, а не в локальном сеансе.

Другая проблема, с которой мы столкнулись, заключается в том, что для подсчета событий создания и удаления ранее описанным способом потребовалось бы использование определенных переменных в основной части скрипта и в функции. PowerShell так не работает, по крайней мере, по умолчанию.

Мы все еще можем выполнить то, что необходимо сделать, но переменные области видимости станут чрезвычайно важными. Поскольку сценарий уже настолько сложен, я действительно не хочу вводить переменные области видимости в уже сложный сценарий и пытаться рассказать вам о том, что происходит. Вместо этого я хочу создать пару коротких демонстрационных сценариев, которые я могу использовать для ознакомления с концепциями, которые мы будем использовать. Как только вы поймете, что происходит, мы интегрируем эти методы в наш существующий сценарий.

Итак, давайте сначала разберемся с проблемой удаленных сеансов. Как упоминалось ранее, вы можете назначить переменную в удаленном сеансе, но эта переменная обычно действительна только в удаленной системе. Таким образом, нам нужен способ вернуть содержимое удаленной переменной в локальную систему, в которой выполняется скрипт.

Чтобы продемонстрировать проблему, взгляните на простой скрипт ниже:

$Session = New-PSSession -ComputerName Hyper-V-3

Invoke-Command -Session $Session -ScriptBlock {

$MyVar = Get-VM

$моя переменная | Выберите имя объекта}

$моя переменная | Имя объекта выбора

Этот сценарий устанавливает удаленный сеанс к серверу с именем Hyper-V-3, а затем получает список имен виртуальных машин. Обратите внимание, однако, что сценарий предназначен для отображения имен виртуальных машин дважды, один раз внутри блока сценария и один раз вне блока сценария. Однако, когда я запускаю сценарий, имена виртуальных машин отображаются только один раз. Причина в том, что переменная $MyVar имеет значение null в локальном сеансе. Вы можете увидеть, как это выглядит на рисунке А.

Изображение 14714
Рисунок A: Имена виртуальных машин отображаются только один раз.

Итак, нам нужен способ связать удаленную переменную с локальной переменной. Я могу сделать это с помощью сценария ниже:

$Session = New-PSSession -ComputerName Hyper-V-3

Invoke-Command -Session $Session -ScriptBlock {

$MyVar = Get-VM

$моя переменная | Выберите имя объекта}

$LocalResult = Invoke-Command -Session $Session -ScriptBlock {$MyVar}

$LocalResult | Имя объекта выбора

Как вы можете видеть на рисунке B, имена виртуальных машин теперь выводятся дважды — один раз локально и один раз удаленно. Хитрость в том, чтобы сделать эту работу предпоследней строкой, которая присваивает содержимое удаленной переменной локальной переменной.

Изображение 14715
Рисунок B: Содержимое удаленной переменной теперь доступно локально.

Итак, я решил проблему захвата содержимого удаленной переменной. Но как насчет проблемы с функцией? Как вы, возможно, помните, наш первоначальный сценарий передавал имена серверов функции, которая получала количество виртуальных машин для каждого сервера.

Имея это в виду, взгляните на сценарий ниже. Этот сценарий идентичен сценарию, который я вам только что показал, за исключением того, что я поместил код в функцию с именем GetMyData. После запуска функции я пытаюсь еще раз отобразить содержимое переменной $LocalResult.

Функция GetMyData{

$Session = New-PSSession -ComputerName Hyper-V-3

Invoke-Command -Session $Session -ScriptBlock {

$MyVar = Get-VM

$моя переменная | Выберите имя объекта}

$LocalResult = Invoke-Command -Session $Session -ScriptBlock {$MyVar}

$LocalResult | Выберите имя объекта}

GetMyData

$LocalResult | Имя объекта выбора

Однако если вы посмотрите на вывод на рисунке C, то увидите, что переменная $LocalResult не работает вне функции. Функция возвращает локальные и удаленные результаты, но вне функции переменная имеет значение null.

Изображение 14716
Рисунок C: Результаты возвращаются только внутри функции.

Есть несколько разных способов решить эту проблему, но, хотите верьте, хотите нет, я могу решить проблему одним словом — Глобальный. Вот мое исправление:

Функция GetMyData{

$Session = New-PSSession -ComputerName Hyper-V-3

Invoke-Command -Session $Session -ScriptBlock {

$MyVar = Get-VM

$моя переменная | Выберите имя объекта}

$Global:LocalResult = Invoke-Command -Session $Session -ScriptBlock {$MyVar}

$LocalResult | Выберите имя объекта}

GetMyData

$LocalResult | Имя объекта выбора

Теперь, когда я запускаю сценарий, отображается правильный вывод, как показано на рисунке D.

Изображение 14717
Рисунок D. Теперь переменная $LocalResult действительна как внутри, так и вне скрипта.

Хорошо, так как я это сделал? Мое исправление состояло в том, чтобы сделать $LocalResult глобальной переменной. Обратите внимание, что когда я объявлял переменную, я использовал эту строку кода:

$Global:LocalResult = Invoke-Command -Session $Session -ScriptBlock {$MyVar}

Вставка Global: перед именем переменной делает значение переменной переносимым по всему сценарию. Вы заметите, что когда я вывожу значение переменной, я все еще могу обращаться к переменной как к $LocalResult. Только когда я объявляю переменную, я должен обращаться к ней как к $Global:LocalResult.

Это на самом деле поднимает важный момент. В большинстве языков программирования достаточно объявить переменную как Global. Однако в PowerShell мы должны сообщать PowerShell, что переменная является глобальной каждый раз, когда мы изменяем значение переменной.

Вывод

Как видите, в следующей статье у нас есть работа. У нас уже есть сложный сценарий, и нам нужно будет пересмотреть его, чтобы некоторые переменные были глобальными, а счетчики создания и удаления виртуальных машин, которые мы извлекаем из удаленных систем, можно было использовать локально. Все будет немного запутанно, но потерпите меня, и мы справимся с этой задачей.

  • Взятие под контроль разрастания виртуальных машин (часть 2)
  • Взятие под контроль разрастания виртуальных машин (часть 3)
  • Взятие под контроль разрастания виртуальных машин (часть 4)
  • Взятие под контроль разрастания виртуальных машин (часть 5)
  • Взятие под контроль разрастания виртуальных машин (часть 6)
  • Взятие под контроль разрастания виртуальных машин (часть 7)
  • Взятие под контроль разрастания виртуальных машин (часть 8)
  • Взятие под контроль разрастания виртуальных машин (часть 9)
  • Взятие под контроль разрастания виртуальных машин (часть 10)
  • Взятие под контроль разрастания виртуальных машин (часть 11)
  • Взятие под контроль разрастания виртуальных машин (часть 12)
  • Взятие под контроль разрастания виртуальных машин (часть 13)
  • Взятие под контроль разрастания виртуальных машин (часть 18)