Когда я начал использовать PowerShell, я увлекся командой Get-Service и заметил, что у нее есть параметр -ComputerName. Не означает ли это, что можно подключиться к службе и с других компьютеров? После проведения ряда экспериментов я обнаружил, что это как раз то, что написано. Я заинтересовался и принялся искать параметры -ComputerName у других команд. И расстроился, когда выяснил, что их было только несколько.

.

PowerShell обеспечивает два типа удаленного взаимодействия: удаленное взаимодействие один к одному (1:1) и удаленное взаимодействие один к нескольким (1:n). Прежде чем рассказать о них, хочу пояснить некоторые основы.

Основы удаленного взаимодействия в PowerShell

Удаленное взаимодействие PowerShell работает почти как Telnet и другие старые технологии удаленного управления. Когда вы запускаете команду, она на самом деле запускается на удаленном компьютере. Все, что возвращается на ваш компьютер, является результатом работы этой команды. В отличие от Telnet или Secure Shell (SSH), PowerShell использует новый протокол системы связи, который называется Web Services for Management (WS-Management). Протокол действует поверх HTTP или HTTP Secure (HTTPS), что облегчает прокладывание маршрута через брандмауэры, если это необходимо, поскольку протокол использует только один порт для установления связи. Реализация WS-Management от Microsoft идет в форме фоновой службы, которая называется Windows Remote Management. WinRM устанавливается вместе с PowerShell 2.0 и запускается по умолчанию на серверах, подобных Windows Server 2008 R2. На Windows 7 она устанавливается по умолчанию, но не активируется. Необходимо активировать WinRM на тех компьютерах, на которые вы хотите послать команду. Компьютер, за которым вы находитесь физически, не нуждается в запуске службы WinRM.

Все команды PowerShell производят объекты в качестве выходных данных. Когда вы запускаете команду удаленно, ее выходные данные нужно облечь в форму, которую можно легко передавать по сети, используя протокол HTTP или HTTPS. Так, PowerShell автоматически преобразует выходные объекты в файлы XML, которые передаются по сети. Достигнув вашего компьютера, они преобразовываются обратно в объекты, с которыми может работать PowerShell. Однако эти преобразованные обратно объекты на самом деле являются мгновенными снимками. Они не могут обновлять сами себя ежеминутно. Таким образом, если вы должны добраться до объектов, которые представляют собой процессы, запускаемые на удаленном компьютере, то полученный результат будет верен только для конкретного промежутка времени, в течение которого эти объекты были сгенерированы. Значения, такие как использование памяти и процессора, не изменятся. Более того, вы не сможете заставить преобразованные обратно объекты сделать что-либо. Например, вы не можете приказать объекту остановить самого себя. Это основное ограничение удаленного взаимодействия, но оно не помешает вам работать и выполнять интересные задачи.

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

  • Как ваш компьютер (он же локальный компьютер) и один из тех, которым вы хотите послать команду (он же удаленный компьютер), должны работать с Windows PowerShell 2.0? Windows XP является устаревшей версией Windows, на которую вы можете установить PowerShell 2.0. Таким образом, старая версия тоже может принимать участие в удаленной сессии.
  • В идеале локальный и удаленный компьютеры должны быть членами одного домена или членами доверенных/доверяющих доменов. С системой удаленного взаимодействия можно работать и вне домена, но это сложно, и здесь я об этом рассказывать не буду. Чтобы узнать больше об этом сценарии, обратитесь к разделу PowerShell Help, где говорится о Remote_Troubleshooting.

Обзор WinRM

Теперь перейдем к WinRM, поскольку вам необходимо задавать настройки этой службы для запуска удаленного взаимодействия. Опять повторюсь, требуется только задать настройки удаленного взаимодействия WinRM и PowerShell на удаленном компьютере. В большинстве сред, в которых я работал, администраторы активировали систему удаленного взаимодействия на каждом компьютере, работающем с версиями XP или более новыми. Это дает возможность проникать в настольные и портативные компьютеры незаметно, что может быть очень полезным (это означает, что пользователи таких компьютеров не будут знать, что вы делаете).

