Я часто работаю с командами на удаленных системах через PowerShell как во время пентестов, так и при решении повседневных задач. Запуска удаленных команд происходит через протокол WinRM (Windows Remote Management), который, насколько мне известно, поддерживается в Windows Vista SP 1, Windows 7, Windows Server 2008 и Windows Server 2012.

Введение

Я часто работаю с командами на удаленных системах через PowerShell как во время пентестов, так и при решении повседневных задач. Запуска удаленных команд происходит через протокол WinRM (Windows Remote Management), который, насколько мне известно, поддерживается в Windows Vista SP 1, Windows 7, Windows Server 2008 и Windows Server 2012.

Первоначальные настройки

Перед тем как начать работу с удаленной системой, необходимо выполнить настройку.

1. Запустите консоль PowerShell от имени администратора и выполните следующую команду:

Enable-PSRemoting -force

Команда выше разрешает запуск команд на удаленных системах. Если у вас возникли проблемы, используйте команды ниже:

2. Убедитесь в том, что служба WinRM запускается автоматически.

# Устанавливаем нужный режим

Set-Service WinRM -StartMode Automatic

# Проверяем, что служба запущена

Get-WmiObject -Class win32_service | Where-Object {$_.name -like "WinRM"}

3. Устанавливаем у всех хостов статус «достоверный» (можно сделать позже).

# Доверяем всем хостам

Set-Item WSMan:localhost\client\trustedhosts -value *

# Проверяем настройку достоверных хостов

Get-Item WSMan:\localhost\Client\TrustedHosts

Примеры работы с удаленными системами

Запуск одиночной команды на удаленной системе

Команда "Invoke-Command" предназначена для запуска команд на удаленных системах. Можно работать от имени текущего пользователя, либо использовать стороннюю учетную запись, если вы работаете в системе, которая не является частью домена:

Invoke-Command –ComputerName MyServer1 -ScriptBlock {Hostname}
Invoke-Command –ComputerName MyServer1 -Credentials demo\serveradmin -ScriptBlock {Hostname}

Если установлен модуль для работы с ActiveDirectory, становится возможным запуск команд на множестве систем при помощи каналов (pipeline):

Get-ADComputer -Filter * -properties name | select @{Name="computername";Expression={$_."name"}} |
Invoke-Command -ScriptBlock {hostname}

Иногда на удаленной системе требуется запустить скрипт, хранящийся локально:

Invoke-Command -ComputerName MyServer1 -FilePath C:\pentest\Invoke-Mimikatz.ps1
Invoke-Command -ComputerName MyServer1 -FilePath C:\pentest\Invoke-Mimikatz.ps1 -Credentials demo\serveradmin

Если вы генерируете команды или функции динамически, которые затем передаются на удаленную систему можно использовать связку команд invoke-expression и invoke-command:

