Глава 3. Изучаем совместимость с Windows PowerShell

В данной главе мы рассмотрим следующие рецепты:

  • Исследование совместимости с Windows PowerShell

  • Применение совместимого с Windows PowerShell решения

  • Исследование ограничений совместимых решений

  • Исследование списка запрета определённых модулей

  • Формат импорта XML

  • Усиление совместимости

Введение

Microsoft построил Windows PowerShell для работы с .NET Framework Microsoft. Вы можете рассматривать PowerShell как некий уровень поверх .NET. Когда вы применяете командлет Get-ChildItem для возврата подробностей о файле или папке, этот командлет активирует некий класс .NET для выполнения всех вовлечённых в процесс трудных моментов. Дополнительные сведения относительно .NET вы получите в Главе 5, Изучаем .NET.

По мере развития Windows PowerShell, всякая новая версия пользовалась преимуществами более новой версии .NET для предоставления дополнительных функциональных возможностей.

В 2014 Microsoft анонсировал, что они выпустят .NET Framework с открытым исходным кодом, который будет носить название .NET Core. Microsoft также принял решение разморозить разработку Windows PowerShell в угоду открытия исходного кода Windows PowerShell. Самые первые две версии носили название PowerShell Core. Начиная с выпуска PowerShell 7, его команда отбросила название "Core" и анонсировала, что последующие версии будут именоваться просто PowerShell. Данная книга ссылается на эту самую последнюю версию просто как на PowerShell 7.

Для вас как для профессионала ИТ критически важным вопросом, который вы должны задавать это будет ли PowerShell 7 способен исполнять именно ваши рабочие процессы. Как всегда ответ - "это зависит от обстоятельств". Это зависит от конкретных свойств Windows PowerShell и модулей/ команд, на которые вы полагаетесь. Как показывает наша книга, остаётся очень немного моментов, которые вы были способны делать в Windows PowerShell и которые нельзя выполнять в PowerShell 7.

На момент публикации также доступна последняя выпущенная версия PowerShell 7.1.3, причём также доступна 8 версия предварительного просмотра PowerShell 7.2. Скорее всего, к моменту чтения вами этой книги ситуация изменится.

Модульная совместимость

С точки зрения совместимости с Windows PowerShell существует три набора модулей, содержащих различные команды для изучения:

  • Модули/ команды, поставляемые с Windows PowerShell, на которые и полагаются ваши сценарии.

  • Модули/ команды, включаемые как часть функциональных возможностей Windows - они содержат команды для управления различными сторонами служб Windows, как правило, в виде части RSAT (Remote Server Administration Tools, Инструментов администрирования удалённым сервером), которые можно загружать независимо от самих служб.

  • Прочие сторонние модули, такие как модуль NTFSSecurity. Данная книга применяет некоторые внешние модули, авторы которых могут обновлять или не обновлять свои модули для работы в .NET Core.

Windows PowerShell содержит модули, которые предоставляют базовые функциональные возможности PowerShell. Например, модуль Microsoft.PowerShell.Management содержит командлет Get-Process. Для PowerShell 7 команда разработчиков заново реализовала все основополагающие команды Windows PowerShell для предоставления хорошего воспроизведения Windows PowerShell. Несколько команд Windows PowerShell применяют частные API, поэтому они не могут быть включены, однако их число относительно невелико.

Эти центральные модули (Microsoft.PowerShell.*) теперь располагаются внутри папки самой инсталляции PowerShell, что упрощает применение располагающихся бок- о- бок версий PowerShell. Когда вы вызываете в PowerShell 7 некий командлет, посредством переменной PSModulePath, вы можете вызывать "правильный" командлет и поддерживаемые основы. Важно отметить, что эти модули ядра изначально разрабатывались командой Windows PowerShell и не являются частью PowerShell с открытым исходным кодом.

Клиент Windows и Windows Server также предоставляют модули, которые позволяют вам управлять системой. Такие модули как Active Directory снабжают вас инструментами для управления AD в вашей среде. Эти модули обитают в вашей папке C:\Windows\System32\WindowsPowerShell\v1.0\modules folder.

Владение такими относящимися к операционной системе модулей лежит на командах конкретных индивидуальных продуктов, причём некоторые из них мотивированы на обновление своих модулей для работы с .NET Core. Как и многие прочие вещи, эта работа в процессе исполнения. Некоторые такие модули, как модуль ActiveDirectory были обновлены и доступны естественным образом в PowerShell 7. Для быстрого ознакомления с совместимостью просмотрите этот документ. Не лишним будет отметить, что обновление таких модулей ОС будет осуществляться лишь с обновлением на более новую версию ОС, что не очень удачно.

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

В рецепте Изучение совместимости с Windows PowerShell подробно рассматриваются те новые команды, которые доступны в PowerShell 7, а также то, где PowerShell и Windows PowerShell обнаруживают команды ядра.

Поскольку команды продуктов Windows и прочие производители модулей могут не обновлять свои модули для работы естественным образом, команда PowerShell разработала некое решение для обеспечения совместимости, которое делает возможным более- менее бесшовный импорт и применение модулей Windows PowerShell в PowerShell. В рецепте Изучение ограничений совместимых решений вы исследуете работу решения совместимость с Windows PowerShell.

Несовместимые модули

В обладающем совместимостью решении те модули, которые разработаны для Windows PowerShell работают как положено, что демонстрируется в большом числе примеров данной книги. Однако в нескольких случаях существуют некоторые небольшие и какие- то более основательные проблемы. Некоторые моменты могут работать как положено, а могут и нет внутри PowerShell 7 и последующих версиях. Например, несмотря на имеющиеся совместимые решения, модули BestPractices, PSScheduledJob и WindowsUpdate не будут работать должным образом в PowerShell 7.

В Windows PowerShell вы применяете модуль WindowsUpdate для управления WSUS (Windows Server Update Services, Службами обновления Windows Server). Модуль UpdateServices WSUS применяет методы объектов. Без новых методов совместимости эти методы не доступны в сеансах PowerShell 7. Кроме того, этот модуль применяет протокол SOAP (Simple Object Access Protocol, Простой протокол доступа к объектам) для которого .NET Core не предоставляет поддержки (и вряд ли появится в ближайшее время). Прочие два модуля применяют типы .NET, которые не предоставляются .NET Core и скорее всего не будут обновлены.

Прочие функциональные возможности, которые не представляются работающими в PowerShell 7 содержат:

  • Рабочие потоки Windows PowerShell: Рабочим потокам требуется компонент .NET Windows Workflow Foundation, который команда .NET не портировала в .NET Core.

  • Оснастки Windows PowerShell: Оснастки позволяют добавлять новые командлеты в PowerShell V2. Модули заменили оснастки в качестве механизма надстроек в PowerShell V2 и выступают тем единственным методом, который вы применяете при добавлении команд в PowerShell. Вы можете преобразовать некоторые оснастки в модули, создавая манифест модуля, но большинство из них требует от авторов их повторного проектирования.

  • Командлеты WMI: Модуль CIMCmdlets заменяет более старые командлеты WMI.

  • DSC (Desired State Configuration, Конфигурации желательного состояния): Изнутри PowerShell 7 функции ядра DSCне доступны для вас.

  • Поставщик IIS модуля WebAdministration: Это означает, что многие сценарии IIS не работают в PowerShell 7, даже в совместимом решении.

  • Команды Add-Computer, Checkpoint-Computer, Remove-Computer и Restore-Computer из модуля Microsoft.PowerShell.Management.

