Модуль WindowsCompatibility

В статье, посвященной PowerShell Core 6.1 (опубликована в Windows IT Pro/RE № 12 за 2018 год. — Прим. ред.), упоминалось о том, что одним из основных направлений данного релиза платформы является обеспечение совместимости с модулями, изначально предназначенными для использования в Windows PowerShell. Многие из этих модулей на данный момент не поддерживают работу в PowerShell Core. К числу таких модулей относятся и те, которые входят в состав операционной системы Windows, как клиентской, так и серверной редакций. И хотя в операционных системах Windows 10 версии 1809 и Windows Server 2019 многие из них были адаптированы для использования в PowerShell Core, тем не менее все еще существует достаточное количество модулей, которые способны функционировать только в Windows PowerShell. Именно для того, чтобы иметь возможность использовать входящие в них команды, и был создан модуль WindowsCompatibility.

Модуль WindowsCompatibility

Сначала давайте разберемся с несколькими основополагающими вопросами. В чем состоит принцип работы этого модуля? Модуль WindowsCompatibility позволяет при работе в PowerShell Core использовать команды, работа которых на данный момент возможна только в Windows PowerShell. Для чего это нужно? Необходимость в этом может возникнуть в тех случаях, когда для решения какой-либо задачи вам потребуются и возможности PowerShell Core, и команды Windows PowerShell.

В двух своих версиях, 6.0 и 6.1, PowerShell Core приобрел немало полезных функций, недоступных в Windows PowerShell, и можно предположить, что с течением времени отрыв будет только увеличиваться.

Как обеспечивается совместимость? Модуль WindowsCompatibility предоставляет некоторую функциональность, позволяющую подходить к проблеме с разных сторон, однако основной используемый им механизм — запуск несовместимых с PowerShell Core команд в той среде, для которой они изначально и были созданы, — Windows PowerShell.

Перед тем как перейти к рассмотрению команд модуля WindowsCompatibility, давайте поговорим о переменной среды PSModulePath.

Переменная среды PSModulePath

Эта переменная хранит пути, по которым расположены модули, доступные для использования в PowerShell. Именно ее содержимое позволяет PowerShell найти и автоматически импортировать определенный модуль при вызове некой ранее не использовавшейся в сессии команды.

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

Получить текущее значение этой переменной из PowerShell вы можете с помощью следующей команды:

$Env: PSModulePath.

Однако, запустив ее из Windows PowerShell и PowerShell Core, вы увидите, что ее значения будут разными, как показано на рисунке 1. Мало того, если вы получите значение этой переменной для локального компьютера (а не для процесса, как в предыдущих случаях), оно также будет отличаться (рисунок 2).

Содержимое переменной среды PSModulePath в различных окружениях
Рисунок 1. Содержимое переменной среды PSModulePath в различных окружениях
Содержимое переменной среды PSModulePath для локального компьютера
Рисунок 2. Содержимое переменной среды PSModulePath для локального компьютера

Что же касается пользовательской переменной среды PSModulePath, то по умолчанию она отсутствует, как видно на рисунке 3. Дело в том, что и Windows PowerShell, и PowerShell Core при запуске задают значение для переменной текущего процесса (powershell. exe и pwsh. exe, соответственно) самостоятельно. И если в случае Windows PowerShell ее значение основывается на одноименной системной переменной, то PowerShell Core не использует данные процесса вовсе.

Содержимое переменной среды PSModulePath для пользователя
Рисунок 3. Содержимое переменной среды PSModulePath для пользователя

Windows PowerShell

Значение переменной среды PSModulePath для процесса создается следующим образом. Если определена пользовательская переменная среды PSModulePath (как мы уже видели, по умолчанию она отсутствует), то переменная процесса будет содержать это значение, сопровождаемое значением переменной локального компьютера. Таким образом, если переменная среды PSModulePath для пользователя содержит значение

C:\username\Modules

а системная переменная — значение по умолчанию

C:\Program Files\WindowsPowerShell\
  Modules;
C:\Windows\system32\Windows
  PowerShell\v1.0\Modules

то содержимое переменной PSModulePath процесса powershell. exe будет следующим:

C:\username\Modules;
C:\Program Files\WindowsPowerShell\
  Modules;
C:\Windows\system32\WindowsPowerShell\
  v1.0\Modules

Если же пользовательской переменной PSModulePath не существует, то предшествовать значению переменной локального компьютера будет следующий путь:

%USERPROFILE%\Documents\
  WindowsPowerShell\Modules

Соответственно результатом будет

%USERPROFILE%\Documents\
  WindowsPowerShell\Modules;
C:\Program Files\WindowsPowerShell\
  Modules;
C:\Windows\system32\WindowsPowerShell\
  v1.0\Modules

что и является значением по умолчанию.

PowerShell Core

В версии 6.0 (в нашем случае — 6.0.5) значение переменной среды PSModulePath для процесса pwsh. exe, вне зависимости от значений системной или пользовательской переменных, будет следующим:

%USERPROFILE%\Documents\PowerShell\
  Modules;
C:\Program Files\PowerShell\Modules;
c:\program files\powershell\6.0.5\Modules

В версии 6.1 к значению этой переменной был добавлен путь C:\Windows\system32\WindowsPowerShell\v1.0\Modules, позволяющий задействовать модули, входящие в операционную систему и изначально созданные для использования в Windows PowerShell. В итоге значение переменной среды PSModulePath в PowerShell Core 6.1 выглядит следующим образом:

%USERPROFILE%\Documents\PowerShell\
  Modules;
C:\Program Files\PowerShell\Modules;
c:\program files\powershell\6\Modules;
C:\Windows\system32\WindowsPowerShell\
  v1.0\Modules

Вопросы совместимости расположенных по пути C:\Windows\system32\WindowsPowerShell\v1.0\Modules модулей с PowerShell Core решаются за счет использования свойства CompatiblePSEditions объекта модуля. Это свойство может содержать следующие значения: ‘Desktop’ и ‘Core’.

‘Desktop’ говорит о том, что данный модуль совместим с Windows PowerShell. Значение ‘Core’ сообщает о совместимости модуля с PowerShell Core. Свойство CompatiblePSEditions модуля, совместимого с обеими версиями PowerShell, будет содержать оба значения. Если же это свойство какого-либо значения не содержит, то считается, что данный модуль совместим только с Windows PowerShell, что соответствует значению ‘Desktop’.

Определить, является ли тот или иной модуль совместимым с PowerShell Core, вы можете при помощи команды Get-Module с параметром ListAvailable, как показано на рисунке 4.

Проверка совместимости модуля с PowerShell Core
Рисунок 4. Проверка совместимости модуля с PowerShell Core

Таким образом, PowerShell Core 6.1 позволяет вам задействовать некоторые, явным образом помеченные как совместимые модули, расположенные в каталоге установки Windows PowerShell. Однако это не касается модулей, расположенных в каталоге C:\Program Files\WindowsPowerShell\Modules, а также тех, что находятся в пользовательском профиле: $HOME\Documents\WindowsPowerShell\Modules.

Add-WindowsPSModulePath

Команда Add-WindowsPSModulePath (равно как и ее псевдоним — Add-WinPSModulePath) позволяет добавить к используемой в текущей сессии PowerShell Core переменной среды PSModulePath все пути расположения модулей, определенные для Windows PowerShell и по умолчанию в PowerShell Core недоступные. Использование этой команды добавляет к переменной среды PSModulePath процесса pwsh. exe пути, показанные на рисунке 5.

Добавление путей к PSModulePath
Рисунок 5. Добавление путей к PSModulePath

Кроме того, добавляются те, что определены в переменных среды PSModulePath пользователя и локального компьютера, не равные приведенным выше. Например, в случае соответствия переменной среды PSModulePath значению по умолчанию результат выполнения этой команды в PowerShell Core 6.1 будет таким, как на рисунке 6.

Пути для переменной среды PSModulePath по умолчанию
Рисунок 6. Пути для переменной среды PSModulePath по умолчанию

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

Add-Content -Path $PROFILE -Value
  "`nAdd-WindowsPSModulePath"

Также следует уточнить, что в Power­Shell Core 6.1 значение упомянутого выше свойства CompatiblePSEditions объекта модуля применяется только к модулям, расположенным по пути C:\Windows\system32\WindowsPowerShell\v1.0\Modules, и не оказывает никакого влияния на модули, в этом каталоге не расположенные. В PowerShell Core 6.0 значение данного свойства не рассматривается вовсе.