$MyCommand = "hostname"
$MyFunction = "function evil {write-host `"Getting evil...`";iex -command $MyCommand};evil"
invoke-command -ComputerName MyServer1 -Credentials demo\serveradmin -ScriptBlock
{Invoke-Expression -Command "$args"} -ArgumentList $MyFunction

Организация интерактивной консоли на удаленной системе

Организовать интерактивную консоль в PowerShell на удаленной системе можно при помощи команды "Enter-PsSession" (немного похожа на SSH). Команда "Enter-PsSession" также запускается либо от имени текущего пользователя, либо при помощи альтернативной учетной записи:

Enter-PsSession –ComputerName server1.domain.com
Enter-PsSession –ComputerName server1.domain.com –Credentials domain\serveradmin

Закрытие сессии выполняется при помощи команды "Exit-PsSession":

Создание фоновых сессий

Еще одна полезная возможность позволяет создавать фоновые сессии (команда "New-PsSession"). Фоновые сессии могут оказаться полезны при запуске множества команд во множестве систем. Как и предыдущие команды, команда "New-PsSession" запускается от имени текущего пользователя, либо при помощи альтернативной учетной записи:

New-PSSession -ComputerName server1.domain.com
New-PSSession –ComputerName server1.domain.com –Credentials domain\serveradmin

Если установлен модуль для работы с ActiveDirectory, становится возможным единовременное создание фоновых сессий для множества систем (этот трюк можно выполнить различными способами). Ниже показан пример создания фоновых сессий для всех систем, входящих в домен. В примере создание сессий происходит в системе, не входящей в домен, при помощи альтернативной учетной записи домена.

New-PSDrive -PSProvider ActiveDirectory -Name RemoteADS -Root "
" -Server a.b.c.d -credential domain\user
cd RemoteADS:
Get-ADComputer -Filter * -Properties name | select @{Name="ComputerName";Expression={$_."name"}}
| New-PSSession

Вывод перечня фоновых сессий

Как только создано несколько фоновых сессий, можно просмотреть их перечень при помощи команды "Get-PsSession".

Взаимодействие с фоновыми сессиями

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

Enter-PsSession –id 3

Для выхода из сессии используйте команду "Exit-PsSession". Сессия перейдет обратно в фоновый режим.

Запуск команд через фоновые сессии

Если вы хотите выполнить команду во всех активных сессиях, используйте связку команд "Invoke-Command" и "Get-PsSession".

Invoke-Command -Session (Get-PSSession) -ScriptBlock {Hostname}

Удаление фоновых сессий

Для удаления всех активных сессий используйте команду "Disconnect-PsSession"

Get-PSSession | Disconnect-PSSession

Заключение

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

  • Для запуска одиночной команды на удаленной системе используйте "Invoke-Command".
  • Для взаимодействия с одиночной системой используйте "Enter-PSSession".
  • Если вы хотите запускать множество команд во множестве систем, используйте фоновые сессии.

Надеюсь, эта статья оказалась для вас полезной.

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

Запускаем службу WinRm
Для удалённого взаимодействия в PowerShell 2.0 используется служба WinRM, которая по умолчанию предустановлена на Windows 7 и Windows 2008 R2. Для более ранних версий операционной системы её требуется устанавливать дополнительно. Указанная служба устанавливается на машину при установке PowerShell 2.0. Для того, чтобы убедиться, в наличии WinRM, запустите консоль PowerShell 2.0 и выполните в ней команду:
Get-Service WinRm
Результат будет выглядеть следующим образом:

Status Name DisplayName ------ ---- ----------- Stopped winrm Windows Remote Management (WS-Manag...

Как видим – служба присутствует, однако не запущена. Для того, чтобы запустить WinRm, необходимо с правами администратора, из консоли PowerShell 2.0, выполнить команду:
Enable-PSRemoting
На запрос о подтверждении запуска службы, нажимаем кнопку «Y». Теперь службе WinRM назначен тип запуска «Автоматический», т.е. она будет запускаться каждый раз при старте компьюрета. Команда Enable-PSRemoting не только запускает службу и меняет её тип запуска, но и настраивает должным образом брандмауэр, для её корректной работы. Служба WinRm принимает запросы с любого IP-адреса.

Запрашиваем имена всех подключенных провайдеров:
Get-PSProvider
Как видим, у нас теперь появился ещё один провайдер под именем WSMan.
Назначение доверенных узлов

В консоли PowerShell 2.0 запускаем с правами администратора команды:

Set-Location –Path WSMan: Set-Location –Path localhost\client Get-ChildItem

Примечание
Обратите внимание на то, что в первой команде значение параметра –Path завершается двоеточием, поскольку это провайдер.

На том компьютере, с которым вы желаете удалённо работать, следует указать, каким серверам позволено подключение к этой машине. Такие серверы известны как "доверенные узлы". Таким образом, если вы находитесь на сервере "MyServer", то прежде чем вы сможете удалённо работать с компьютером "MyComputer", следует настроить доверенные узлы (TrustedHosts). Указанный ниже способ назначения доверенных узлов используется в том случае, когда компьютер не входит в состав домена Active Directory. Если же компьютер входит в состав домена Active Directory, то настройки TrustedHosts можно сконфигурировать через групповую политику (Group Policy).

Важно!
Приведённая ниже команда не будет работать, если текущим каталогом не установлен WSMan:\localhost\client (см. вызов команд, выполненный нами выше).

Set-Item TrustedHosts *

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

Set-Item WSMan:\localhost\Client\TrustedHosts *

На запрос о подтверждении жмём клавишу «Y».

Для того, чтобы PowerShell увидел изменения, выполненные нами в настройках TrustedHosts - необходимо перезапустить службу WSMan. Это делается с помощью следующей команды:
Restart-Service winrm

Аналогичное действие можно выполнить из под DOS. Запустите команду winrm -?. Вы увидите общую справку по команде. Для того, чтобы посмотреть текущее значение TrustedHosts, следует выполнить команду:

winrm get winrm/config/client

а для того, чтобы установить значение - следует выполнить:

winrm set winrm/config/client/ @{TrustedHosts="*"}

В приведённых выше командах, для TrustedHosts, в качестве значения указывался символ «*», однако, вместо него можно указывать имена конкретных серверов. Управление TrustedHosts является классическим случаем, для применения PowerShell-глаголов "Get" и "Set" в связке: вы используете Get-Item и Set-Item.
Создание и завершение удалённого сеанса PowerShell 2.0
В приведённых ниже командах, вместо "IpAddress" следует указывать нужный IP-адрес, а вместо "FQDN " - полностью определённое имя домена (Fully Qualified Domain Name):

Enter-PSSession IpAddress

Enter-PSSession FQDN

Для завершения сеанса удалённой работы, следует выполнить команду:

Команде Enter-PSSession требуется полностью.определённое.доменное.имя. Например, в случае MyServer.domain.local, простое указание MyServer не сработало бы, однако использование IP-адреса всегда хорошо работает в подобных ситуациях. Альтернативный метод PSSession:

New-PSSession -computername testMachine2 Get-PSSession

Завершить работу этой сессии можно так:

Get-PSSession | remove-PSSession

Если вы хотите протестировать удалённую работу, но не имеете второй машины, тогда создайте "удалённое подключение" вашего компьюетера к себе самому. Например, если ваша машина называется "MyMachine", тогда попробуйте это:

New-PSSession -computername MyMachine

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

Работа в удалённом сеансе PowerShell 2.0
После создания удалённого подключения, вы можете организовывать конвейры команд, запуская их в консоли PowerShell 2.0, но при этом выполняться они будут на удалённой машине, как будто вы находитесь за её клавиатурой и набираете команды там, а не здесь. Например, запустите такую команду и посмотрите результат её работы:

Set-Location c:\ | Get-childitem

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

Примечание
Если вам кажется, что сессии удалённого подключения у вас не работает какая-то команда - протестируйте её сначала на своей локальной машине.

Как только удалённое подключение у вас заработает, это сразу даёт вам возможность использовать PowerShell 2.0 для управления компьютерами, подключенными к вашей сети. Теперь вы можете выполнять сценарии на других машинах. В PowerShell 2.0 многие командлеты поддерживают параметр "-computerName", но удалённое подключение позволяет вам использовать команды семейства PSSession, а так же вызывать Invoke-Command (т.е. вы можете делать всё что угодно).

Поиск и устранение проблем, возникающих в процессе удалённой работы PowerShell 2.0

Одна типичная проблема – ОШИБКА «Access is denied» (доступ запрещён).

Решение:
Запустите PowerShell 2.0 с правами администратора. Попробуйте на обоих машинах (на той, с которой подключаетесь, и на той, к которой подключаетесь) задать настройке "TrustedHosts" значение * (звёздочка). Только не забывайте, что такой вариант разрешает подключения отовсюду.
Не забудьте перезапустить службу WinRm, иначе выполненные вами для "TrustedHosts" изменения не вступят в силу. Для перезапуска службы следует в консоли PowerShell 2.0 выполнить команду: Restart-Service WinRm
Кроме того, будьте внимательней и не путайте имя провайдера WSMan с именем службы WinRm.
Ещё один странный, но порой помогающий совет: Попытайтесь повторить попытку удалённого подключения. Странно, но это может не сработать с первой попытки, но сработать со второй или третьей. Т.е. вам нужно повторно выполнить команду: Enter-PSSession -computerName myOtherMachineName

Брандмауэры, PowerShell 2.0 и «The rpc server is unavailable» (Сервер RPC не доступен)
Специалисты по безопасности в ужасе поднимут руки от такого предложения, однако в случае получения указанной выше ошибки, я предлагаю вам отключить брандмауэр на обоих компьютерах. Если после отключения всё заработает - это хорошо, значит нужно проверить задействованность портов 135 и 445. Настройте для этих портов исключения в брандмауэрах - это даст возможность PowerShell 2.0 работать удалённо и при этом брандмауэр защитит компьютер от угроз.

P.S. я читал, что команда Enable-PSRemoting должна брать на себя автоматическое внесение изменений в настройки брандмауэра, но по моему опыту это не всегда так.
О том, как с помощью групповой политики отключить брандмауэр в Windowws 8, читайте .

Два типа, использующихся для удалённой работы в PowerShell 2.0
Пора сообщить, что существуют два варианта удалённой работы в PowerShell 2.0.
Первый способ - это более изощрённая вариация, в которой используются командлеты, создавая устойчивый канал ко второй машине. Имена таких команд содержат в качестве существительного слово "PSSession" (напоминаю, что имена командлетов строятся по правилу "Глагол-Существительное"). Получить перечень этих командлет можно с помощью такой команды:

Get-Command -noun PSSession

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

Get-Process -computerName machine2

Перечень командлет, которые можно использовать таким простым способом (т.е. тех, что имеют в своём составе параметр "-computerName") можно получить с помощью такой команды:

Get-command | where { $_.parameters.keys -contains "ComputerName"}

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

Get-command | where { $_.parameters.keys -contains "ComputerName" -and ($_.parameters.keys -notContains "Session")}

Подводим итог об удалённой работе в PowerShell 2.0
Секрет в том, чтобы удалённо работать с помощью PowerShell 2.0 в том, что нужно понять основные вещи:
Следует установить WinRm.
С помощью команды Enable-PSRemoting необходимо разрешить удалённое взаимодействие.
Нужно выполнить настройку TrustedHosts (например задать ей в качестве значения *).
В случае использования команды Enter-PSSession, следует не забывать указывать полностью определённое имя узла или же его IP-адрес.

Англоязычный источник изложенной и немного переработанной мною информации .

# Создаём новую сессию подключения к удалённой машине $s = New-PSSession -computername TestComputer

# Выполняем на удалённой машине произвольные действия, например - смотрим содержимое каталога C:
Invoke-Command -Session $s -ScriptBlock {ls c:\}

# Создаём на удалённой машине каталог "%ProgramFiles%\MyCompany\MySoft"
Invoke-Command -Session $s -ScriptBlock {New-Item -Path "$env:ProgramFiles\MyCompany\MySoft" -ItemType directory}

# Однако, гораздо удобней не вручную вбивать команды, а запускать на удалённой машине уже готовый скрипт:
Invoke-Command -Session $s -FilePath "\\ServerDir\Common Scripts\MyScript.ps1"

# Завершаем сессию
$s | remove-PSSession

Удаленное управление с помощью PowerShell

Существует довольно много методов для работы с удаленными компьютерами. Есть Windows Management Instrumentation (WMI), широко используемый в VBScript. Есть различные утилиты, которые позволяют осуществлять удаленное управление, типа от Sysinternals. Даже многие командлеты PowerShell имеют параметр ComputerName для выполнения на удаленных компьютерах.

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

PowerShell Remoting решает большинство описанных проблем. Он основан на Microsoft реализации протокола Web Services for Management (WS-Management), а для связи использует службу (WinRM). Связь между компьютерами осуществляется по HTTP (по умолчанию) или HTTPS. Весь трафик между двумя компьютерами шифруется на уровне протокола (за исключением случаев, когда используется SSL). Поддерживаются несколько методов аутентификации, включая NTLM и Kerberos.

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

Есть несколько способов управления с помощью PowerShell Remoting.

Управление «один к одному»

Самый простой способ удаленного управления — интерактивно открыть удаленную сессию и в ней выполнить нужные действия. Например, откроем сессию на компьютер SRV4 и рестартуем на нем сервис печати:

Enter-PSSession -ComputerName SRV4
Restart-Service -Name spooler

Посмотрим состояние сервиса и закроем удаленную сессию:

Get-Service -Name spooler
Exit-PSSession

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

Invoke-Command -ScriptBlock {Restart-Service spooler} -ComputerName SRV4

Эта команда откроет удаленную сессию на SRV4, выполнит блок команд, указанный в параметре -ScriptBlock , и закроет сессию. А чтобы задание выполнялось в фоновом режиме, дополнительно можно указать параметр -AsJob .

Cледует помнить о том, что при работе в фоновом режиме PowerShell не возвращает результат. Для его получения придется воспользоваться командлетом Receive-Job .

Для того, чтобы выполнить не пару-тройку команд, а какой либо скрипт, у Invoke-Command есть параметр –FilePath , который можно использовать вместо –ScriptBlock для определения файла сценария. Для примера я создал скрипт, который выводит список остановленных служб и запустил его на удаленной машине SRV4:

Invoke-Command -FilePath .\script.ps1 -ComputerName SRV4

Управление «один ко многим»

Довольно часть возникает необходимость параллельно выполнить одну задачу на нескольких компьютерах. Это довольно легко можно сделать с помощью того же Invoke-Command . Например, имена компьютеров можно просто перечислить через запятую:

Invoke-Command -ScriptBlock {Restart-Service spooler} -ComputerName SRV4,SRV5

Поместить в переменную:

$servers = @(″SRV1″,″SRV2″,″SRV3″)
Invoke-Command -ScriptBlock {Restart-Service spooler} -ComputerName $servers

Или взять из файла:

Invoke-Command -ScriptBlock {Restart-Service spooler} -ComputerName`
(Get-Content .\servers.txt)