Хотя и имеются некоторые свойства и команды Windows PowerShell, которые вы не можете применять в PowerShell 7, даже при помощи решения совместимости Windows PowerShell вы всегда можете применять Windows PowerShell.

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

Одним из недостатков имеющегося механизма совместимости, является то, что любой включаемый в модули формат XML не загружаются в сеанс PowerShell 7. Основной результат состоит в том, что PowerShell 7 не так хорошо форматирует объекты. К счастью, имеется способ обойти это, как вы это обнаружите в рецепте Импорт формата XML.

Решение совместимости Windows PowerShell применяет специально созданный удалённый сеанс PowerShell. В рецепте Пользуемся совместимостью вы рассмотрите такой сеанс и изучите как вы можете пользоваться его преимуществами.

[Предостережение]Предостережение

Несмотря на имеющиеся проблемы совместимости, более чем разумно перейти на PowerShell 7 и отказаться от Windows PowerShell. Одна из ключевых причин состоит в улучшении производительности. Вы можете применять конструкцию ForEachObject -Parallel для параллельного исполнения блоков сценария без необходимости обращаться к рабочим потокам. Когда ваш сценарий должен выполнять действия на большом количестве компьютеров, или же вы обрабатываете большой массив, улучшения PowerShell оправдывают такое перемещение вперёд. Вдобавок ко всему, все вновь добавляемые функциональные возможности превращают жизнь в намного более простую.

Изучение совместимости с Windows PowerShell

Когда вы активируете некий командлет, PowerShell обязан загрузить некий модуль, содержащий этот командлет и был способен далее его выполнить. По умолчанию, PowerShell для обнаружения необходимых модулей и соответствующих, содержащихся в этих модулях, командлетов применяет значение пути из переменной среды $env:PSModulePath.

Как показывает данный рецепт, значения настроек путей, удерживаемых в $env:PSModulePath изменилось при переходе с Windows PowerShell 5.1 на PowerShell 7.

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

Подготовка

Вы можете выполнять этот рецепт в SRV1 после того как вы установили PowerShell 7 и/ или VS Code.

Как это сделать...

  1. Убеждаемся что удалённый PowerShell полностью готов

    
    Enable-PSRemoting -Force -WarningAction SilentlyContinue |
      Out-Null
    		
  2. Получаем сеанс с применением в качестве конечной точки Windows PowerShell 5.1

    
    $SHT1 = @{
      ComputerName      = 'localhost'
      ConfigurationName = 'microsoft.powershell'
    }
    $SWP51 = New-PSSession @SHT1
    		
  3. Получаем сеанс с применением конечной точки PowerShell 7.1

    
    $CNFName = Get-PSSessionConfiguration | 
                 Where-Object PSVersion -eq '7.1' |
                   Select-Object -Last 1
    $SHT2 = @{
      ComputerName      = 'localhost'
      ConfigurationName = $CNFName.Name
    }               
    $SP71    = New-PSSession @SHT2
    		
  4. Определяем блок сценария для просмотра установленных по умолчанию путей к модулям

    
    $SBMP = {
      $PSVersionTable
      $env:PSModulePath -split ';'
    }
    		
  5. Просматриваем эти пути в Windows PowerShell 5.1

    
    Invoke-Command -ScriptBlock $SBMP -Session $SWP51
    		
  6. Просматриваем эти пути в PowerShell 7.1

    
    Invoke-Command -ScriptBlock $SBMP -Session $SP71
    		
  7. Создаём блок сценария для получения команд в PowerShell

    
    $SBC = {
      $ModPaths = $Env:PSModulePath -split ';'
      $CMDS = @()
      Foreach ($ModPath in $ModPaths) {
        if (!(Test-Path $Modpath)) {Continue}
        # Process modules found in an existing module path
        $Mods = Get-ChildItem -Path $ModPath -Directory
        foreach ($Mod in $Mods){
          $Name  = $Mod.Name
          $Cmds  += Get-Command -Module $Name
        }
      }
      $Cmds  # return all commands discovered
    }
    		
  8. Исследуем все командлеты 7.1

    
    $CMDS71 = Invoke-Command -ScriptBlock $SBC -Session $SP71 | 
                Where-Object CommandType -eq 'Cmdlet'
    "Total commands available in PowerShell  7.1 [{0}]" -f $Cmds71.count
    		
  9. Исследуем все командлеты 5.1

    
    $CMDS51 = Invoke-Command -ScriptBlock $SBC -Session $SWP51 |
                Where-Object CommandType -eq 'Cmdlet'
    "Total commands available in PowerShell  5.1 [{0}]" -f $Cmds51.count
    		
  10. Создаём массив только из названий командлетов

    
    $Commands51 = $CMDS51 | 
      Select-Object -ExpandProperty Name |
        Sort-Object -Unique
    $Commands71 = $CMDS71 |
      Select-Object -ExpandProperty Name |
        Sort-Object -Unique
    		
  11. Исследуем новые команды в PowerShell 7.1

    
    Compare-Object $Commands51 $Commands71  | 
      Where-Object sideindicator -match '^=>' 
    		
  12. Создаём блок сценария для проверки моделей ядра PowerShell

    
    $CMSB = {
      $M = Get-Module -Name 'Microsoft.PowerShell*' -ListAvailable
      $M
      "$($M.count) modules found in $($PSVersionTable.PSVersion)"
    }
    		
  13. Просматриваем модули ядра в Windows PowerShell 5.1

    
    Invoke-Command -Session $SWP51 -ScriptBlock $CMSB
    		
  14. Просматриваем модули ядра в PowerShell 7.1

    
    Invoke-Command -Session $SWP71 -ScriptBlock $CMSB
    		

Как это работает...

На Шаге 1 вы полностью гарантируете что удалённый PowerShell включён внутри PowerShell 7. Это может не быть необходимым, но данный шаг, который не выдаёт никакого вывода, обеспечит существование создаваемых позднее в данном рецепте терминальных точек.

На Шаге 2 вы создаёте новый удалённый сеанс к конечной точке Windows PowerShell 5.1 в своём локальном компьютере. Название конфигурации этой терминальной точки, microsoft.powershell хорошо знакомое название конфигурации, которая исполняет Windows PowerShell 5.1.

На Шаге 3 вы затем повторяете эту операцию и создаёте новый удалённый сеанс к конечной точке PowerShell 7.1. Этот шаг не производит вывода.

На Шаге 4 вы создаёте простой блок сценария, который отображает таблицу версии PowerShell и показывает пути к модулям своей терминальной точки.

На Шаге 5 вы просматриваете значение версии запущенного PowerShell (внутри своего удалённого сеанса) и пути к модулям версии. Вывод на этом шаге выглядит примерно так:

 

Рисунок 3-01


Инспектируем версию PowerShell 5.1 и пути к её модулям