Нельзя сказать, что WinRM представляет собой что-то особенное для PowerShell. WinRM может прокладывать трафик к нескольким административным приложениям. По существу, WinRM действует как диспетчер. Когда трафик появляется, WinRM решает, какое приложение должно взаимодействовать с ним, и помечает его именем приложения-адресата. Принимающее приложение должно зарегистрироваться в WinRM, таким образом WinRM сможет прослушивать входящий трафик от его имени. Другими словами, вам нужно не только активировать WinRM, но и зарегистрировать Power Shell как конечную точку для WinRM.

Самым простым способом выполнения обеих задач является запуск PowerShell от имени администратора и выполнение команды Enable-PSRemoting. Вы можете посмотреть руководство по другой команде, которая называется Set-WSManQuickConfig. Нет нужды запускать команду. Это сделает за вас Enable-PSRemoting, и она же выполняет еще несколько шагов, которые необходимы для установления удаленного взаимодействия и работы. В сущности, команда Enable-PSRemoting запускает службу WinRM, задает ее настройки для запуска автоматически, регистрирует PowerShell как конечную точку и даже устанавливает исключения в Windows Firewall для того, чтобы разрешить входящий трафик WinRM.

Если вам не хочется обходить все компьютеры ради активации удаленного взаимодействия, можно задействовать объект групповой политики Group Policy Object (GPO). Необходимые настройки GPO встроены в контроллеры домена Windows Server 2008 R2. Просто откройте GPO и идите по маршруту Computer Configuration\

Administrative Templates\Windows Components. Внизу списка вы найдете как Remote Shell, так и Windows Remote Management (WRM), настройки которых нужно задать. Раздел Help о проблемах системы удаленного взаимодействия (Remote_Troubleshooting) даст вам детальные инструкции о том, как это сделать. Просмотрите разделы How to Enable Remoting in an Enterprise и How to Enable Listeners by Using a Group Policy в Help.

WinRM 2.0 (который применяется PowerShell) по умолчанию использует порт TCP 5985 для HTTP и порт 5986 для HTTPS. Это гарантирует, что WinRM не будет конфликтовать с локально установленными веб-серверами, которые настроены на прослушивание портов 80 и 443. Вы можете задать настройки WinRM для использования альтернативных портов, но я не рекомендую этого делать. Ели вы оставите эти порты, все команды удаленного доступа PowerShell будут работать нормально. Если вы измените эти порты, вам придется всегда указывать альтернативный порт при запуске команды удаленного доступа. Это означает, что вам придется больше печатать. Если вам крайне необходимо изменить порт, можете ввести команду:

Winrm set winrm/config/
   listener? Address=*
   +Transport=HTTP @{Port="1234"}

Цифры 1234 означают порт, который вам нужен. Здесь эта команда написана в несколько строк, но вам нужно вводить ее в одну строку. То же самое касается и всех других команд, описанных в статье. Если необходимо использовать HTTPS вместо http, вы можете видоизменить эту команду, чтобы настроить новый порт HTTPS. Должен признаться, что есть способ задать настройки WinRM на локальных компьютерах для того, чтобы задействовать альтернативные порты по умолчанию. Таким образом, вам не нужно постоянно определять альтернативный порт, когда вы запускаете команду удаленного доступа. Но давайте поработаем с настройками по умолчанию, заданными Microsoft.

Если покопаться в настройках GPO в Remote Shell, вы заметите, что можете задать, например, насколько долго удаленная сессия будет оставаться неактивной до того, как сервер прервет ее; как много одновременно действующих пользователей могут обращаться к удаленному серверу за один раз; как много памяти и процессов каждая удаленная оболочка может использовать; максимальное количество удаленных оболочек, которые пользователи могут открывать за один раз. Эти настройки помогут убедиться, что ваши серверы не перегружены забывчивыми администраторами. Однако по умолчанию необходимо быть администратором, чтобы использовать удаленное взаимодействие, поэтому вам не стоит беспокоиться об обычных пользователях, засоряющих ваши серверы.

Удаленное взаимодействие 1:1