Примечание: у Invoke-Command есть параметр ThrottleLimit , ограничивающий максимальное количество компьютеров, которыми можно управлять одновременно. По умолчанию этот параметр равен 32. При необходимости его можно изменить, но учтите, что повышение этого параметра увеличит нагрузку на процессор и память вашего компьютера, поэтому эту операцию нужно выполнять с большой осторожностью.

Сессии

Каждый раз при выполнении Invoke-Command создается новая сессия, на создание которой тратится время и ресурсы. Чтобы этого избежать мы можем открыть одну сессию, в которой и выполнять все команды. Например, откроем сессию с именем SRV4 на компьютер SRV4 и поместим ее в переменную $session, а затем этой сессии выполним нашу задачу (остановим многострадальный spooler):

$session = New-PSSession -ComputerName SRV4 -Name SRV4
Invoke-Command -ScriptBlock {Get-Service spooler | Stop-Service}`
-Session $session

Сессия будет активна до того момента, пока мы не выйдем из консоли PowerShell. Также сессию можно закрыть — Disconnect-PSSession или удалить — Remove-PSSession .

А теперь несколько интересных возможностей, появившихся в PowerShell 3.0. Если раньше при выходе из сессии или закрытии консоли сессия удалялась, то в PS 3.0 при закрытии сессия переходит в состояние disconnected . Мы можем открыть новый сеанс на этом же (или любом другом) компьютере и выполнить команду прямо в этой отключенной сессии. В качестве примера стартуем на компьютере SRV4 сервис печати, остановленный в прошлый раз:

Invoke-Command -ScriptBlock {Start-Service spooler}`
-ComputerName SRV4 -Disconnected