На Шаге 6 вы просматриваете пути в конечной точке PowerShell 7.1, что выглядит следующим образом:

 

Рисунок 3-02


Инспектируем версию PowerShell 7.1 и пути к её модулям

На Шаге 7 вы создаёте блок сценария, который выдаёт все подробности каждого из модулей, доступных для конкретной конечной точки. Этот шаг не воспроизводит вывод. На Шаге 8 вы исполняете это блок сценария в удалённой конечной точке PowerShell 7.1 для выявления всех доступных команд, что выглядит так:

 

Рисунок 3-03


Обнаруживаем все командлеты в PowerShell 7.1

На Шаге 9 вы выполняете этот блок сценария внутри конечной точки Windows PowerShell для воспроизведения следующего вывода:

 

Рисунок 3-04


Обнаруживаем все командлеты в PowerShell 5.1

На Шаге 10 вы создаёте массив для содержания названий всех доступных команд. Вы сопоставляете их на Шаге 11 для обнаружения тех команд, которые имеются в PowerShell 7.1, но отсутствуют в Windows PowerShell 5.1, что отображено ниже:

 

Рисунок 3-05


Обнаруживаем командлеты имеющиеся в PowerShell 7.1, но не в PowerShell 5.1

На Шаге 12 вы создаёте блок сценария, который можно применять для выявления всех модулей ядра PowerShell и местоположений хранящих их файлов. Этот шаг не производит никакого вывода. На Шаге 13 вы исполняете этот блок сценария внутри созданного вами ранее удалённого сеанса Windows PowerShell, что выглядит так:

 

Рисунок 3-06


Просматриваем модули ядра в PowerShell 5.1

Далее вы повторно исполняете этот блок сценария в конечной точке PowerShell 7.1, на Шаге 14. Вывод этого шага выглядит следующим образом:

 

Рисунок 3-07


Просматриваем модули ядра в PowerShell 5.1

Есть кое- что ещё...

Приводимый на Шаге 2 код создаёт удалённую конечную точку PowerShell к хорошо известной терминальной точке Windows PowerShell 5. Вы не можете просматривать конфигурацию удалённой точки Windows PowerShell изнутри PowerShell 7.1.

На Шаге 3 вы получаете сеанс, который предоставляет PowerShell 7.1 с применением слегка иной техники, чем та, которую вы применяли на Шаге 2. PowerShell 7.1 обладает множеством конечных точек, в особенности, когда вы обладаете и версией выпуска, и версией предварительного просмотра, выгруженные бок- о- бок. Для просмотра имеющихся доступными конфигураций конечных точек в вашем конкретном хосте вы можете воспользоваться командлетом Get-PSSessionConfiguration. Таким образом, вы не увидите удалённые конечные точки Windows PowerShell внутри PowerShell 7.1. Хотя командлет Get-PSSessionConfiguration и не возвращает никакие подробности конфигурации Windows PowerShell, эти удалённые конечные точки присутствуют, и можем пользоваться ими, что вы и наблюдали на Шаге 2.

На Шаге 5 и Шаге 6 вы выявляете значение путей к модулям по умолчанию в Windows PowerShell и в PowerShell 7.1. Как вы можете наблюдать, в PowerShell 7 имеется пять путей по умолчанию к модулям, в противоположность всего трём в Windows PowerShell 5.1. Самые первые три папки модулей с PowerShell 7 позволяют PowerShell 7 подхватывать команды из специфичных для PowerShell 7.1 папок (когда они имеются), а последние два пути к модулям делают для вас возможным доступ к более ранним командам Windows PowerShell, которых у вас нет в PowerShell 7.

На Шаге 13 и на Шаге 14 вы выявляете все модули ядра внутри Windows PowerShell. Эти модули ядра содержат все основные внутренние команды PowerShell, такие как Get-ChildItem, обнаруживаемая в модуле Microsoft.PowerShell.Management .

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

Применение совместимых с Windows PowerShell решений

Решение PowerShell 7 совместимости Windows позволяет вам применять команды Windows PowerShell, чьи разработчики (ещё пока) не портировали свои команды для работы естественным образом в PowerShell 7. PowerShell 7создаёт специальный удалённый сеанс в терминальную точку Windows PowerShell 5.1, загружает необходимые модули в этом удалённом сеансе, а затем предоставляет неявное удалённое взаимодействие для для предоставления функций посредника (прокси) внутри сеанса PowerShell 7. Этот сеанс удалённого взаимодействия обладает уникальным именем сеанса WinPSCompatSession. если вам необходимо применять множество модулей Windows PowerShell, PowerShell 7 загружает их все в отдельном удалённом сеансе. Кроме того, этот сеанс пользуется транспортным механизмом "процесса" в противоположность WinRM (Windows Remote Management, Удалённому управлению Windows). WinRM является центральным транспортным протоколом, применяемым в удалённой работе PowerShell. Новый транспорт процесса это транспорт, применяемый для исполнения заданий в фоновом режиме; он обладает меньшими накладными расходами, нежели применение WinRM, а потому более эффективен.

Некоторым примером применения механизма совместимости является использование Get-WindowsFeature, командлета внутри модуля ServerManager. Вы пользуетесь этой командой для получения подробностей относительно установленных или не установленных внутри Windows Server свойств. Для установки или удаления свойств вы применяете прочие команды из модуля ServerManager.

К сожалению, команда Windows Server ещё пока не обновила данный модуль для работы внутри PowerShell Core. Рассматриваемый нами механизм совместимости Windows PowerShell позволяет вам применять имеющиеся в Windows PowerShell сценарии в PowerShell 7, хотя и с весьма незначительными предостережениями.

Когда вы активируете PowerShell 7, PowerShell применяет свою команду механизма обнаружения для определения того какой из модулей содержит нужную команду. В нашем случае таким модулем выступает модуль Windows PowerShell ServerManager. Затем PowerShell создаёт сеанс удалённого взаимодействия и, применяя удалённое исполнение в неявном виде, импортирует необходимые команды в этом модуле в качестве функций посредников (прокси). Затем вы активируете эти посреднические функции для осуществления своей цели. По большей части это прозрачно целиком. Вы пользуетесь необходимыми командами модуля, а они возвращают тот объект (те объекты), которые вы запросили. Одна незначительная проблема состоит в том, что рассматриваемый механизм совместимости не импортирует формат XML для соответствующего модуля Windows PowerShell. Как результат, мы получаем что вывод по умолчанию для некоторых объектов не тот же самый. Существует некий обходной манёвр для этого, который мы описываем в рецепте Импорт формата XML.

Применяя удалённое исполнение, PowerShell 7 создаёт внутри сеанса PowerShell 7 некую функцию с теми же самыми названием и параметрами, что и у реальной команды (в соответствующем сеансе удалённого взаимодействия). Вы можете просматривать определение такой функции в устройстве Function (Get-Item Function:Get-WindowsFeature | Format-List -Property *). Получаемый вывод отображает определение соответствующей посреднической функции, которую создаёт PowerShell 7 при выполнении соответствующего импорта необходимого удалённого модуля.

