Глава 18. Сеансы: удалённое управление с меньшей работой
В Главе 13 мы представили вам введение в функциональные возможности
удалённого взаимодействия PowerShell. В той главе вы пользовались двумя первичными командлетами -
Invoke-Command
и Enter-PSSession
- для доступа
как с управлением дин- ко- многим, так и один- к- одному. Эти два командлета работают посредством создания нового удалённого
подключения, выполняя все определяемую вами работу, а затем закрывают такое соединение.
В таком подходе нет ничего плохого, однако может быть утомительным постоянное указание имён компьютеров, учётных данных, альтернативных номеров портов и т.п.. В данной главе вы познакомитесь с более простым и многоразовым вариантом удалённого взаимодействия. Также вы узнаете о третьем способе применения удалённого взаимодействия, носящего название неявного удалённого взаимодействия, который делает для вас возможным добавлять промежуточные (прокси) команды путём импорта модуля из удалённого компьютера в удалённый сеанс.
Всякий раз когда вы подключаетесь к некому удалённому компьютеру при помощи Invoke-Command
или Enter-PSSession
, вам приходится, по крайней мере, определять название компьютера
(или компьютеров, когда вы активируете команду во множестве компьютеров). В зависимости от вашей среды, вам также может быть
приходится задавать альтернативные полномочия, что означает получение приглашение на ввод пароля. Вам также может потребоваться
определять альтернативные порты или механизмы аутентификации, в зависимости от того как ваша организация настроила удалённое
взаимодействие.
Нет ничего сложного в том, чтобы указывать это, но может оказаться утомительным повторять такой процесс снова и снова. К счастью, мы знаем лучший вариант: многоразовые сеансы.
Замечание | |
---|---|
Все примеры из этой главы могут быть выполнены только когда у вас имеется другой компьютер для подключения и если в нём разрешено удалённое взаимодействие PS. Для дополнительных сведений отсылаем вас к Главе 13. |
Сеанс это постоянное соединение между вашей копией PowerShell и удалённой копией PowerShell. Когда этот сеанс активен, и ваш компьютер, и удалённая машина обрекают небольшие объём памяти и процессорного времени на поддержку данного подключения. Тем не менее, при таком соединении вовлечён в процесс небольшой обмен. PowerShell поддерживает список всех имеющихся открытыми вами сеансов и вы можете применять эти сеансы для активации команд или для входа в удалённую оболочку.
Для создания нового сеанса пользуйтесь известным командлетом New-PSSession
.
Определите значение имени компьютера или названия хоста (или названий) и, когда необходимо, определите альтернативные имя
пользователя, порт, механизм аутентификации и тому подобное. Давайте также не забывать, что мы можем в противовес WinRM
использовать SSH, применяя параметр -hostname
. В любом случае, получаемым результатом
будет объект сеанса, который сохраняется в памяти PowerShell:
PS C:\> new-pssession -computername srv02,dc17,print99
PS C:\> new-pssession -hostname LinuxWeb01,srv03
Для выборки этих сеансов выполните Get-PSSession
:
PS C:\> get-pssession
Совет | |
---|---|
Как упоминалось в Главе 13, при применении параметра
|
Хотя это работает, мы предпочитаем создавать свой сеанс и немедленно сохранять его в переменной для доступа к сеансу
позднее. Например, Юлия имеет множество веб серверов, для которых она повседневно изменяет конфигурацию при помощи
Invoke-Command
. Для упрощения этого процесса она сохраняет эти сеансы в определённой
переменной:
PS C:\> $iis_servers = new-pssession -computername web01,web02,web03 -credential WebAdmin
PS C:\> $web_servers = new-pssession -hostname web04,web05,web06 -username WebAdmin
Никогда не забывайте, что такие сеансы потребляют ресурсы. Когда вы закрываете свою оболочку, они закроются автоматически, однако когда вы не пользуетесь ими активно, хорошей мыслью является закрытие их вручную даже когда вы планируете продолжать пользоваться своей оболочкой для прочих задач, а потому вы не связываете ресурсы своей машины или соответствующей удалённой машины.
Для закрытия сеанса воспользуйтесь командлетом Remove-PSSession
. Например,
для закрытия только сеансов IIS, воспользуйтесь следующей командой:
PS C:\> $iis_servers | remove-pssession
Или, когда вы желаете закрыть все открытые сеансы, применяйте следующую команду:
PS C:\> get-pssession | remove-pssession
Это достаточно просто.
Однако если вы получаете поднятым и исполняемым некий сеанс, что вы с ним будете делать? Для своих следующих пары разделов
мы предполагаем что вы создали переменную с названием $sessions
, которая содержит
по крайней мере два сеанса. Мы будем применять localhost
и
SRV02
(вам следует обозначить свои собственные названия компьютеров). Применение
localhost
не является мошенничеством: PowerShell запускает реальный удалённый сеанс с
другой своей копией. Имейте в виду, что всё это работает только когда вы разрешили удалённое взаимодействие во всех
компьютерах, к которым вы подключены,, а потому если у вас не включено удалённое взаимодействие, повторите
Главу 13.
Испробуйте это сейчас
Начните следовать за нами и выполняйте эти команды и убедитесь что применяете допустимые названия компьютеров. Если у вас
есть только один компьютер, пользуйтесь и его названием, и localhost
. К счастью,
если у вас также имеются машины с запущенными macOS и Linux, вы также можете работать и с ними.
Дополнительно | |
---|---|
Существует классный синтаксис, который позволяет создавать несколько сеансов при помощи одной команды и присваивать каждому сеансу уникальную переменную (вместо того чтобы объединять их все в одну переменную, как мы это делали ранее):
Такой синтаксис помещает значения сеансов для Однако будьте осторожны: мы наблюдали ситуации, когда конкретные сеансы создавались не в точно указанном вами порядке,
а потому |
Вот как мы получаем свои сеансы поднятыми и исполняющимися:
PS C:\> $session01 = New-PSSession -computername SRV02,localhost
PS C:\> $session02 = New-PSSession -hostname linux01,linux02 -keyfilepath {path to key file}
Помните, что мы уже разрешили удалённое взаимодействие в этих компьютерах, а все машины находятся в одном домене. И снова, если вы хотите освежить в памяти как включать удалённое взаимодействие, вернитесь к Главе 13.
Хорошо, теперь, когда вам всё известно о причинах применения сеансов, давайте посмотрим как именно ими пользоваться. Как
мы надеемся, вы помните из Главы 13 командлет
Enter-PSSession
, применяемый для взаимодействия один- к- одному удалённой интерактивной
оболочки с одним удалённым компьютером. Вместо того чтобы указывать имя компьютера или имя хоста при помощи командлета, вы можете
указать единственный объект сеанса. Поскольку наши переменные $session01
и
$session02
обладают более чем одним объектом сеанса, нам следует указать один из них при
помощи индекса (который вы впервые изучили в Главе 16):
PS C:\> enter-pssession -session $session01
[SRV02]: PS C:\Users\Administrator\Documents>
Вы можете наблюдать изменения приглашения на ввод, указывающие что вы теперь управляете и удалённым компьютером.
Exit-PSSession
возвращает нам локальное приглашение на ввод, однако наш сеанс остаётся
открытым для дальнейшего применения:
[SRV02]: PS C:\Users\Administrator\Documents> exit-pssession
PS C:\>
Что если у вас имеется множество сеансов и вы забыли значение номера индекса, которым обладает определённый сеанс? Вы можете
взять соответствующую переменную сеанса и отправить её конвейером в Get-Member
и
определить свойства его объекта сеанса. Например, когда мы отправляем конвейером в Get-Member
$session02
, мы получаем следующий вывод:
PS C:\> $session01 | gm
TypeName: System.Management.Automation.Runspaces.PSSession
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
ApplicationPrivateData Property psprimitivedictionary App...
Availability Property System.Management.Automat...
ComputerName Property string ComputerName {get;}
ComputerType Property System.Management.Automat...
ConfigurationName Property string ConfigurationName {get;}
ContainerId Property string ContainerId {get;}
Id Property int Id {get;}
InstanceId Property guid InstanceId {get;}
Name Property string Name {get;set;}
Runspace Property runspace Runspace {get;}
Transport Property string Transport {get;}
VMId Property System.Nullable[guid] VMId {get;}
VMName Property string VMName {get;}
DisconnectedOn ScriptProperty System.Object DisconnectedOn...
ExpiresOn ScriptProperty System.Object ExpiresOn {get...
IdleTimeout ScriptProperty System.Object IdleTimeout {get=$t...
State ScriptProperty System.Object State {get=$this...
В нашем предыдущем выводе вы можете видеть, что наш объекта сеанса обладают свойством
ComputerName
, что означает что вы можете выполнять фильтрацию для этого сеанса:
PS C:\> enter-pssession -session ($sessions | where { $_.computername -eq 'SRV02' })
[SRV02]: PS C:\Users\Administrator\Documents>
Однако это неудобный синтаксис. Если вам нужно применять единственный сеанс из переменной, а вы не можете вспомнить какой номер индекса на что указывает, может быть проще забыть о применении такой переменной.
Несмотря на то, что вы сохранили свои объекты сеанса в своей переменной, они также по- прежнему хранятся в списке хозяина
PowerShell для открытых сеансов. Вы имеете возможность получать к ним доступ при помощи
Get-PSSession
:
PS C:\> enter-pssession -session (get-pssession -computer SRV02)
Get-PSSession
извлекает сеанс нашего компьютера с названием
SRV02
и передаёт его в параметр -session
для Enter-PSSession
.
Когда мы впервые разобрались с этой техникой, мы были впечатлены, но это также заставило нас копнуть слегка глубже. Мы
открыли полную справку для Enter-PSSession
и ознакомились с параметром
-session
. Вот что мы увидели:
-Session <System.Management.Automation.Runspaces.PSSession>
Specifies a PowerShell session ( PSSession ) to use for the interactive session. This parameter takes a
session object. You can also use the Name , InstanceID , or ID parameters to specify a PSSession.
{Определяет сеанс PowerShell ( PSSession ) для применения в соответствующем интерактивном сеансе. Этот параметр
получает объект сеанса. Для определения PSSession вы также можете применять параметры Name , InstanceID или ID.}
Enter a variable that contains a session object or a command that creates or gets a session object, such as a
`New-PSSession` or `Get-PSSession` command. You can also pipe a session object to `Enter-PSSession`. You can
submit only one PSSession by using this parameter. If you enter a variable that contains more than one
PSSession , the command fails.
{Введите параметр, который содержит объект сеанса или команду, которая создаёт или получает объект сеанса, например,
команду `New-PSSession` или `Get-PSSession`. Также вы можете передавать конвейером объект сеанса в `Enter-PSSession`.
При помощи этого параметра вы можете подставлять только один PSSession. Если вы введёте переменную, которая содержит
более одной PSSession, эта команда откажет.}
When you use `Exit-PSSession` or the EXIT keyword, the interactive session ends, but the PSSession that you
created remains open and available for use.
{Если вы воспользуетесь `Exit-PSSession` или ключевым словом EXIT, ваш интерактивный сеанс завершится, однако созданный
вами PSSession останется открытым и доступным для применения.}
Если вы вспомните Главу 9, вы обнаружите, что вводные сведения ближе к
окончанию справки представляет интерес. Там нам сообщается, например, что параметр -session
может получать из своего конвейера объект PSSession
. Мы знаем, что
Get-PSSession
производит объект PSSession
, а
потому также должен работать и следующий синтаксис:
PS C:\> Get-PSSession -ComputerName SRV02 | Enter-PSSession
[SRV02]: PS C:\Users\Administrator\Documents>
И это работает. Мы полагаем, что это гораздо более элегантный способ получения отдельного сеанса, причём даже когда мы все их сохранили в переменной.
Сеансы проявляют свою полезность при помощи Invoke-Command
, который как вы помните,
вы применяли для параллельной отправки команд (или сценария целиком) в несколько удалённых компьютеров. При помощи своих
переменных $session01
мы запросто можем настраивать их все при помощи такой команды:
PS C:\> invoke-command -command { Get-Process } -session $session01
Параметр -session
для Invoke-Command
также
загружаться заключённой в скобки командой, как мы это делали с именами компьютеров в наших предыдущих главах. К примеру,
следующий код отправляет команду во все перечисляемые названия каждого подключённого к компьютеру сеанса.
PS C:\> invoke-command -command { get-process bits } -session (get-pssession –computername server1,server2,server3)
Вы могли бы ожидать, что Invoke-Command
был бы способен получать объекты сеанса из
своего конвейера, на что как вы знаете, способен Enter-PSSession
. Однако беглый взгляд
на полную справку Invoke-Command
показывает, что он не способен выполнять конкретно
этот трюк. Весьма печально, однако приводимый выше пример применения выражения в скобках обеспечивает ту же самую
функциональность без слишком сложного синтаксиса.
Неявное удалённое взаимодействие для нас является одной из крутейших и полезнейших - вероятно, самой крутой и наиболее полезной - функциональной возможностью интерфейса командной строки, которая когда либо имелась в любой операционной системе. Тем не менее, она почти не задокументирована в PowerShell. Естественно, все необходимые для этого команды имеют хорошую документацию, однако отсутствуют упоминания о том, как соединять их для формирования этой невероятной возможности. К счастью, мы обсуждаем это.
Давайте вернёмся к просмотру следующей ситуации: вы уже знакомы с тем, что Microsoft поставляет всё больше и больше модулей с Windows Server и прочими продуктами, но порой, по той или иной причине, вы не можете устанавливать эти модули в своём локальном компьютере. Прекрасным примером выступает модуль ActiveDirectory, который впервые появился в Windows Server 2008 R2: он присутствует лишь в Контроллерах домена и в серверах/ клиентах с установленными средствами удалённого администрирования серверов (RSAT, Remote Server Administration Tools). Рассмотрим весь этот процесс в отдельном примере:
PS C:\> $session = new-pssession -comp SRV02 # устанавливаем соединение
PS C:\> invoke-command -command { import-module activedirectory } session $session # загружаем удалённый модуль
PS C:\> import-pssession -session $session -module activedirectory -prefix rem # импортируем удалённые команды
ModuleType Name ExportedCommands # просматриваем свой временный локальный модуль
---------- ---- ----------------
Script tmp_2b9451dc-b973-495d... {Set-ADOrganizationalUnit, Get-ADD...
Вот что происходит в данном образце:
-
Мы начинаем с установления сеанса с удалённым компьютером, который обладает установленным модулем Active Directory/
-
Мы велим этому удалённому компьютеру импортировать его локальный модуль Active Directory. Это всего лишь один пример; мы вольны выбрать для загрузки любой модуль. Поскольку этот сеанс всё ещё открыт, данный модуль продолжает быть загруженным в данном удалённом компьютере.
-
Затем мы велим своему компьютеру импортировать в этот удалённый сеанс необходимые команды. Нам требуются лишь команды в загруженном модуле Active Directory и, когда они импортированы, мы желаем чтобы к существительному каждой из команд добавлялся префикс rem. Он позволяет нам легче отслеживать такие удалённые команды. Это также подразумевает, что данные команды не будут конфликтовать ни с какими уже загруженными в нашу оболочку одноимёнными командами.
-
PowerShell создаёт в нашем компьютере временный модуль, представляющий необходимые удалённые команды. Сами команды не копируются; вместо этого PowerShell создаёт для них ярлыки, а эти ярлыки указывают в соответствующий удалённый компьютер.
Теперь мы способны запускать необходимые команды Active Directory или даже запрашивать подсказки. Вместо исполнения
New-ADUser
мы запускаем New-remADUser
,
потому как мы добавили такой префикс rem
в существительные своих команд. Сами
команды остаются доступными пока мы не закроем эту оболочку или не закроем свой сеанс с таким удалённым компьютером.
Когда мы откроем новую оболочку, нам придётся повторить данный процесс для повторного получения доступа к этим удалённым
командам.
Когда мы исполняем эти команды, они не выполняются в нашей локальной машине. Вместо этого они неявно удалённо взаимодействуют со своим удалённым компьютером. Они исполняют их для нас и отправляют получаемые результаты в наш компьютер.
Мы можем представить себе мир, в котором мы больше никогда не будем устанавливать в свои компьютеры инструменты администрирования. Сегодня вам требуются инструменты, которые способны исполняться в операционной системе вашего компьютера и взаимодействовать с любым удалённым сервером, которым вы пытаетесь управлять - а может быть невозможным заставлять устанавливать соответствие всего этого. В будущем вам это не понадобится. Серверы будут предлагать свои функциональные возможности управления в качестве иной службы через Windows PowerShell.
А теперь плохие новости: все получаемые посредством неявного удалённого взаимодействия результаты распаковываются (deserialized), что означает, что соответствующие свойства объектов копируются в некий файл XML для передачи через сетевую среду. Те объекты, которые вы получаете таким образом, не будут обладать никакими методами. В большинстве ситуаций это не будет проблемой, однако некоторые модули и оснастки создают объекты, которые подразумевают применение более программным способом, поэтому они не поддаются неявному удалённому взаимодействию. Мы надеемся, что вы столкнётесь лишь с несколькими объектами с подобными ограничениями (если вообще столкнётесь), ибо зависимость от методов нарушает некоторые приёмы архитектуры PowerShell. Когда вы столкнётесь с подобными объектами, вы не сможете применять их посредством неявного удалённого взаимодействия.
PowerShell v3 представил два улучшения в свои возможности управления удалённым взаимодействием. Во- первых, сеансы
намного менее уязвимы, что означает, что они способны переживать краткосрочные сетевые сбои и прочие недолговременные
прерывания. Вы получаете такое преимущество даже когда не применяете объект сеанса в явном виде. Даже когда вы
воспользовались Enter-PSSession
и его параметром
-ComputerName
, с технической точки зрения, под капотом, вы по- прежнему пользуетесь
неким сеансом, а потому вы получаете более надёжное подключение.
Другой новой, введённой в v3, важной функциональной возможностью является необходимость применения свойства в явном виде,
а именно отключённых сеансов. Допустим, вы располагаетесь в COMPUTER1
,
зарегистрированном под Admin1
(который является участником группы Администраторов
домена) и вы создаёте новое подключение к COMPUTER2
:
PS C:\> New-PSSession -ComputerName COMPUTER2
Id Name ComputerName State
-- ----------------- ------------- -----
4 Session4 COMPUTER2 Opened
Затем вы можете отключиться от этого сеанса. Вы всё ещё осуществляете это в COMPUTER1
,
в котором вы и располагаетесь, и это разъединяет имеющееся соединение между данными двумя компьютерами, однако это оставляет
поднятой и исполняемой в COMPUTER2
соответствующую копию PowerShell. Обратите внимание,
что вы выполняете это определяя значение номера идентификатора сеанса, который был отображён когда вы впервые создали данный
сеанс:
PS C:\> Disconnect-PSSession -Id 4
Id Name ComputerName State
-- ----------------- ------------- -----
4 Session4 COMPUTER2 Disconnected
Это нечто, о чём вам, очевидно, стоит задуматься - вы оставляете запущенной некую копию PowerShell в
COMPUTER2
. Становится важным назначение полезных промежутков простоя в тайм- ауте и
тому подобного. В более ранних версиях PowerShell отключённый вами сеанс прекращался, а потому вам не приходилось заниматься
очисткой. Начиная с версии 3 вы способны замусорить свою среду запущенными сеансами, а это подразумевает, что вам приходится
брать на себя слегка большую ответственность.
Но вот и заманчивая сторона: мы зарегистрируемся в другом компьютере, COMPUTER3
в
качестве того же самого Администратора домена под именем Admin1
, и получаете список
запущенных в COMPUTER2
сеансов:
PS C:\> Get-PSSession -computerName COMPUTER2
Id Name ComputerName State
-- ----------------- ------------- -----
4 Session4 COMPUTER2 Disconnected
Чётко, не так ли? Вы не смогли бы увидеть этот сеанс, если бы вошли в систему под иным пользователем, даже в качестве иного
администратора; вы можете наблюдать лишь те сеансы, которые вы создали в COMPUTER2
.
Но теперь, обнаружив его, вы способны повторно подключить его. Это позволит вам повторно соединяться с сеансом, от которого
вы намеренно или непреднамеренно отключились, причём вы сможете продолжать прямо с того места, в котором закончили свой
сеанс:
PS C:\> Get-PSSession -computerName COMPUTER2 | Connect-PSSession
Id Name ComputerName State
-- ----------------- ------------- -----
4 Session4 COMPUTER2 Open
Давайте потратим немного времени на обсуждение управления такими сеансами. В накопителе WSMan PowerShell вы обнаружите настройки, которые способны помочь вам удерживать под контролем свои отключённые сеансы. Вы также обладает централизованно настраивать большинство из них через Групповые политики. Ключевые настройки для просмотра содержат следующие:
-
В
WSMan:\localhost\Shell
:-
IdleTimeout
- Определяет продолжительность времени, на протяжении которого сеанс способен пребывать в бездействии, прежде чем он будет закрыт. Значение по умолчанию составляет около 2000 часов (выражаемое в секундах), или около 84 дней. -
MaxConcurrentUsers
- Определяет число пользователей, которые могут одновременно обладать открытым сеансом. -
MaxShellRunTime
- Задаёт максимальную продолжительность времени, в течении которого способен быть открытым сеанс. По умолчанию, практически для всех целей, без ограничений. Имейте в виду, чтоIdleTimeout
способен перекрывать его если эта оболочка пребывает в бездействии вместо выполнения команд. -
MaxShellsPerUser
- Устанавливает предел на число сеансов отдельного пользователя, которыми тот может обладать одновременно. Для вычисления максимально возможного числа сеансов для всех пользователей в данном компьютере умножьте его наMaxConcurrentUsers
.
-
-
В
WSMan:\localhost\Service
:-
MaxConnections
- Устанавливает верхний предел входящих подключений для всей инфраструктуры удалённого взаимодействия в целом. Даже если вы позволите большее число оболочек на пользователя или большее максимальное число пользователей, именноMaxConnections
выступает абсолютным пределом входящих подключений.
-
В качестве администратора, очевидно, вы несёте более высокий уровень ответственности нежели обычный пользователь. Вам предстоит отслеживать свои сеансы, в особенности когда вы будете отключаться и подключаться вновь. Разумные настройки времён ожидания способны гарантировать что сеансы оболочки не простаивают на протяжении длительного времени.
Замечание | |
---|---|
Для данных лабораторных занятий вам требуется машина Windows Server 2016, macOS или Linux с запущенным PowerShell v7 или выше. Если у вас имеется доступ только к компьютеру клиента (запущенным под Windows 10 или выше), у вас не будет возможности выполнять задачи с 6 по 9 для этих лабораторных занятий. |
Для выполнения данных лабораторных занятий вам следует обладать двумя компьютерами: одним для исходящего удалённого взаимодействия, а другой для входящего. Если у вас имеется лишь один компьютер, применяйте название этого компьютера для удалённого взаимодействия с ним. Вам надлежит получить аналогичный опыт следующим образом:
-
Закройте все открытые сеансы в своей оболочке.
-
Установите сеанс с удалённым компьютером. Сохраните этот сеанс в переменной с названием
$session
. -
Для установления сеанса один- к- одному с удалённой оболочкой в своём удалённом компьютере воспользуйтесь своей переменной
$session
. Отобразите список процессов и затем выйдите. -
При помощи
Invoke-Command
воспользуйтесь переменной$session
и выведите список значения временной зоны своей удалённой машины. -
Если вы пребываете в клиенте Windows, для получения списка 20 наиболее последних записей журнала событий безопасности из своего удалённого компьютера воспользуйтесь
Get-PSSession
иInvoke-Command
. -
Если вы клиент macOS или Linux, перечислите значение числа элементов в своём каталоге
/var
. Задачи 7 - 10 могут выполняться только в машине Windows. -
Воспользуйтесь
Invoke-Command
и своей переменной$session
для загрузки модуляServerManager
в своём удалённом компьютере. -
Импортируйте необходимые команды модуля
ServerManager
из этого удалённого компьютера в свой компьютер. Добавьте необходимый префиксrem
для существительных своих импортированных команд. -
Исполните свою импортированную команду
Get-WindowsFeature
. -
Закройте тот сеанс, который пребывает в вашей переменной
$session
.
-
get-pssession | Remove-PSSession
-
$session=new-pssession –computername localhost
-
enter-pssession $session
Get-Process
Exit
-
invoke-command -ScriptBlock { get-timezone } -Session $session
-
Invoke-Command -ScriptBlock {get-eventlog -LogName System -Newest 20} -Session (Get-PSSession)
Get-ChildItem -Path /var | Measure-Object | select count
-
Invoke-Command -ScriptBlock {Import-Module ServerManager} -Session $session
-
Import-PSSession -Session $session -Prefix rem -Module ServerManager
-
Get-RemWindowsFeature
-
Remove-PSSession -Session $session
Проведите быструю инвентаризацию своей среды: какие продукты с поддержкой PowerShell у вас имеются? Exhange Server? SharePoint Server? VMware vSphere? System Center Virtual Machine Manager? Все эти и прочие продукты содержать модули PowerShell, многие из которых доступны через удалённое взаимодействие PowerShell.