Еще один вариант использования отключенных сессий — запуск длительных по времени задач. Для примера откроем сессию c именем LongJob на SRV4 и запустим в ней фоновое задание, которое будет выводить список сервисов с интервалом в 1 минуту:

$session = New-PSSession -ComputerName SRV4 -Name LongJob
Invoke-Command -Session $session -ScriptBlock`
{Get-Service | foreach {$_;sleep 60} } -AsJob

Посмотрим, как выполняется задача и закроем сессию:

Receive-Job -Name Job2
Disconnect-PSSession $session

Идем на другой компьютер и открываем консоль, Подключаемся к сессии LongJob и с помощью командлета Receive-PSSession получаем результат выполнения задания:

Connect-PSSession -Name LongJob -ComputerName SRV4
Receive-PSSession -Name LongJob

Или еще вариант, без явного подключения к сессии с помощью Connect-PSSession :

$session = Get-PSSession -Name LongJob -ComputerName SRV4
$job = Receive-PSSession $session -OutTarget Job
Receive-Job $job

Примечание: для того, чтобы результат остался в системе, Receive-Job надо использовать с параметром -Keep .

Неявное удаленное управление

Еще один, довольно нестандартный способ удаленного управления — неявное удаленное управление (Implicit remoting). Используя его можно, не создавая удаленной сессии, локально выполнять командлеты, находящиеся на удаленном компьютере.

Для примера берем обычную рабочую станцию, без установленных средств удаленного администрирования. Создаем удаленную сессию с контроллером домена SRV4 и импортируем в эту сессию модуль Active Directory:

$session = New-PSSession -ComputerName SRV4
Invoke-Command {Import-Module ActiveDirectory} -Session $session

Затем экспортируем из удаленной сессии командлеты Active Directory и помещаем их в локальный модуль RemoteAD:

Export-PSSession -Session $session -CommandName *-AD* -OutputModule RemoteAD`
-AllowClobber

