Для удаленного запуска команд или PowerShell скриптов на одном или нескольких удаленных компьютерах можно использовать командлет Invoke-Command.
Настройка WinRM для PowerShell Remoting
Для установки связи с удаленным компьютерами командлет Invoke-Command использует сессии PowerShell Remoting. Технология удаленного управления и запуска команд PowerShell Remoting основана на протоколе WS-Management (реализуется через службу WinRM, Windows Remote Management). Для связи с удаленным компьютерами используются протокол HTTP (порт TCP/5985 ) или HTTPS (порт TCP/5986 ). По умолчанию используется протокол HTTP, но даже этот трафик шифруется с помощью ключа AES-256 (впрочем, есть угроза атак man-in-the middle). Возможна аутентификация через Kerberos (в домене) или NTLM.
Чтобы установить сессию (PSSession) с удаленным компьютерам, на нем нужно включить службу WinRM и разрешить удаленные подключения:
Проверьте, что на клиенте запущена служба WinRM и слушатель службы (WinRM listener):
Get-Service -Name "*WinRM*" | fl
WinRM enumerate winrm/config/listener

В данном случае служба WinRM не настроена. Чтобы включить ее и разрешить удаленные подключения через WinRM, выполните команду:
winrm quickconfig
или
Enable-PSRemoting -Force
WinRM has been updated to receive requests. WinRM service started. WinRM is already set up for remote management on this computer.

Эта команда запустит службу WinRM (установит автоматический запуск), задаст настройки winrm по-умолчанию и добавит исключения в Windows Firewall.
Теперь проверьте возможно ли удаленное подключение к компьютеру через PSRemoting:
Test-WsMan compname1

Enable-PSRemoting -SkipNetworkProfileCheck
Set-NetFirewallRule -Name 'WINRM-HTTP-In-TCP' -RemoteAddress Any Set-Item wsman:localhostClientTrustedHosts -value 192.168.1.201 Либо можно разрешить подключение ко все компьютерам (не рекомендуется, т.к. один из главных недостатков NTLM – он не осуществляет проверку подлинности)
Set-Item wsman:localhostClientTrustedHosts -value * Аналогичные настройки нужно сделать на удаленных хостах.
Чтобы вывести список доверенных хостов, выполните команду:
Get-Item WSMan:localhostClientTrustedHosts
Чтобы применить изменения, перезапустите службу WinRM:
Restart-Service WinRM

Выполнение удаленных команд через Invoke-Command
Чтобы выполнить одну команду на удаленном компьютере, нужно указать имя компьютера ( -ComputerName ) и саму команду в блоке {ScriptBlock} :
Invoke-Command -ComputerName dc01 -ScriptBlock {$PSVersionTable.PSVersion}
Командлет отправит указанную команду на удаленный компьютер и выведет результат в консоль (результат возвращается в виде объекта PowerShell). В данном случае мы проверили состояние службы Windows Update на удаленном компьютере.

CTRL+C .Командлет Invoke-Command выполняет команды от имени пользователя, под которым запущена консоль PowerShell. Чтобы выполнить команду от другого пользователя, используется параметр -Credential :
$cred = Get-Credential
Invoke-Command -ComputerName comp-buh2 -Credential $cred -ScriptBlock {Get-NetAdapter}
Эта PowerShell команда выведет список сетевых интерфейсов на удаленном компьютере:

- Право на удаленное подключение через PSRemoting есть у членов группы локальных администраторов и Remote Management Users.
- Если в отправляемой на удаленный компьютер команде есть обращение к удаленному ресурсу (например папке сетевой папке), при аутентфикации на втором ресурсе произойдёт ошибка. Эта проблема называется double hop (двойной прыжок) и связана с ограничениями безопасности Windows, запрещающими передачу учетных данных на третий ресурс.
Если на компьютере нужно выполнить несколько последовательных команд, их нужно разделить точкой с запятой в блоке ScriptBlock. Следующая команда выведет текущий часовой пояс и изменит его на другой:
Invoke-Command -Computername dc01 -ScriptBlock {Get-TimeZone| select DisplayName;Set-TimeZone -Name "Astrakhan Standard Time"}

Командлет Invoke-Command позволяет запускать не только отдельные команды, но и скрипты PowerShell. Для этого нужно указать путь к локальному PS1 файлу со скриптом в параметре -FilePath :
Invoke-Command -ComputerName Server01 -FilePath c:PSScriptsGetComputerInfo.ps1
- При таком способе закуска не нужно вручную копировать ваш PowerShell скрипт на удаленные компьютеры
- Настройки политики выполнения скриптов PowerShell игнорируются
Если нужно передать значение локальной переменной из скрипта в блок команд Invoke-Command, используется конструкцию $using :
$localVar = Get-Date
Invoke-Command -ComputerName Server01 -ScriptBlock {
"Date = $using:localVar"
}
Invoke-Command: одновременный запуск команд на нескольких компьютерах
Командлет Invoke-Command позволяет выполнить вашу команду одновременно (параллельного) на нескольких удаленных компьютерах. В самом просто случае имена компьютеров, на которых нужно выполнить команды указываются через запятую:
Invoke-Command server1, server2, server3 -ScriptBlock {get-date}

Список компьютеров можно поместить в переменную (массив):
$servers = @("server1","server2","server3")
Invoke-Command -ScriptBlock { get-date} -ComputerName $servers
Или получить из текстового файла:
Invoke-Command -ScriptBlock {Restart-Service spooler} -ComputerName(Get-Content c:psservers.txt)
Также можно получить список компьютеров в ADс помощью командлета Get-ADComputer из модуля AD PowerShell. Например, чтобы выполнить команду на всех Windows Server в домене, используйте такой код:
$computers = (Get-ADComputer -Filter 'operatingsystem -like "*Windows server*" -and enabled -eq "true"').Name
Invoke-Command -ComputerName $computers -ScriptBlock {get-date} -ErrorAction SilentlyContinue
Если компьютер выключен, или недоступен, благодаря параметру SilentlyContinue скрипт не будет остановлен и продолжит выполнение на других компьютерах.
Чтобы понять с какого компьютера получены результаты, нужно использовать специальную переменную окружения PSComputerName.
$results = Invoke-Command server1, server2, server3 -ScriptBlock {get-date}
$results | Select-Object PSComputerName, DateTime

В Invoke-Command есть ограничение на максимальное количество одновременных сессий с компьютерами. По умолчанию она равно 32 (определяется параметром ThrottleLimit. Если вам нужно выполнить команду одновременно более чем на 32 компьютерах (например, на 128), используйте параметр –ThrottleLimit 128 .
Для запуска команд на удаленных компьютерах через Invoke-Command в фоновом режиме используется специальный атрибут –AsJob . В этом случае результат выполнения команды не возвращается в консоль. Чтобы получить результаты нужно использовать командлет Receive-Job .
Постоянные сессии в PowerShell Remoting
Если вам часто нужно выполнять команды на удаленном компьютер, можно создать постоянную PSRemoting сессию с удаленным компьютером. В этом случае командлету Invoke-Command не нужно будет каждый раз инициировать удаленное подключение.
Создадим постоянную (persistent) сессию с удаленным одним или несколькими компьютерами:
$s = New-PSSession -ComputerName Server01, Server02
Теперь, чтобы выполнить команду в созданном сеансе PSSession, используйте параметр -Session:
Invoke-Command -Session $s -ScriptBlock { Get-ComputerInfo|select OsLastBootUpTime } 
Чтобы закрыть удаленную сессию, нужно закрыть консоль PowerShell или выполнить:
Remove-PSSession $s

Добавить комментарий