Таким образом, команда Add-WindowsPSModulePath позволяет вам задействовать ранее недоступные из PowerShell Core модули путем добавления к переменной среды PSModulePath процесса pwsh. exe всех используемых Windows PowerShell путей их расположения.

Что касается остальных команд модуля WindowsCompatibility, то их работа основывается на прямом взаимодействии с Windows PowerShell, и одной из наиболее важных частей этого взаимодействия является команда Initialize-WinSession.

Initialize-WinSession

Команда Initialize-WinSession предназначена для создания и управления удаленными подключениями к Windows PowerShell, расположенному как на локальном компьютере, так и на любом другом.

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

Будучи вызванной без параметров, команда Initialize-WinSession устанавливает подключение к Windows PowerShell на локальном компьютере с использованием набора настроек Microsoft. PowerShell. Увидеть результаты ее работы вы можете при помощи команды Get-PSSession (рисунок 7).

Результаты работы команды Initialize-WinSession
Рисунок 7. Результаты работы команды Initialize-WinSession

Имя создаваемой сессии строится следующим образом: wincompat-имя_компьютера-имя_пользователя. Для того чтобы подключиться к другому компьютеру или использовать настройки сессии, отличные от Microsoft. PowerShell, вы можете воспользоваться параметрами ComputerName и ConfigurationName соответственно.

Параметр Credential позволяет указать требуемые учетные данные, а использование параметра PassThru приведет к тому, что команда Initialize-WinSession возвратит созданную ею сессию как объект. По умолчанию она этого не делает.

При каждом запуске команда проверяет наличие сессии, соответствующей указанным параметрам и в случае ее отсутствия создает новую. Если же такая сессия существует, то будет использоваться она. К примеру, если мы вызовем команду Initialize-WinSession еще раз, теперь с параметром PassThru, то увидим, что будет возвращена та же самая сессия (рисунок 8).

Initialize-WinSession с параметром PassThru
Рисунок 8. Initialize-WinSession с параметром PassThru

Get-WinModule

Команда Get-WinModule позволяет вам получить информацию обо всех доступных в Windows PowerShell модулях, хотя и за некоторым исключением. Дело в том, что Get-WinModule не отображает те модули, чья функциональность реализована в PowerShell Core в полном объеме. К ним относятся: PSReadLine, PackageManagement, PowerShellGet, Microsoft. PowerShell. Archive и Microsoft. PowerShell. Host. Также в этот список, известный как NeverImportList, входит и модуль WindowsCompatibility, на случай если он вдруг присутствует среди модулей Windows PowerShell, хотя и предназначен исключительно для использования в PowerShell Core.

Без применения каких-либо параметров команда выведет список доступных в Windows PowerShell модулей, как показано на рисунке 9. Причем это могут быть модули, уже доступные из PowerShell Core, например в случае PowerShell Core версии 6.1 — модули, расположенные по пути C:\Windows\system32\WindowsPowerShell\v1.0\Modules.

Результаты запуска Get-WinModule
Рисунок 9. Результаты запуска Get-WinModule

Команда Get-WinModule обладает параметром Name, который позволяет вам указать массив имен интересующих вас модулей. Также вы можете использовать символы подстановки. Например, так, как показано на рисунке 10.

Get-WinModule поддерживает символы подстановки
Рисунок 10. Get-WinModule поддерживает символы подстановки

Кроме параметров, уже известных нам по предыдущей команде, таких как ComputerName, ConfigurationName и Credential, которые позволяют нам подключиться к другому компьютеру, настройкам сессии или же осуществить подключение с использованием иной учетной записи, команда Get-WinModule обладает параметром Full. По умолчанию команда Get-WinModule отображает только три свойства объекта модуля — Name, Version и Description. Если же мы хотим получить объекты целиком, то можем воспользоваться этим параметром (рисунок 11).

Get-WinModule с параметром Full
Рисунок 11. Get-WinModule с параметром Full

Compare-WinModule

Команда Compare-WinModule, в отличие от предыдущей команды, выводит только те модули Windows PowerShell, которые недоступны из PowerShell Core. Чем она похожа на команду Get-WinModule, так это тем, что в своей работе тоже использует список NeverImportList. Соответственно результаты ее работы точно так же не будут включать в себя информацию о модулях PSReadLine, PackageManagement, PowerShellGet, Microsoft. PowerShell. Archive, Microsoft. PowerShell. Host и WindowsCompatibility.