Эта команда создаст в папке WindowsPowerShell\Modules\RemoteAD новый модуль PowerShell. Загружены будут только командлеты с именами, соответствующими шаблону *-AD*. При этом сами командлеты не копируются на локальный компьютер. Локальный модуль служит своего рода ярлыком, а сами команды будут выполняться на удаленном контроллере домена.

После создания модуля удаленную сессию можно закрыть, она больше не понадобится.

Импортируем новый модуль в текущий сеанс (в PS 3.0 можно этот шаг пропустить):

Import-Module RemoteAD

А теперь внимание — мы не открываем удаленную сессию с контроллером домена, где расположены командлеты. Не нужно явно запускать этот сеанс - это можно сделать неявно , попытавшись выполнить удаленные командлеты:

New-ADUser -Name BillGates -Company Microsoft
Get-ADUser BillGates

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

Удаленный сеанс будет активным до тех пор, пока вы не закроете консоль или не удалите модуль RemoteAD.

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

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



Здесь минимум теории, в основном практическая часть. Описывается как настроить WinRM, как изменить профиль сетевого адаптера, дается скрипт по добавлению в TrustedHosts с фильтрацией, объясняется зачем нужны доверенные хосты, и рассматриваются поверхностно удаленные подключения так чтобы можно было сесть и сразу админить удаленные машины.