Когда вы активируете некую команду по её названию, например, Get-WindowsFeature, PowerShell исполняет соответствующую функцию. Эта функция далее активирует свой удалённый командлет применяя пошаговый конвейер. Неявное удалённое взаимодействие это сложная функциональная возможность, которая при работе практически прозрачна.

Подготовка

Вы можете выполнять этот рецепт в SRV1 после того как вы установили PowerShell 7 и/ или VS Code.

Как это сделать...

  1. Обнаруживаем модуль ServerManager

    
    Get-Module -Name ServerManager -ListAvailable
    		
  2. Отыскиваем команду в модуле ServerManager

    
    Get-Command -Name Get-WindowsFeature
    		
  3. Импортируем этот модуль в явном виде

    
    Import-Module -Name ServerManager
    		
  4. Выявляем имеющиеся в этом модуле команды

    
    Get-Module -Name ServerManager | Format-List
    		
  5. Применяем команду из модуля ServerManager

    
    Get-WindowsFeature -Name TFTP-Client
    		
  6. Исполняем необходимую команду в сеансе удалённого взаимодействия

    
    $Session = Get-PSSession -Name WinPSCompatSession
    Invoke-Command -Session $Session -ScriptBlock {
      Get-WindowsFeature -Name DHCP |
        Format-Table
    }
    		
  7. Удаляем модуль ServerManager из нашего текущего сеанса

    
    Get-Module -Name ServerManager |
      Remove-Module
    		
  8. Устанавливаем свойство Windows при помощи автоматической загрузки модуля

    
    Install-WindowsFeature -Name TFTP-Client
    		
  9. Выявляем это свойство

    
    Get-WindowsFeature -Name TFTP-Client
    		
  10. Просматриваем вывод внутри сеанса PowerShell

    
    Invoke-Command -Session $Session -ScriptBlock {
        Get-WindowsFeature -Name 'TFTP-Client' |
          Format-Table
    }
    		

Как это работает...

На Шаге 1 вы пользуетесь командой Get-Module для обнаружения модуля ServerManager. Поскольку данная команда не работает в PowerShell 7, несмотря на присутствие переключателя -ListAvailable, эта команда не возвращает никаких данных вывода.

На Шаге 2 для выявления команды Get-WindowsFeature мы пользуемся Get-Command. Вот что мы получаем на выходе:

 

Рисунок 3-08


Обнаруживаем команду Get-WindowsFeature

На Шаге 3 вы импортируете в явном виде модуль ServerManager, что выглядит следующим образом:

 

Рисунок 3-09


Импортируем модуль ServerManager в явном виде

Теперь, когда PowerShell 7 импортировал необходимый модуль, вы можете наблюдать вывод из Get-Module. Вот представленный на Шаге 4 вывод:

 

Рисунок 3-10


Выявляем модуль ServerManager

Для иллюстрации работы более старой команды Windows PowerShell в PowerShell 7, на Шаге 5 вы активируете Get-WindowsFeature. Эта команда выявляет установлено ли свойство Клиента TFTP, что показано ниже:

 

Рисунок 3-11


Активируем команду Get-WindowsFeature

На Шаге 6 вы повторно исполняете команду Get-WindowsFeature внутри сеанса удалённого взаимодействия Windows PowerShell, причём вывод выглядит так:

 

Рисунок 3-12


Активируем команду Get-WindowsFeature в удалённом сеансе

На Шаге 7 вы удаляете из текущего сеанса PowerShell модуль ServerManager, что не выдаёт никакого вывода. На Шаге 8 вы устанавливаете функциональную возможность TFTP-Client, что выглядит следующим образом:

 

Рисунок 3-13


Устанавливаем TFTP-Client

На Шаге 9 вы повторно выполняете команду Get-WindowsFeature для проверки состояния функциональной возможности TFTP-Client, которое отображается так:

 

Рисунок 3-14


Проверяем состояния TFTP-Client

На Шаге 10 вы повторно просматриваете свойство TFTP-Client изнутри своего сеанса удалённого взаимодействия Windows PowerShell, что показано ниже:

 

Рисунок 3-15


Просматриваем TFTP-Client внутри своего удалённого сеанса

Есть кое- что ещё...

На Шаге 1 вы пытаетесь обнаружить модуль ServerManager, применяя переключатель -ListAvailable. Этот модуль не доступен в PowerShell 7, следовательно отсутствует в выводе. Даже хотя наш механизм совместимости и способен обнаружить этот модуль, по умолчанию Get-Module не отображает этот модуль.

На Шаге 2 вы обнаруживаете, что команда Get-WindowsFeature поступает из модуля ServerManager и далее вы загружаете его в явном виде на Шаге 3. Загрузка этого модуля при помощи Import-Module вырабатывает предупредительное сообщение, которое вы можете наблюдать в полученном выводе. Обратите внимание на то, что в PowerShell 7 наша команда Get-WindowsFeature это функция, а не командлет. Наш неявный удалённый процесс создаёт некую функцию- посредник (в своём сеансе PowerShell 7), которая затем активирует в своём сеансе удалённого взаимодействия лежащую в основе команду. Вы можете изучить определение этой функции чтобы увидеть как ваша посредничающая функция активирует необходимую удалённую функцию.

На Шаге 9 и на Шаге 10 вы просматриваете внутри PowerShell 7 вывод из Get-WindowsFeature , а затем внутри своего удалённого сеанса к Windows PowerShell. На Шаге 9 вы наблюдаете вывод, отличающийся от вывода на Шаге 10, что является результатом того, что PowerShell 7 не импортирует необходимый формат XML для данного модуля. Вы увидите как обходить эту небольшую проблему позднее в этой главе в Импорт формата XML.

Описанный механизм совместимости с Windows PowerShell в PowerShell 7 выполняет исключительное задание поддержки несовместимых в противном случае модулей Windows PowerShell. Но даже при этом имеются некоторые команды и модули, которые даже и не собираются работать.

Изучение ограничений совместимых решений

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

Самым первым ограничением выступает обнаружение. Вы не можете простым способом выявлять не поддерживаемые команды. Например, вы не можете пользоваться модулем Get-Module для перечисления модуля ServerManager, даже хотя вы и можете применять Get-Command для выявления команд внутри этого модуля.

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

Несмотря на наличие решения совместимости, некоторые модули Windows Server просто вовсе не работают в PowerShell 7. Если вы загрузите такие модули вручную, подобный модуль может загрузиться, однако некоторые или все его команды не будут работать и зачастую выдают сообщения об ошибках, которые невозможно применять на практике.

Подготовка

Выполняйте этот рецепт в новом сеансе PowerShell в SRV1 после того как вы установили PowerShell 7 и/ или VS Code.

Как это сделать...

  1. Попытайтесь просмотреть модуль Windows PowerShell

    
    Get-Module -Name ServerManager -ListAvailable
    		
  2. Попробуйте загрузить модуль, не проверяя редакцию

    
    Import-Module -Name ServerManager -SkipEditionCheck
    		
  3. Обнаружьте команду Windows PowerShell Get-WindowsFeature

    
    Get-Command -Name Get-WindowsFeature
    		
  4. Изучите сеанс совместимости Windows PowerShell

    
    $Session = Get-PSSession
    $Session | Format-Table -AutoSize
    		
  5. Исследуйте в таком сеансе удалённого взаимодействия Get-WindowsFeature

    
    $SBRC = {Get-Command -Name Get-WindowsFeature}
    Invoke-Command -Session $Session -ScriptBlock $SBRC
    		
  6. Активируйте Get-WindowsFeature локально

    
    Invoke-Command $SBRC
    		