При сравнении модулей PowerShell Core с модулями, доступными из Windows PowerShell, команда Compare-WinModule использует два свойства — Name и Version. Таким образом, если обе редакции PowerShell содержат некий модуль с одним и тем же именем, но с разными номерами версий, информация о нем будет выведена командой (рисунок 12).

Результаты работы Compare-WinModule
Рисунок 12. Результаты работы Compare-WinModule

Команда Compare-WinModule обладает уже знакомыми нам параметрами — Name, ComputerName, ConfigurationName и Credential.

Copy-WinModule

Команда Copy-WinModule позволяет скопировать модуль из каталога модулей для Windows PowerShell в папку, доступную для PowerShell Core. Точно так же, как и другие команды, Copy-WinModule обладает параметрами Name, ComputerName, ConfigurationName и Credential.

Еще одним параметром, доступным для использования с командой Copy-WinModule, является Destination. Без использования этого параметра копирование модуля происходит в каталог модулей для PowerShell Core, расположенный в пользовательском профиле: C:\Users\username\Documents\PowerShell\Modules. Если же вам нужно, чтобы модуль был скопирован в некоторое отличное от значения по умолчанию расположение, вы можете указать его в качестве значения этого параметра.

Естественно, для того чтобы при вызове входящей в него команды скопированный модуль был импортирован в сессию PowerShell автоматически, он должен находиться по одному из путей расположения модулей PowerShell Core. Если же модуль был скопирован в какое-либо другое место, то перед использованием он должен быть импортирован при помощи команды Import-Module.

Основная особенность команды Copy-WinModule заключается в том, что копирование происходит только для строго определенных модулей — тех, что указаны в списке совместимых модулей CompatibleModules.

В него входят следующие модули: AppBackgroundTask, AppLocker, Appx, AssignedAccess, BitLocker, BranchCache, CimCmdlets, ConfigCI, Defender, DeliveryOptimization, DFSN, DFSR, DirectAccessClientComponents, Dism, EventTracingManagement, GroupPolicy, Hyper-V, International, IscsiTarget, Kds, MMAgent, MsDtc, NetAdapter, NetConnection, Net­Security, NetTCPIP, NetworkConnectivityStatus, NetworkControllerDiagnostics, NetworkLoadBalancingClusters, NetworkSwitchManager, NetworkTransition, PKI, PnpDevice, PrintManagement, ProcessMitigations, Provisioning, PSScheduledJob, ScheduledTasks, SecureBoot, SmbShare, Storage, TrustedPlatformModule, VpnClient, Wdac, WindowsDeveloperLicense, WindowsErrorReporting, WindowsSearch и WindowsUpdate.

Исключение составляют модули, созданные на основе файлов cdxml — Cmdlet Definition Xml. Данные файлы позволяют создавать команды PowerShell динамически, на основе содержащейся в них информации, описывающей принципы взаимодействия создаваемых команд со свойствами и методами классов CIM — Common Information Model.

Так как PowerShell Core полностью поддерживает работу с классами CIM, можно с достаточной степенью уверенности предположить, что и модули, их использующие, также будут совместимы (рисунок 13).

Результаты работы Copy-WinModule
Рисунок 13. Результаты работы Copy-WinModule

Взаимодействие PowerShell Core и Windows PowerShell

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

Однако как же быть с теми модулями, что не поддерживают работу в PowerShell Core вовсе или чья функциональность в этой среде является явно недостаточной? Здесь стоит задуматься о том, что же нам в действительности нужно от этих команд. На самом деле нам нужен не сам факт их выполнения в PowerShell Core, а лишь возвращаемые ими результаты. Таким образом, ничто нам не мешает выполнять недоступные команды в их родной среде — Windows PowerShell, а результаты выполнения использовать в PowerShell Core. Именно на этом и основана работа оставшихся команд модуля WindowsCompatibility.

Import-WinModule

Команда Import-WinModule использует механизм, известный как Implicit Remoting, то есть прозрачное выполнение команд в удаленной сессии. Она позволяет импортировать модуль Windows PowerShell в текущую сессию PowerShell Core, так что все входящие в него команды будут нам доступны. Однако, будучи вызванными, реально эти команды будут выполняться в среде Windows PowerShell, возвращая результаты своего выполнения в PowerShell Core.