Используя удаленное взаимодействие 1:1, вы, по существу, получаете доступ к командной строке на одном удаленном компьютере. Любые команды, которые вы даете, запускаются прямо на удаленном компьютере, а вы видите результаты в окне командной строки. Отчасти это похоже на использование Remote Desktop Connection, если не считать того, что вы ограничены средой командной строки PowerShell. Система удаленного взаимодействия PowerShell использует часть ресурсов, которые требует Remote Desktop, поэтому она оказывает намного меньшее воздействие на ваши серверы.

Для того чтобы установить соединение 1:1 с удаленным компьютером, названным Server-R2, нужно запустить

Enter-PSSession -Computername Server-R2

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

[server-r2] PS C:\>

Часть [server-r2] информирует вас о том, что все, что вы делаете, происходит на Server-R2. После этого вы можете запустить любые команды, какие хотите. Вы даже можете импортировать любые модули и добавить расширения PowerShell (PSSnapins), которые будут располагаться на удаленном компьютере.

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

  • Если у вас есть сценарий PowerShell для вашего профиля на удаленном компьютере, он не будет запускаться, когда вы подсоединитесь, используя систему удаленного доступа. Проще говоря, профили являются пакетом команд, которые автоматически запускаются каждый раз, когда вы открываете окно командной строки. Они используются для автоматической загрузки расширений, модулей и тому подобного.
  • Вы ограничены политикой Execution Policy удаленного компьютера. Скажем, политика вашего компьютера устанавливается на RemoteSigned так, что вы можете запускать локальные неподписанные сценарии. Если политика удаленного компьютера установлена в Restricted (настройка по умолчанию), она не позволит запускать никакие сценарии, когда вы взаимодействуете удаленно.

Многие команды PowerShell идут в парах: одна делает нечто, другая — противоположное этому. В нашем случае Enter-PSSession подсоединяет вас к удаленному компьютеру, а Exit-PSSession закрывает это соединение. Exit-PSSession не нужны никакие параметры. После запуска удаленное соединение закрывается, и приглашение вашего окна командной строки возвращается обратно к нормальному виду. А что если вы забудете запустить Exit-PSSession? Не беспокойтесь. PowerShell и WinRM способны выяснить, что вы сделали, и закрыть в случае необходимости удаленное соединение.

Хочу дать один совет. Когда вы подсоединяетесь к удаленному компьютеру, не запускайте на нем Enter-PSSession до тех пор, пока полностью не осознаете, что вы делаете. Например, вы работаете на ComputerА. Вы подсоединяетесь к Server-R2. В строке PowerShell вы запускаете

[server-r2] PS C:\> Enter-PSSession
   Server-DC4

Теперь Server-R2 содержит открытое соединение с Server-DC4. Это создает «цепь удаленного взаимодействия», которую отследить сложно. Кроме того, ваши серверы без надобности оказываются перегруженными. Могут быть моменты, когда вы должны будете делать это (например, Server-DC4 находится за брандмауэром и вы не можете получить к нему прямой доступ, поэтому в качестве посредника вам нужно использовать Server-R2). Однако общее правило состоит в следующем: старайтесь избегать цепочек удаленного взаимодействия.

Удаленное взаимодействие 1:n

Одна из самых интересных вещей в PowerShell — это удаленное взаимодействие 1: n. Оно позволяет вам отсылать команды на несколько удаленных компьютеров одновременно — полномасштабные распределенные вычисления. Каждый компьютер по отдельности будет выполнять команду и отсылать вам результаты. Все делается при помощи команды Invoke-Command в таком виде:

Invoke-Command -ComputerName
   Server-R2, Server-DC4, Server12
   -Command {Get-EventLog Security
   -Newest 200 |
   Where {$_.EventID -eq 1212}}

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

Единственный параметр, которого вы не увидите на странице Help этой команды, — параметр Command. Он, как я уже показал, работает прекрасно. Параметр Command является псевдонимом или кратким именем для параметра ScriptBlock, который указан на странице Help. Для меня проще использовать Command, поэтому я склонен задействовать именно его вместо ScriptBlock, однако они работают одинаково.

Если вы прочитали страницу Help для Invoke-Command внимательно, вы также заметили параметр, который позволяет указывать файл сценария, а не команду. Параметр FilePath позволяет посылать сценарий на удаленные компьютеры; это означает, что вы можете автоматизировать некоторые сложные задачи, а каждый компьютер будет выполнять свою долю работы.