Как это работает...

На Шаге 1 вы применяете командлет Get-Module для получения подробностей относительно модуля ServerManager. Однако, поскольку такой модуль не поддерживается естественным образом, Get-Module не выдаёт никакого вывода когда вы активируете его внутри сеанса PowerShell 7, причём даже когда вы пользуетесь переключателем -ListAvailable.

На Шаге 2 вы применяете переключатель -SkipEditionCheck чтобы проинструктировать Import-Module попытаться загрузить необходимый модуль ServerManager в наш сеанс PowerShell 7, что выглядит следующим образом:

 

Рисунок 3-16


Загрузка ServerManager без проверки редакции

Как вы можете наблюдать в получаемом выводе, Import-Module выдаёт ошибки когда вы пытаетесь загружать этот модуль в PowerShell 7, причём с неким сообщением об ошибке, постулирующем что Import-Module оказался не способен загрузить тип .NET System.Diagnostics.Eventing.EventDescriptor. Поскольку тип EventDescriptor не доступен в .NET Core, вы не можете применять модуль ServerManager естественным образом. Единственной альтернативой является что сама команда Server Manager обновит свой код, либо вы исполняете этот командлет в Windows PowerShell (либо в явном виде, либо через описанный механизм совместимости).

На Шаге 3 вы пользуетесь Get-Command для обнаружения команды Get-WindowsFeature, что достигает цели, как вы это можете видеть ниже:

 

Рисунок 3-17


Обнаружение команды Get-WindowsFeature без проверки редакции

На Шаге 4 вы пользуетесь Get-PSSession для выявления сеанса удалённого взаимодействия с Windows PowerShell. Вот вывод с этого шага:

 

Рисунок 3-18


Обнаружение удалённого сеанса совместимости

На Шаге 5 вы активируете команду Get-WindowsFeature внутри сеанса удалённого взаимодействия из Windows PowerShell 5.1 для просмотра подробностей, например, так:

 

Рисунок 3-19


Активация Get-WindowsFeature в сеансе удалённого взаимодействия

На Шаге 6 вы исполняете Invoke-Command для обнаружения подробностей относительно данной команды внутри своей консоли PowerShell 7. Вот вывод данного шага:

 

Рисунок 3-20


Локальная активация Get-WindowsFeature

Есть кое- что ещё...

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

Как вы видите на Шаге 1, некоторые модули не обнаруживаются непосредственно в PowerShell 7. Попытка принудительной загрузки модуля в сеанс PowerShell 7, которую вы предпринимаете на Шаге 2 завершается неудачей (причём даже с бесполезным для пользователя сообщением).

В данном случае, когда PowerShell 7 приступает к загрузке указанного модуля, PowerShell пытается воспользоваться неким типом (объектом .NET), который не существует в ни в полном .NET CLR, ни в .NET Core. Этот тип .NET не только не реализован в .NET Core, но сама команда .NET на практике считает его устаревшим. Чтобы прочесть обсуждение этого, отсылаем вас к https://github.com/dotnet/core/issues/2933. Само обсуждение в данном посте выступает выдающимся образцом прозрачности программного обеспечения с открытым исходным кодом, в котором вы можете увидеть имеющуюся проблему и отследить её решение.

Модуль ServerManager это один из большого числа модулей команды Windows, который требует обновления прежде чем применяться естественным образом в PowerShell 7. К счастью, последующие выпуски Windows Serveer могут решить проблему этого модуля. Однако тем временем, механизм совместимости Windows PowerShell предоставляет исключительное решение для большинства не совместимых модулей.

На Шаге 5 и на Шаге 6 вы изучаете подробности команды Get-WindowsFeature. Внутри Windows PowerShell 5.1 эта команда представляет собой командлет. Когда, на Шаге 6, вы просматриваете эту команду внутри своей консоли PowerShell 7, вы можете обнаружить, что эта команда является (посреднической, прокси) функцией. Когда вы просматриваете само определение этой функции (ls function:get-WindowsFeature.definition), вы можете обнаружить, как PowerShell использует пошаговый конвейер для исполнения данной команды в вашем сеансе удалённого взаимодействия. Для получения бо́льшей основы по самому пошаговому конвейеру, который превратился в функциональную возможность Windows PowerShell начиная с версии 2, смотрите https://livebook.manning.com/book/windows-powershell-in-action-third-edition/chapter-10/327.

Изучение списка запрета модулей

В процессе разработки PowerShell 7 стало ясно, что несколько модулей Windows PowerShell не работают в PowerShell 7 несмотря на решение совместимости. Хуже того, если вы попытаетесь воспользоваться ими, причём получаемые в результате сообщения об ошибках были загадочными и не применимые на практике. Одно из предложенных решений состояло в создании перечня модулей, о которых было известно, что их нельзя применять в PowerShell 7. При попытке Import-Module загружать какой- либо модуль из этого списка, отказ становится более аккуратным с более очевидным сообщением.

Одна из возможных проблем, которую способен вызывать подобный перечень, может состоять в том, что когда владельцы таких модулей должны были выпускать некий обновлённый модуль, который ранее пребывал в списке запрета, а теперь он работает. Для упрощения этой ситуации PowerShell 7 сохраняет перечень запретов в файле конфигурации из папки $PSHOME.

В PowerShell 7.1 имеются три модуля, которые пребывают в таком списке запрета:

  • PSScheduledJob: Команды Windows PowerShell для управления службой Диспетчера задач (Task Manager) Windows. Этот модуль устанавливается в Windows Server по умолчанию.

  • BestPractices: Команды Windows Server для просмотра, запуска и просмотра результатов оптимального сканирования основных служб Windows Server. Этот модуль установлен в Windows Server по умолчанию.

  • UpdateServices: Вы пользуетесь этим модулем для управления WSUS (Windows Server Update Services, Службами обновления Windows Server). Вы можете установить его вместе с WSUS или как часть инструментов RSAT. Этот метод применяет методы объекта для управления службой WSUS, а такие методы недоступны через механизм совместимости. Данный модуль также пользуется SOAP (Simple Object Access Protocol, Протоколом простого доступа к объектам), который также не реализован в .NET Core. По этой причине, чтобы позволить вам управлять WSUS естественным образом в PowerShell 7, необходимо приложить значительные усилия для разработки. В настоящее время Microsoft не берет на себя обязательство выполнять эту работу.

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

В данном рецепте мы рассмотрим списка запрета загрузки модулей PowerShell и расследуем как он работает на практике.

Подготовка

Вы выполняете этот рецепт в SRV1, сервере Windows Server Datacenter Edition, с установленными PowerShell 7 и VS Code.