Команда Import-WinModule, как и команды Get-WinModule и Compare-WinModule, руководствуется в своей работе списком NeverImportList, то есть она не позволяет импортировать те модули, чья функциональность присутствует в PowerShell Core в полном объеме.

Кроме того, команда Import-WinModule предусматривает особый подход к следующим модулям:

  • Microsoft.PowerShell.Management;
  • Microsoft.PowerShell.Utility;
  • Microsoft.PowerShell.Security;
  • Microsoft.PowerShell.Diagnostics.

Этот список известен как Never­ClobberList.

Дело в том, что данные модули, хотя и присутствуют в PowerShell Core, однако по сравнению с Windows PowerShell содержат меньшее количество команд. Поэтому при их импорте в PowerShell Core нам не требуется импортировать все содержащиеся в них команды, а только те из них, что в данной среде отсутствуют.

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

Новое имя модуля строится следующим образом: оригинальное_имя. WinModule. Таким образом, если при помощи команды Import-WinModule мы импортируем модуль Windows PowerShell Microsoft.PowerShell.Management в PowerShell Core, то значиться в этой среде он будет уже как Microsoft.PowerShell.Management. WinModule и содержать в себе будет лишь те команды, что отсутствуют в модуле Microsoft.PowerShell.Management, входящем в PowerShell Core (рисунок 14).

Результаты работы Import-WinModule
Рисунок 14. Результаты работы Import-WinModule

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

Кроме уже известных нам параметров Name, ComputerName, Configura­tionName и Credential, команда Import-WinModule обладает параметрами, свойственными еще одной команде для работы с модулями — Import-Module. Это параметры Prefix, DisableNameChecking, NoClobber, Force, PassThru и Exclude.

Prefix. Параметр Prefix позволяет добавить к имени каждой импортированной команды указанный префикс, на случай если в текущей сессии уже присутствует команда с таким же именем и мы не хотим, чтобы вследствие импорта она была скрыта или переопределена. Например, так, как показано на рисунке 15.

Параметр Prefix в команде Import-WinModule
Рисунок 15. Параметр Prefix в команде Import-WinModule

DisableNameChecking. Параметр DisableNameChecking предотвращает вывод предупреждающего сообщения, если в импортируемом модуле присутствуют команды, имена которых не соответствуют стандартам именования PowerShell.

Как известно, рекомендованный подход к именованию команд в PowerShell предполагает связку «глагол-существительное». Первая часть имени описывает действие, а вторая — объект, над которым это действие производится. Например: Get-Process, Stop-Service и т. д. И если вторая часть имени может быть абсолютно произвольной, то первая, то есть действие, должна соответствовать утвержденному списку, ознакомиться с которым вы можете, введя команду Get-Verb.

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

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

Force. Параметр Force реимпортирует модуль в текущую сессию. По умолчанию задача команд Import-Module и Import-WinModule заключается в том, чтобы удостовериться, что некий модуль был импортирован. При вызове этих команд без параметра Force в случае, если указанный модуль уже был импортирован ранее (явным образом — с использованием одной из этих же самых команд или, для модулей, расположенных в каталогах, указанных в переменной среды PSModulePath, автоматически), его повторного импорта не происходит, даже если файлы этого модуля были изменены. Параметр Force позволяет принудительно реимпортировать модуль, вне зависимости от его присутствия в текущей сессии.

PassThru. Использование параметра PassThru приводит к тому, что команда возвращает объект импортированного модуля. По умолчанию этого не происходит.

Exclude. Команда Import-WinModule обладает параметром Exclude, позволяющим указать имена модулей, которые импортировать не требуется. Например, чтобы импортировать все доступные в Windows PowerShell модули, чьи имена начинаются c Net, однако пропустить модули, начинающиеся с Network, мы можем выполнить команду, приведенную на рисунке 16.

Import-WinModule обладает параметром Exclude
Рисунок 16. Import-WinModule обладает параметром Exclude

Invoke-WinCommand

Команда Invoke-WinCommand позволяет выполнить произвольный блок сценария. При этом, как и в предыдущем случае, его фактическое выполнение будет происходить в Windows PowerShell (рисунок 17).

Команда Invoke-WinCommand
Рисунок 17. Команда Invoke-WinCommand