Наиболее простой путь сконфигурировать удаленное управление это выполнить Enable-PSRemoting в оболочке powershell с правами администратора. При этом произойдет следущее:

  • запустится служба WinRM (если запущена перезапустится)
  • служба WinRM перейдет в состояние - автоматический запуск при старте
  • будет создан прослушиватель WinRM для HTTP трафика на порту 5985 для всех локальных IP адресов
  • будет создано правило файрвола для прослушивателя WinRM. Внимание, этот пункт завершится с ошибкой если любая из сетевых карточек имеет тип сети «публичная», т.к. открывать порт на такой карточке не хорошо. Если у вас при конфигурировании вышла такая ошибка измените профиль это сетевушки командлетом Set-NetConnectionProfile и после этого запустите Enable-PSRemoting снова. Если вам нужна сетевая карточка с профилем «Публичная сеть» запустите Enable-PSRemoting с параметром -SkipNetworkProfileCheck в этом случае будут созданы правила файрвола только из локальной сети.
После этого нужно разрешить подключаться к удаленной машине с той машины с которой будет происходить управление. Сделано это в целях безопасности для того чтобы уменьшить риск взлома сессии удаленного управления или DNS с подстановкой себя вместо удаленной машины и предотвратить исполнение скриптов на машинах которые вы принудительно не разрешили.

Для проверки куда можно подключаться используем:
get-item wsman:\localhost\Client\TrustedHosts
для разрешения подключаться ко всем
set-item wsman:localhost\client\trustedhosts -value *
Если вы открываете доступ для всех указав * то WinRM будет подключаться ко ВСЕМ машинам без проверки. Помните, что вы открываете самого себя для потенциального взлома из локальной сети. Лучше указывать адреса хостов куда вам нужно подключится, тогда WinRM будет отклонять все остальные адреса или имена. Если машина с которой ведется управление находится в домене она будет доверять всем машинам этого домена. Если она не в домене, или в другом домене, то нужно указать в TrustedHosts адрес или имя машины на которую мы будем подключаться. Добавлять себя на машине к которой мы подключаемся не нужно.