Как это сделать...

  1. Получаем файл конфигурации PowerShell

    
    $CFFile = "$PSHOME/powershell.config.json"
    Get-Item -Path $CFFile
    		
  2. Просматриваем его содержимое

    
    Get-Content -Path $CFFile
    		
  3. Пытаемся загрузить модуль из перечня запрещённых

    
    Import-Module -Name BestPractices
    		
  4. Загружаем этот модуль, перекрывая проверку редакции

    
    Import-Module -Name BestPractices -SkipEditionCheck
    		
  5. Посматриваем определение этого модуля

    
    Get-Module -Name BestPractices
    		
  6. Пробуем воспользоваться Get-BpaModel

    
    Get-BpaModel
    		

Как это работает...

На Шаге 1 вы определяете местоположение и просматриваете подробности файла конфигурации PowerShell, powershell.config.json. Этот файл пребывает в папке установки PowerShell. Вы можете наблюдать получаемый вывод на следующем снимке экрана:

 

Рисунок 3-21


Получаем файл конфигурации PowerShell

На Шаге 2 вы просматриваете содержимое этого файла, которое выглядит примерно так:

 

Рисунок 3-22


Просмотр содержимого файла конфигурации

На Шаге 3 вы пользуетесь Import-Module для импорта модуля, который вы могли видеть (в своём выводе на Шаге 2) и находящийся в перечне запрещённых. Вывод этого шага выглядит как- то так:

 

Рисунок 3-23


Пытаемся загрузить BestPractices, находящийся в списке запрещённых

В PowerShell 7 вы можете принудить Import-Module к игнорированию списка запрета и попытаться загрузить этот модуль в сеанс PowerShell 7, что вы и наблюдаете на Шаге 4. Для осуществления этого вы определяете переключатель -SkipEditionCheck. Этот переключатель сообщает PowerShell об импорте указанного модуля без проверки на совместимость или же попытаться загрузить такой модуль в имеющемся сеансе совместимости.

На Шаге 5 импорт проявляется как работающий в данном Import-Module, выполняя импорт указанного модуля, что вы можете наблюдать в выводе на данном этапе:

 

Рисунок 3-24


Просмотр определения модуля BestPractices

Как вы обнаружите на Шаге 6, выполнение команд из пребывающего в списке запрещённых модуля, скорее всего завершится неудачей. В данном случае командлет Get-BpaModel применяет тип .NET, который отсутствует в .NET Core, в результате чего этот командлет не способен работать.

 

Рисунок 3-25


Пробуем применить Get-BpaModel

Механизм совместимости подразумевает, что многие старые модули Windows PowerShell будут применяться вашими старыми скриптами. Однако некоторые модули (как оказалось, всего три) нельзя применять непосредственно в PowerShell 7 или через механизм совместимости Windows PowerShell.

Есть кое- что ещё...

На Шаге 2 вы просматриваете файл конфигурации. Этот файл содержит два набора настроек. Первый формирует перечень запрещённых модулей, а прочие установки запускают политики исполнения. Вы можете воспользоваться командлетом Set-ExecutionPolicy для изменения установленной политики исполнения и в таком случае PowerShell записывает и обновляет версию данного файла, отражая такое обновление политики. Собственно перечень запрещённых модулей в данном файле конфигурации содержи три названия модулей, содержимое которых не знакомо с работой в PowerShell 7, как вы это наблюдали в предыдущих рецептах из этой главы.

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

В итоге, механизм совместимости Windows PowerShell позволяет вам применять большое число дополнительных команд в PowerShell 7. Этот механизм не идеален, поскольку он обладает несколькими ограничениями, однако в большинстве случаев этот рабочеспособный подход. Более того, хотя вы и можете поступать так, обход механизма совместимости в явном виде, скорее всего, не окажется полезным.

Импорт формата XML

PowerShell, даже с самого начала, отображал объекты автоматически и приглядно. По умолчанию, PowerShell отображает объекты и свойства для всех объектов. Когда подлежащий отображению объект содержит менее пяти свойств, он создаёт таблицу, иначе он создаёт список. PowerShell форматирует каждое свойство, вызывая для каждого из свойств метод .ToString().

Вы или разработчик командлета способны улучшить такой вывод при помощи формата XML. Формат XML это персонально написанный XML, который сохраняется в файле format.ps1XML. Этт файл формата сообщает PowerShell как в точности отображать конкретный тип объекта (в виде таблицы или списка), какие свойства отображать, какой заголовок применять (для таблиц) и как отображать индивидуальные свойства.