Теперь остановимся на параметре Computer Name. В примере кода Invoke-Command у меня был список имен компьютера, разделенный запятыми. Если у вас много компьютеров, то вы, возможно, не хотите печатать их имена каждый раз, когда подсоединяетесь к ним. Вместо этого вы можете создать текстовый файл, который содержит по одному имени компьютера на одной строке, без запятых, кавычек или чего-то еще. Например, если бы ваш текстовый файл был назван webservers.txt, вы бы использовали такой код:

Invoke-Command -Command { dir }
   -ComputerName (Get-Content
      webservers.txt)

Круглые скобки заставляют PowerShell выполнять сначала команду Get-Content — это похоже на то, как работают круглые скобки в математике. Затем результаты Get-Content вкладываются в параметр -ComputerName.

Возможен также запрос имени компьютера в Active Directory, но это сложнее. Для того чтобы найти компьютер, вы можете использовать команду Get-ADComputer, но вы не вставите эту команду в круглые скобки, как делали это в Get-Content. Почему нет? Get-Content выдает простые текстовые строки, тогда как Get-ADComputer производит объекты типа «компьютер». Параметр -ComputerName ожидает строки. Если бы он должен был получать объекты «компьютер», то не знал бы, что с ними делать. Поэтому, если вы хотите использовать Get-ADComputer, вам нужно получить значения из свойства Name компьютерных объектов. Вот так:

Invoke-Command -Command {dir}
   -ComputerName (Get-ADComputer
   -Filter * -SearchBase
   "ou=Sales, dc=company, dc=pri" |
   Select-Object -Expand Name)

В круглых скобках компьютерные объекты передаются команде Select-Object, а параметр -Expand используется для выяснения свойства Name этих компьютерных объектов. Результат выражения в скобках — это набор имен компьютера, а не компьютерных объектов. Имена компьютеров — это как раз то, что нужно параметру -Computer Name.

Если вы не знакомы с Get-ADComputer, давайте посмотрим, что делает эта команда. Параметр -Filter определяет, что все компьютеры должны быть включены в результаты, а параметр -Search Base предписывает PowerShell, чтобы он начал искать компьютеры в организационной группе Sales (OU) в домене company.pri. Команда Get-ADComputer доступна только в Windows Server 2008 R2 и в Windows 7 после установки набора утилит Remote Server Administration Tools. В этих операционных системах вы запускаете

Import-Module ActiveDirectory

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

Есть кое-что еще!

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

Чтобы создать постоянные сессии, нужно использовать команду New-PSSession, затем сохранить их в переменной для легкого доступа. Например, следующий код создает сессию удаленного взаимодействия с тремя компьютерами и сохраняет их в переменной $sessions:

$sessions = New-PSSession
   -ComputerName One, Two, Three
   -Port 5555
   -Credential DOMAIN\Administrator

Сессии удаленного взаимодействия закрываются автоматически, когда вы закрываете командную оболочку, но до этого времени они могут занимать память и немного загружать процессор на локальной и удаленной системах. Для того чтобы точно закрыть их, вы можете использовать команду Remove-PSSession:

$sessions | Remove-PSSession

Когда вам нужно вновь открыть сессии, вы можете задействовать команду Invoke-Command:

Invoke-Command -Command {dir}
   -Session $sessions

Или можете применить Enter-PSSession:

Enter-PSSession
   -Session $session [1]

Заметьте, что в коде Enter-PSSession только одна сессия удаленного взаимодействия открывается повторно. Переменная индекса 1 сообщает PowerShell, что он должен вновь открыть сессию с компьютером, названным Two (индекс отсчитывается с нулевого значения).

Как мы видим, пользы от удаленного взаимодействия PowerShell очень много. Если вы будете использовать его, вы убедитесь, как сильно он расширит горизонты вашей деятельности.

Дон Джоунз (powershell@concentratedtech.com) — технический инструктор по PowerShell (www.windowsitpro.com/go/DonJonesPowerShell), автор более 35 книг. Имеет звание Microsoft MVP