пятница, 17 февраля 2012 г.

Удалённое взаимодействие с помощью PowerShell 2.0

Англоязычный источник, на основе которого выполнена эта статья, находится здесь.
В данной статье подробно объясняется тема удалённого взаимодействия с использованием 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
Для завершения сеанса удалённой работы, следует выполнить команду:
Exit-PSSession
Команде 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

Комментариев нет: