У цій статті ми розглянемо особливості використання командлет Invoke-Command для віддаленого виконання команд і скриптів. Можливо запускати команди віддалено на одному комп’ютері, або паралельно на безлічі комп’ютерах у вашій мережі. Командлет Invoke-Command використовує можливості віддаленого управління, закладені в Віддалення PowerShell. PowerShell Remoting дозволяє віддалено підключатися до PowerShell сесій на комп’ютерах через службу WinRM (Windows Remote Management) через протокол Веб-служби для управління (WS-Management). Цей сервіс дає можливість приймати команди Powershell і встановлювати сеанси.

Налаштування WinRM для PowerShell Remoting

Для зв’язку між комп’ютерами в PowerShell Remoting використовується протокол HTTP (порт TCP / 5985) або HTTPS (порт TCP / 5986). За замовчуванням використовується протокол HTTP, але навіть цей трафік шифрується за допомогою ключа AES-256 (втім, є загроза атак man-in-the middle). Можлива аутентифікація через Kerberos (в домені) або NTLM.

На віддалених комп’ютерах, до яких ви плануєте підключатися повинен бути запущена служба WinRM. Перевірити це можна так:

Get-Service -Name "*WinRM*" | fl

Якщо служба не запущена, запустіть її:

Enable-PSRemoting

WinRM has been updated to receive requests.
WinRM service started.
WinRM is already set up for remote management on this computer.

Enable-PSRemoting включити і налаштувати winrm в Windows

Дана команда запустить службу WinRM (встановить автоматичний запуск), виставить настройки winrm за замовчуванням і додасть виключення в Windows Firewall. Команда Enable-PSRemoting -Force включає WinRM без запиту користувача.

Тепер до комп’ютера можна підключитися віддалено через PowerShell Remoting.

Зверніть увагу, що PowerShell Remoting за замовчуванням не працює, якщо тип вашої мережі визначено як загальнодоступна (Public). В цьому випадку команда поверне помилку:

Set-WSManQuickConfig : ... WinRM firewall exception will not work since one of the network connection types on this machine is set to Public. Change the network connection type to either Domain or Private and try again.

Вам потрібно змінити тип мережі на приватну (private), або використовувати команду:

Enable-PSRemoting –SkipNetworkProfileCheck.

Також потрібно включити правило Window Defender Firewall, яке дозволяє доступ до WinRM в загальнодоступних мережах. Ви можете включити правило брандмауера за допомогою GPO або PowerShell:

Set-NetFirewallRule -Name 'WINRM-HTTP-In-TCP' -RemoteAddress Any

Щоб перевірити підключення до віддаленого комп’ютера через PowerShell Remoting використовується команда:

Test-WsMan compname1

Test-WsMan - перевірити роботу winrm на віддаленому комп'ютері

Якщо у вас немає домену, або ви звертаєтеся до комп’ютерів через PowerShell Remoting по IP адресами, в цьому випадку використовується для аутентифікації використовується протокол NTLM. При використанні NTLM, при виконанні команду Invoke-Command з’явиться помилка:

[192.168.1.201] Connecting to remote server 192.168.1.201 failed with the following error message : The WinRM client cannot process the request. Default authentication may be used with an IP address under the following conditions: thetransport is HTTPS or the destination is in the TrustedHosts list, and explicit credentials are provided. Use winrm.cmd to configure TrustedHosts. Note that computers in the TrustedHosts list might not be authenticated. + FullyQualifiedErrorId : CannotUseIPAddress,PSSessionStateBroken

Ідентифікація Invoke-Command за замовчуванням може використовуватися з IP-адресою за таких умов: транспорт - HTTPS або пункт призначення - у списку TrustedHosts, і надаються явні облікові дані

Для коректної роботи NTLM аутентифікації, на комп’ютері, з якого ви будете встановлювати підключення потрібно скористатися додатковими функціями: випустити SSL сертифікат або додати ім’я / IP адреса хоста в довірені:

Set-Item wsman:localhostClientTrustedHosts -value 192.168.1.201

Параметр wsman:  localhost  Client  TrustedHosts