Кроме того, при помощи параметра ArgumentList вы можете указать необходимые для вашего блока сценария аргументы. Параметр принимает массив значений для определенных в блоке сценария параметров и назначает их в той последовательности, в которой они были указаны (рисунок 18). При этом, так же как и при обычном выполнении команд в удаленной сессии, вы можете указать локальные переменные непосредственно в блоке сценария при помощи модификатора Using (рисунок 19).

Команда Invoke-WinCommand с параметром ArgumentList
Рисунок 18. Команда Invoke-WinCommand с параметром ArgumentList
Команда Invoke-WinCommand с параметром Using
Рисунок 19. Команда Invoke-WinCommand с параметром Using

Что касается остальных параметров команды, а именно ComputerName, ConfigurationName и Credential, то их функциональность соответствует одноименным параметрам предыдущих команд.

Add-WinFunction

Команда Add-WinFunction позволяет создать в текущей сессии функцию, выполнение которой будет происходить в среде Windows PowerShell. Имя функции задается параметром Name, а ее тело — параметром ScriptBlock. Создаваемые при помощи команды Add-WinFunction функции поддерживают использование параметров, однако при их вызове вы можете указать только значения. При сопоставлении полученных функцией аргументов определенным в функции параметрам используется логика позиционных параметров (рисунок 20).

Пример использования Add-WinFunction
Рисунок 20. Пример использования Add-WinFunction

Как уже говорилось выше, команда Add-WinFunction создает указанную функцию в текущей сессии. Для того чтобы созданные вами функции были доступны в каждой сессии, потребуется указать определения этих функций в профиле PowerShell. Другой способ предполагает создание отдельного модуля, содержащего нужные функции. Например, если мы создадим файл с именем WinFunctions. psm1 и следующим содержимым:

$GetHotFix = {
  Param ($Id)
  Get-HotFix @PSBoundParameters
}
Add-WinFunction -Name Get-HotFix
  -ScriptBlock $GetHotFix

и сохраним его в качестве модуля в каталоге C:\Program Files\PowerShell\

Modules\WinFunctions, то, импортировав его в текущую сессию, получим доступ ко всем определенным в файле функциям.

Стоит сказать, что в данном случае, несмотря на то что определения функций находятся в файле модуля и их инициализация происходит при его импорте, сами функции после того, как были созданы, уже не являются частью этого модуля (рисунок 21).

Инициализация функций при импорте модуля
Рисунок 21. Инициализация функций при импорте модуля

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

Как и большинство других команд модуля WindowsCompatibility, Add-WinFunction позволяет указать имя нужного компьютера при помощи параметра ComputerName, имя набора настроек сессии при помощи параметра ConfigurationName и нужные учетные данные при помощи параметра Credential.

Сериализация объектов

Хотя набор инструментов, состоящий из команды Invoke-WinCommand и функций, созданных при помощи команды Add-WinFunction, пусть даже и дополненный командами, что были импортированы в составе модулей с использованием команды Import-WinModule, позволяет вам выполнять ранее недоступные в PowerShell Core инструкции, тем не менее результаты их выполнения не являются точной копией данных, возвращаемых командами, выполненными в Windows PowerShell явным образом.

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

Таким образом, полученные объекты не обладают какими-либо свойственными им методами, за исключением GetType и ToString. Например, у вас не получится вызвать тот или иной метод полученного при помощи команды Get-WMIObject объекта (рисунок 22).

Работа с объектом Get-WMIObject
Рисунок 22. Работа с объектом Get-WMIObject 

Для того чтобы данными методами все-таки воспользоваться, вам потребуется обратиться к ним непосредственно в удаленной сессии, например при помощи команды Invoke-WinCommand, как показано на рисунке 23.

Удаленная сессия при помощи команды Invoke-WinCommand
Рисунок 23. Удаленная сессия при помощи команды Invoke-WinCommand

На пути к совместимости

В дополнение ко всем новшествам PowerShell Core 6.1, таким как интеграция Windows Compatibility Pack для. NET Core, добавление пути C:\Windows\system32\WindowsPowerShell\v1.0\Modules в переменную среды PSModulePath и адаптация входящих в операционную систему модулей, модуль WindowsCompatibility — это еще один шаг к тому, чтобы восполнить недостающую функциональность PowerShell Core по сравнению с Windows PowerShell и сделать его основным инструментом для управления и автоматизации.