В Windows PowerShell, Microsoft включил определённые файлы форматов XML, которые вы можете обнаружить в домашней папке PowerShell. Вы можете просматривать их, набрав Get-ChileItem $PSHOME/*.format.ps1xml.

В PowerShell 7 определяемый по умолчанию формат XML располагается внутри самого кода каждой реализации командлета, вместо его представления в виде отдельного файла, как в Windows PowerShell. Как результат, в домашней папке PowerShell 7 $PSHOME нет никаких файлов format.ps1xml. Что касается Windows PowerShell, вы всегда способны написать свои собственные индивидуальные файлы формата XML для персонализации того как по умолчанию отображать объекты PowerShell.

Применение индивидуального формата XML является великолепным решением, когда вы отображаете определённые объекты, как правило, из командной строки, а установленное по умолчанию отображение не отвечает вашим целям. Вы можете реализовать формат XML, который сообщит PowerShell 7 отображать объекты в том виде, в котором вы пожелаете их выводить и импортировать соответствующий формат XML в свой файл профиля.

Некой альтернативой созданию формата является отправка конвейером соответствующего объекта в Format-Table или Format-List, причём определяя те свойства, которые вы бы желали отображать. Вы даже можете применять таблицы хэширования с Format-Table для определения того как форматировать свойства. В зависимости от того насколько часто вы отображаете некий конкретный объект, формат XML может оказаться полезным для изменения тех сведений, которые вы обозреваете, в особенности из консоли.

За получением дополнительных сведений относительно формата XML обратитесь к https://docs.microsoft.com/powershell/module/microsoft.powershell.core/about/about_format.ps1xml.

Разработчики модуля часто создают формат XML в помощь отображения вырабатываемых командами внутри такого модуля объектов. Модуль ServerManager, например, обладает форматом XML который делает привлекательным вывод, вырабатываемый Get-WindowsFeature. Этот модуль не поддерживается непосредственно в PowerShell 7.Благодаря описанному ранее в этой главе механизму совместимости с Windows PowerShell вы можете получать доступ к этим командам. Одним ограничением, по умолчанию, такого механизма совместимости выступает то, что он не импортирует формат XML (если таковой имеется). В итоге, результат подобного вывода может выглядеть иным образом, когда вы исполняете сценарии или активируете команды консоли в PowerShell 7 по сравнению с Windows PowerShell.

Самый простой способ обойти это состоит в импорте необходимого формата XML вручную, что вы увидите в данном рецепте.

Подготовка

Вы выполняете этот рецепт в SRV1, сервере Windows Server Datacenter Edition, в котором установлены PowerShell 7 и VS Code.

Как это сделать...

  1. Импортируем модуль ServerManager

    
    Import-Module -Name ServerManager
    		
  2. Проверяем функциональную возможность Windows

    
    Get-WindowsFeature -Name Simple-TCPIP
    		
  3. Выполняем эту команду в сеансе совместимости

    
    $S = Get-PSSession -Name 'WinPSCompatSession'
    Invoke-Command -Session $S -ScriptBlock {
        Get-WindowsFeature -Name Simple-TCPIP }
    		
  4. Выполняем эту команду с форматированием в соответствующем сеансе удалённого взаимодействия

    
    Invoke-Command -Session $S -ScriptBlock {
                        Get-WindowsFeature -Name Simple-TCPIP | 
                          Format-Table}
    		
  5. Получаем путь к модулям Windows PowerShell

    
    $Paths = $env:PSModulePath -split ';' 
    foreach ($Path in $Paths) {
      if ($Path -match 'system32') {$S32Path = $Path; break}
    }
    "System32 path: [$S32Path]"
    		
  6. Отображаем путь к фомату XML для модуля ServerManager

    
    $FXML = "$S32path/ServerManager"
    $FF = Get-ChildItem -Path $FXML\*.format.ps1xml 
    "Format XML file: [$FF]"
    		
  7. Обновляем свой формат XML

    
    Foreach ($F in $FF) {
      Update-FormatData -PrependPath $F.FullName}
    		
  8. Просматриваем функциональную возможность Simple-TCPIP Windows

    
    Get-WindowsFeature -Name Simple-TCPIP
    		
  9. Добавляем службу Simple-TCPIP

    
    Add-WindowsFeature -Name Simple-TCPIP
    		
  10. Изучаем функциональную возможность Simple-TCPIP

    
    Get-WindowsFeature -Name Simple-TCPIP
    		
  11. Применяем функциональную возможность Windows Simple-TCPIP

    
    Install-WindowsFeature Telnet-Client |
      Out-Null
    Start-Service -Name simptcp
    		
  12. Применяем службу Quote of the Day

    
    Telnet SRV1 qotd
    		

Как это работает...

На Шаге 1, внутри сеанса PowerShell 7.1, вы импортируете модуль ServerManager, при этом вывод выглядит так:

 

Рисунок 3-26


Импорт модуля ServerManager

На Шаге 2 вы проверяете функциональную возможность Windows службы Simple-TCPIP при помощи команды Get-WindowsFeature, которая производит вывод подобный следующему:

 

Рисунок 3-27


Испытываем свойство Simple-TCPIP

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

На Шаге 3 для исполнения командлета в удалённом сеансе Get-WindowsFeature вы применяете сеанс удалённого взаимодействия с Windows PowerShell. Получаемый вывод приводится ниже.

 

Рисунок 3-28


Выполняем команду Get-WindowsFeature в сеансе совместимости

На Шаге 2 и на Шаге 3 Get-WindowsFeature производит некий объект, который сеанс PowerShell 7 форматирует не применяя преимуществ формата XML.

На Шаге 4 вы выполняете команду Get-WindowsFeature для выполнения выборки выборку подробностей этой функциональной возможности, затем осуществляете форматирование в своём сеансе удалённого взаимодействия со следующим выводом:

 

Рисунок 3-29


Выполняем команду Get-WindowsFeature в сеансе удалённого взаимодействия

Теперь вы наблюдаете хорошо отформатированный Display Name заполненным, поскольку Windows PowerShell выполняет необходимое форматирование получаемого от командлета Get-WindowsFeature вывод полностью совместимым с самими сеансом совместимости, где имеется формат XML.

На Шаге 5 вы осуществляете синтаксический разбор значения переменной среды Windows PSModulePath для выявления значения пути по умолчанию к модулям Windows PowerShell. Этот путь содержит модули добавляемые центральными службами Windows и содержит и модуль ServerManager. Вывод этой команды подобен следующему:

 

Рисунок 3-30


Получаем значение пути к модулям Windows PowerShell

На Шаге 6 вы выявляете значение имени файла для формата XML модуля ServerManager, что снабжает нас таким выводом:

 

Рисунок 3-31


Выполняем выборку значения пути в формат XML для ServerManager

Большинство, но не все, модулей Windows обладают единственным файлом формата XML.

На Шаге 7, который не предоставляет вывода, вы обновляете полученные данные формата для своего текущего сеанса Windows PowerShell. Когда модуль обладает множеством файлов формата XML, данный подход обеспечивает импорт их всех.

На Шаге 8 вы просматриваете функциональную возможность Windows, службу Simple-TCPIP. Вот вывод этой команды:

 

Рисунок 3-32


Просматриваем Simple-TCPIP

На Шаге 9 вы добавляете свойство Simple-TCPIP к SRV1, что обеспечивает нам приводимый ниже вывод:

 

Рисунок 3-33


Добавляем Simple-TCPIP в SRV1

На нашем следующем Шаге 10 вы просматриваете вывод Simple-TCPIP, который теперь выглядит так:

 

Рисунок 3-34


Просматриваем Simple-TCPIP

Для проверки функциональности Simple-TCPIP вам надлежит установить клиента Telnet. Затем вы запускаете эту службу. Оба действия вы осуществляете на Шаге 11, который не производит вывод.

На Шаге 12 вы применяете протокол QOTD (Quote Of The Day). Вы можете применять QOTD для отладки проблем со связью, а также для измерения сетевой производительности. Определяет протокол QOTD RFC 8965; вы можете ознакомиться с определением протокола на https://tools.ietf.org/html/rfc865, а получить дополнительные сведения о применении QOTD в https://searchcio.techtarget.com/tip/Quote-of-the-Day-A-troubleshooting-networking-protocol.

Есть кое- что ещё...

На Шаге 1 вы импортируете модуль ServerManager. Это обеспечивает настройку сеанса удалённого взаимодействия совместимости с Windows. Если вы только что выполняли какие- либо более ранние рецепты из этой главы в том же самом сеанса PowerShell, этот шаг является избыточным, ибо сеанс удалённого взаимодействия совместимости уже был настроен и модуль ServerManager уже был загружен.

На Шаге 2 вы обнаруживаете, что вывод из Get-WindowsFeature не заполнил столбец Display Name. Аналогично и на Шаге 3. На обоих этих этапах PowerShell осуществляет базовое форматирование по умолчанию. На Шаге 4 вы получаете подробности соответствующего свойства Windows и выполняете форматирование всего в своём сеансе удалённого взаимодействия. Как вы можете видеть, в этом удалённом сеансе форматирование применяет формата XML для воспроизведения более совершенного вывода. В данном случае полученный формат XML заполняет соответствующее поле Display Name и добавляет некое указание того установлено это свойство или нет.

На Шаге 5 и на Шаге 6 вы выявляете папку модулей Windows PowerShell по умолчанию и находите название необходимого формата XML для этого модуля. Выявив название файла для искомого формата XML на Шаге 7 вы импортируете эти сведения формата. После импорта формата XML, на Шаге 8 вы исполняете командлет Get-WindowsFeature для просмотра функциональных возможностей Windows. Поскольку вы импортировали необходимый формат XML, получаемый результат вывода тот же самый, что и на Шаге 4.

Пользуемся совместимостью

В этой главе до сих пор мы рассматривали проблему совместимости между Windows Powershell и Powershell 7. Вы исследовали новые функциональные возможности в Powershell 7и рассмотрели механизм совместимости с Windows Powershell.

Такой механизм совместимости позволяет вам применять несовместимые командлеты Windows PowerShell в PowerShell 7. Несовместимые командлеты/ модули Windows PowerShell полагаются на функциональ8ные возможности, которые не представлены целиком в .NET CLR, но недоступны в .NET Core (и, скорее всего, никогда не будут добавлены в .NET Core). Например, командлет Get-WindowsFeature, применяющий тип .NET System.Diagnostics.Eventing.EventDescriptor, как вы видели ранее. Хотя этот командлет и не может естественным образом работать в PowerShell 7, описанный механизм совместимости позволяет вам применять функциональ8ные возможности этого командлета.

Когда Import-Module начинает загружать некий несовместимый модуль, он выполняет проверку наличия сеанса удалённого взаимодействия с названием WinPSCompatSession. Когда такой сеанс имеется, PowerShell применяет его. Если он не существует, Import-Module создаёт новый сеанс удалённого взаимодействия с таким названием. Затем PowerShell 7 импортирует необходимый модуль в созданный удалённый сеанс и создаёт в своём сеансе PowerShell 7 функции- посредники (прокси).

После того как Import-Module создал необходимый сеанс удалённого взаимодействия, PowerShell применяет этот единственный сеанс для всех используемых функциональных возможностей, поэтому загружаемые модули применяют единственный сеанс удалённого взаимодействия.

Подготовка

Вы выполняете этот рецепт в SRV1, в котором вы установили PowerShell 7 и VS Code. SRV1 является сервером рабочей группы, запущенным с Windows Server Datacenter Edition.

Как это сделать...

  1. Создайте сеанс с зарезервированным названием

    
    $S1 = New-PSSession -Name WinPSCompatSession -ComputerName SRV1
    		
  2. Получите загруженные в этом сеансе удалённого взаимодействия модули.

    
    Invoke-Command -Session $S1 -ScriptBlock {Get-Module}
    		
  3. Загрузите в этот сеанс удалённого взаимодействия модуль ServerManager

    
    Import-Module -Name ServerManager -WarningAction SilentlyContinue |
      Out-Null
    		
  4. Получите загруженные в этом сеансе удалённого взаимодействия модули.

    
    Invoke-Command -Session $S1 -ScriptBlock {Get-Module}
    		
  5. Воспользуйтесь Get-WindowsFeature

    
    Get-WindowsFeature -Name PowerShell
    		
  6. Закройте сеансы удалённого взаимодействия и удалите модули из текущего сеанса PS7

    
    Get-PSSession | Remove-PSSession
    Get-Module -Name ServerManager | Remove-Module
    		
  7. Создайте сеанс совместимости удалённого взаимодействия по умолчанию

    
    Import-Module -Name ServerManager -WarningAction SilentlyContinue
    		
  8. Получите этот новый удалённый сеанс

    
    $S2 = Get-PSSession -Name 'WinPSCompatSession'
    $S2
    		
  9. Исследуйте модули в WinPSCompatSession

    
    Invoke-Command -Session $S2 -ScriptBlock {Get-Module}
    		

Как это работает...

На Шаге 1 вы создаёте новый сеанс удалённого взаимодействия, применяя название сеанса WinPSCompatSession. Этот шаг не создаёт вывода, но он реально создаёт удалённый сеанс к терминальной точке WIndows PowerShell. PowerShell 7 сохраняет значение названия той конечной точки, которую использует New-PSSession, только если вы воспользуетесь параметром ConfigurationName для определения альтернативного имени конфигурации при создании соответствующего нового сеанса.

На Шаге 2 вы исполняете командлет Get-Module для исполнения загруженных в настоящий момент модулей в том сеансе удалённого взаимодействия, который вы настроили на Шаге 1. Для этого шага PowerShell не вырабатывает никакого вывода, что указывает на то, что до сих пор в этот удалённый сеанс не было импортировано никаких модулей.

На Шаге 3 вы импортируете модуль ServerManager. Поскольку этот модуль не совместим с PowerSell 7, PowerSell применяет сеанс совместимости с Windows PowerSell, который вы создали ранее. Import-Module только проверяет что уже имеется сеанс удалённого взаимодействия с названием WinPSCompatSession. Этот этап не вырабатывает вывод.

На Шаге 4 вы повторно проверяете загруженный в свой сеанс удалённого взаимодействия модули. Как вы можете обнаружить, эта команда обнаружила загруженными в удалённом сеансе два модуля, причём одним из них является модуль Windows PowerShell ServerManager. Получаемый на этом этапе вывод выглядит следующим образом:

 

Рисунок 3-35


Получение загруженных в сеансе удалённого взаимодействия модулей

На Шаге 5 вы активируете Get-WindowsFeature для выявления искомой функциональности PowerShell. Как вы можете обнаружить из полученного вывода, это свойство и доступно и установлено в SRV1:

 

Рисунок 3-36


Активация Get-WindowsFeature

На Шаге 6 вы закрываете тот сеанс удалённого взаимодействия, который вы создали ранее в этом рецепте и удаляете все загруженный модули. Этот шаг не вырабатывает вывод. На Шаге 7 вы импортируете необходимый модуль ServerManager (не совместимый с PowerShell 7). Как вы уже наблюдали ранее, эта команда создаёт совместимый сеанс, хотя и не производит никакого вывода на этом этапе.

На Шаге 8 вы получаете, а затем отображаете тот сеанс удалённого взаимодействия, который производит следующий вывод:

 

Рисунок 3-37


Получение загруженных в сеансе удалённого взаимодействия модулей

На Шаге 9 вы выполняете просмотром проверку тех модулей, которые были загружены в имеющемся сеансе совместимости с Windows (который мы создали на Шаге 7 при импорте модуля). Вывод с этого шага выглядит подобно приводимому ниже:

 

Рисунок 3-38


Проверка модулей, загруженных в сеансе удалённого взаимодействия

Есть кое- что ещё...

В этом рецепте вы создали два сеанса удалённого взаимодействия PowerShell. На Шаге 1 вы создали его в явном виде при помощи New-PSSession. Позднее, на Шаге 7, вы вызвали Import-Module для импорта некого несовместимого модуля. Затем Import-Module создаёт сеанс удалённого взаимодействия, поскольку тот отсутствует.

Как вы можете видеть из данного рецепта, до тех пор, пока имеется сеанс удалённого взаимодействия с названием WinPSCompatSession, Import-Module применяет его для загрузки, в данном случае, модуля ServerManager.

Одним из потенциальных применений показанного в этом рецепте подхода может быть то, когда вы желаете создать некую ограниченную терминальную точку для применения с делегируемым администрированием, которая полагается на более старые командлеты Windows PowerSehell. Вы можете создать подробности конфигурации такой терминальной точки, а затем, в своих сценариях, создаёте сеанс удалённо взаимодействия, применяя соответствующую персонализированную терминальную точку и зарезервированное название сеанса WinPSCompatSession.