В хелпе указаны команды, я их чуть чуть переделал в скрипт
###################################################################################### # добавляет NewHost в список TrustedHost с фильтрацией если такая строка уже есть # можно дергать из командной строки указывая параметр напрямую например # .\Add-TrustedHost.ps1 192.168.2.1 ###################################################################################### param ($NewHost = "192.168.2.89") Write-Host "adding host: $NewHost" $prev = (get-item WSMan:\localhost\Client\TrustedHosts).value if (($prev.Contains($NewHost)) -eq $false) { if ($prev -eq "") { set-item WSMan:\localhost\Client\TrustedHosts -Value "$NewHost" } else { set-item WSMan:\localhost\Client\TrustedHosts -Value "$prev, $NewHost" } } Write-Host "" Write-Host "Now TrustedHosts contains:" (get-item WSMan:\localhost\Client\TrustedHosts).value
он проверяет на есть ли такая запись, если нет то добавляет в список. Вызывать можно из командной строки указав адрес или имя.

Есть разница указывать имя или адрес. Если в TrustedHosts будет только адрес то открыть сессию по имени не получится, и наоборот - если указать имя то прицепится по адресу не получится. Учитывайте это.

в чем же разница

Enable-PSRemoting делает больше действий чем «winrm quickconfig». Командлет Set-WSManQuickConfig делает точно такие же действия как «winrm quickconfig». Enable-PSRemoting запускает Set-WSManQuickConfig когда ведет настройку системы

Удаленные подключения
1. Сессии 1-to-1
открываются командой
Enter-PSSession -ComputerName Test
Вы получите оболочку на удаленной машине. Подключится можно к самому себе указав localhost. Альтернативные кредиталы указываются с параметром -Credential , выход происходит командлетом Exit-PSSession

Ограничения следующие:

  • нельзя сделать второй прыжок - только 1 сессия, внутри сессии подключиться дальше нельзя
  • вы не можете использовать команды имеющие графический интерфейс. Если вы это сделаете оболочка повиснет, нажмите Ctrl+C чтобы отвисло
  • вы не можете запускать команды имеющие свой собственый шел, например nslookup, netsh
  • вы можете запускать скрипты если политика запуска на удаленной машине позволяет их запускать
  • нельзя прицепится к интерактивной сессии, вы заходите как «network logon» , как будто прицепились к сетевому диску. Поэтому не запустятся логон скрипты, и вы можете не получить домашнюю папку на удаленной машине (лишний довод чтобы не мапать хом фолдеры логон скриптами)
  • вы не сможете взаимодействовать с юзером на удаленной машине даже если он туда залогинен. Не получится показать ему окошко или попечатать чтонибудь ему.
этот способ лучше всего для простых операций, зашел, подергал сервер и отключился. Если нужно удержать переменные в скопе, нужна длительная операция (много часов или дней), нужно больше возможностей по администрированию то нужно использовать технику попродвинутее.
Комментарий.
объекты переданные по сети обрезаются и перестают быть живыми. У них удаляются методы, свойства остаются. Вытащить объект на свою машину, поколдовать и засунуть обратно не получится. Если нужно больше пишите, допишу отдельно.

2. Сессии 1-to-many
Invoke-Command
определяем что будем исполнять так:
$sb = { команды для удаленной машины разделенные точкой с запятой }
передаем на удаленные машины Test1 и Test2
Invoke-Command -ComputerName Test1, Test2 -ScriptBlock $sb
за раз можно забросить на 32 машины. Если альтернативные кредиталы то используем параметр -Credential

Чтобы передать целиком скрипт вместо параметра -ScriptBlock пишем -FilePath, удаленной машине НЕ нужно иметь доступ к файлу, он будет разобран на запчасти, передан через HTTP и выполнен с той стороны.

Запомним что на той стороне будет новый скоп, так что ваш скрипт не получит значений из вашей консоли, а переменные скрипта могут оказаться на той стороне пустыми. Поэтому передавайте сразу целиком готовые инструкции и скрипты с параметрами.

для полноценного использования Invoke-Command надо уметь превращать строки в скрипт блоки. Например у вас есть команды которые зависят от какогото списка, вам нужно сгенерировать строку, превратить ее в ScriptBlock и отправить на удаленный комп:
$sb = ::Create($SomeString)
kuda78
В статье пропущен очень важный момент - передача параметров в скрипт на удаленной машине.