Або можна авторизувати до все комп’ютерів (не рекомендується, тому що один з головних недоліків NTLM – він не здійснює перевірку справжності).

Set-Item wsman:localhostClientTrustedHosts -value *

Аналогічні настройки потрібно зробити на віддалених хостах.

Щоб вивести список довірених хостів, виконайте команду:

Get-Item WSMan:localhostClientTrustedHosts

Щоб застосувати зміни, запустіть службу WinRM:

Restart-Service WinRM

Віддалене виконання PowerShell за допомогою Invoke-Command

Командлет Invoke-Command дозволяє виконати команду на одному або декількох віддалених комп’ютерах.

Наприклад, для запуску одиночної команди на віддаленому комп’ютері можна використовувати таку команду:

Invoke-Command -ComputerName dc01 -ScriptBlock {$PSVersionTable.PSVersion}

Invoke-Command -ComputerName -ScriptBlock - запуск команд powershell на віддаленому комп'ютері через winrm

Ця команда виведе в вашу консоль значення версії PowerShell, встановленої на віддаленому комп’ютері, ім’я якого зазначено в параметрі -ComputerName. У блоці -ScriptBlock {[cmdlet]} вказується команда, яку потрібно запустити на віддаленому комп’ютері.

За замовчуванням команда, послана через Invoke-Command виконується на віддаленому комп’ютері від поточного користувача. Якщо потрібно виконати команду від імені іншого користувача, спочатку потрібно запитати облікові дані користувача і зберегти їх в змінну:

$cred = Get-Credential
Invoke-Command -ComputerName comp-buh2 -Credential $cred -ScriptBlock {Get-NetAdapter}

Ця PowerShell команда виведе список мережевих інтерфейсів на віддаленому комп’ютері:

Можна задати кілька команд в блоці ScriptBlock, їх потрібно розділити крапкою з комою. Наприклад наступна команда виведе поточний часовий пояс і змінить його на інший:

Invoke-Command -Computername dc01 -ScriptBlock {Get-TimeZone| select DisplayName;Set-TimeZone -Name "Astrakhan Standard Time”}

Invoke-Command кілька команд в блоці ScriptBlock

Invoke-Command дозволяє виконувати не тільки окремі команди, а й запускати скрипти PowerShell. Для цього використовується аргумент -FilePath (Замість -ScriptBlock). При цьому ви вказуєте шлях до локального PS1 файлу скрипта на вашому комп’ютері (вам не потрібно копіювати файл скрипт на віддалений комп’ютер):

Invoke-Command -ComputerName Server01 -FilePath c:PSScriptsGetComputerInfo.ps1

Використовуємо Invoke-Command для паралельного запуску команд на декількох комп’ютерах

Командлет Invoke-Command можна використовувати для паралельного виконання команд на декількох віддалених комп’ютерах.

У самому просто випадку імена комп’ютерів, на яких потрібно виконати команди вказуються через кому:

Invoke-Command server1, server2, server3 -ScriptBlock {get-date}

Invoke-Command паралельний запуск команд на декількох компьютра

Список комп’ютерів можна помістити в змінну (масив):

$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 повернути результи з кожного комп'ютера через PSComputerName

При запуску команди через Invoke-Command на декількох комп’ютерах вона виконується паралельно. У Invoke-Command є обмеження на максимальну кількість комп’ютерів, якими можна управляти одночасно (обмеження на кількість одночасних PSSession). Воно визначається параметром ThrottleLimit (За замовчуванням 32). Якщо вам потрібно виконати команду одночасно більш ніж на 32 комп’ютерах (наприклад, на 128), використовуйте параметр -ThrottleLimit 128 (але це викликає підвищене навантаження на ваш комп’ютер).

Для запуску команд на віддалених комп’ютерах через Invoke-Command у фоновому режимі використовується спеціальний атрибут –AsJob. В цьому випадку результат виконання команди не повертається консоль. Щоб отримати результати потрібно використовувати командлет Receive-Job.

Leave a Reply

Your email address will not be published. Required fields are marked *