$deployRemote = {
param(
$targetEnvName,
$targetUsername)
$Global:ErrorActionPreference = «Stop»
#…
}

Invoke-Command -Session $session -ScriptBlock $deployRemote -ArgumentList ($targetEnvName, $targetUsername)


Да действительно пропущен. Сделал сознательно чтобы не загромождать обзор параметрами и описаниями. Спасибо. Параметр -ArgumentList работает как со скрипт блоками так и со сценариями

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

Создание сессии происходит командлетом New-PSSession, результат можно поместить в переменную
$DC01 = New-PSSession -ComputerName DC01 $Controllers = New-PSSession DC01, DC02, DC03
использовать можно такие же параметры подключения как в Invoke-Command

Как использовать:
если 1-to-1
Enter-PSSession -Session $DC01
если 1-to-many
Invoke-Command -Sessions $Controllers -ScriptBlock {get-eventlog -logname security -newest 50}
посмотреть какие сессии открыты можно с помощью Get-PSSession, закрыть Remove-PSSession
закрыть вообще все сессии
Get-PSSession | Remove-PSSession
прицепится к сессии можно с помощью Connect-PSSession, отключиться через Disconnect-PSSession

Invoke-Command может создать сразу disconnected сессию, он отправляет команды на исполнение и отключатся, позже можно подключится и сгрузить результаты работы. Делается это параметром -Disconnected. Получение результатов через командлет Recieve-PSSession.

Сессии имеют очень много настроек, возможно даже создание сессий с обрезаным набором команд, модулей и т.п. Называется custom endpoints

Вы можете помочь и перевести немного средств на развитие сайта

Powershell настолько крут, что позволяет не только выполнять некоторые команды на удалённых компьютерах, но и полностью подключаться к компьютеру и выполнять команды как-будто на локальном компьютере. По умолчанию такое удовольствие отключено в целях безопасности. Включить и настроить его совсем не сложно, но многие почему-то этого не знают.

Для удалённого управления необходимо два условия: во-первых на обоих компьютерах естественно необходимо чтобы были установлены Powershell, .NET Framework и служба Windows Remote Management (все компоненты начиная с версии 2.0 и выше), а во-вторых, чтобы они были настроены на удалённое управление. Для Windows 7 и выше ничего устанавливать не нужно, всё уже есть, для Windows XP/2003 нужно установить.NET Framework и Powershell (служба Windows Remote Management поставляется в комплекте с Powershell).

После того как всё необходимое установлено нужно настроить, компьютер к которому нужно будет подключаться на разрешение удалённых подключений. Для этого нужно выполнить команду winrm quickconfig или winrm qc . Эта команда выполняет сразу несколько действий:

  • Запускает службу WinRM
  • Изменяет тип запуска службы WinRM на автоматический
  • Создаёт прослушивателя для приема запросов с любого IP-адреса
  • Изменяет правила брандмауэра для трафика WS-Management (только HTTP)

На этом можно сказать, что компьютер готов для удалённых подключений, однако на практике бывает нужно ещё выполнить команду Enable-PSRemoting .

Всё! Настройка компьютера завершена, и к нему можно подключаться. Теперь пару слов о том, как подключаться. Самый простой способ это использовать командлет Enter-PSSession , после которого указать имя компьютера к которому нужно подключиться, например:

Enter-PSSession NameOfRemoteComputer

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

Кстати, по умолчанию подключаться к удалённому компьютеру могут только члены группы “Администраторы” (о том как это исправить в другой раз).

А как быть в случае если компьютеры не в домене (или в разных доменах) и логины и пароли администраторов разные?

В этом случае командлет Enter-PSSession нужно использовать с параметром -Credential , который позволяет ввести нужные учётные данные для подключения. Но до того как подключаться к компьютеру его нужно добавить в список доверенных узлов (Trusted Hosts). Это делается командой:

Set-Item WSMan:\ localhost\Client\TrustedHosts -value ComputerName

где ComputerName — имя компьютера, к которому будем подключаться. Можно указать как имя компьютера, так и его IP-адрес, однако следует помнить, что то, что ввести здесь, то и нужно будет в последствии использовать для подключения, т.е. если указать IP-адрес, то нельзя будет подключиться к компьютеру, указывая его имя, нужно будет указывать IP-адрес, и наоборот.