Для удаленного запуска команд или PowerShell скриптов на одном или нескольких удаленных компьютерах можно использовать командлет Invoke-Command.
Содержание:
- Настройка WinRM для PowerShell Remoting
- Выполнение удаленных команд через Invoke-Command
- Invoke-Command: одновременный запуск команд на нескольких компьютерах
- Постоянные сессии в PowerShell Remoting
Настройка 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
По умолчанию WinRM не будет работать для сетевых подключений, которые определяются как общедоступные (Public). Рекомендуется изменить тип сети в Windows на частную (private) или доменную. Если это невозможно, можно разрешить WinRM для общедоступных сетей и включить соответствующее правило брандмауэра:
Enable-PSRemoting -SkipNetworkProfileCheck
Set-NetFirewallRule -Name 'WINRM-HTTP-In-TCP' -RemoteAddress Any
Если компьютеры не в домене (используется рабочая группа), или вы обращаетесь к компьютерам через по IP адресам, в этом случае для аутентификации вместо Kerberos использоваться протокол NTLM. Чтобы разрешить NTLM аутентификацию через WimRM, нужно на компьютере (с которого вы будете устанавливать подключения) добавить имя/IP удаленного хоста в доверенные:
Set-Item wsman:\localhost\Client\TrustedHosts -value 192.168.1.201
Либо можно разрешить подключение ко все компьютерам (не рекомендуется, т.к. один из главных недостатков NTLM – он не осуществляет проверку подлинности)
Set-Item wsman:\localhost\Client\TrustedHosts -value *
Аналогичные настройки нужно сделать на удаленных хостах.
Чтобы вывести список доверенных хостов, выполните команду:
Get-Item WSMan:\localhost\Client\TrustedHosts
Чтобы применить изменения, перезапустите службу WinRM:
Restart-Service WinRM
Выполнение удаленных команд через Invoke-Command
Чтобы выполнить одну команду на удаленном компьютере, нужно указать имя компьютера (
-ComputerName
) и саму команду в блоке
{ScriptBlock}
:
Invoke-Command -ComputerName dc01 -ScriptBlock {$PSVersionTable.PSVersion}
Командлет отправит указанную команду на удаленный компьютер и выведет результат в консоль (результат возвращается в виде объекта PowerShell). В данном случае мы проверили состояние службы Windows Update на удаленном компьютере.
Чтобы прервать удаленный запуск команды через Invoke-Command, нажмите в консоли
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:\PS\Scripts\GetComputerInfo.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:\ps\servers.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
.
Для интерактивного запуска команды на удаленном компьютере, используйте командлет Enter-PSSession.
Постоянные сессии в 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
В наше время даже для собак придумали удаленное управление.
Возвращаясь к циклу «Конспект Админа», мне хотелось бы рассказать о вариантах запуска исполняемых программ на удаленных компьютерах. Эта статья будет интересна тем, у кого еще нет систем централизованного управления, но уже есть понимание утомительности ручного обхода рабочих станций и серверов. Либо тем, кому решения «под ключ» не интересны ввиду неспортивности.
В качестве того, зачем нужен такой запуск программ, можно привести недавнюю истерию с Петей\Не-Петей, когда все бросились проверять\отключать SMBv1 и загружать обновления. Да и провести инвентаризацию или установить срочный патч таким методом тоже можно.
Когда-то давно я устроился работать в организацию в период эпидемии Kido\Conficker. Наиболее простым способом выяснить, все ли хорошо в ИС компании, была славная утилита от Касперского под названием Kido Killer, которая проверяла наличие вируса и устраняла его. Запускать программу на доброй сотне машин руками было невесело, поэтому пришлось знакомиться с автоматизацией.
Если в операционных системах *nix для удаленного запуска, как правило, используется SSH, то у Windows способов запуска программ и скриптов воистину как песка в пустыне. Я разберу основные варианты, как общеизвестные, так и экзотические. Таких очевидных вещей как telnet-сервер касаться не буду, тем более Microsoft уже убрала его из современных ОС.
Способы старые, временем проверенные
Psexec
Пожалуй, это первое, что приходит на ум, когда идет речь об удаленном запуске программ. Утилита от Марка Руссиновича используется еще со времен Windows NT и до сих пор применяется. Помимо основной функции, можно использовать ее и как Runas, и для запуска программ в пользовательской сессии терминального сервера. Psexec также позволяет задавать ядра процессора, на которых будет запускаться программа, и ее приоритет в системе.
В качестве примера посмотрим, установлено ли обновление, закрывающее нашумевшую уязвимость SMB на списке компьютеров:
psexec @computers.txt /u USER /p PASS cmd.exe /v /c ""systeminfo | find "KB4012212" || echo !computername! >> \\server\share\log.txt"""
В файле computers.txt находится список компьютеров. Для запуска по всему домену можно использовать \\*. В файле \\server\share\log.txt будут появляться имена рабочих станций или серверов без обновления. Если в домене существуют компьютеры с *nix на борту или нет доступа к административному сетевому ресурсу Admin$ ― команда на этой машине не выполнится, но обработка продолжится. Чтобы скрипт не зависал при каждой попытке подключения, можно задать тайм-аут с помощью ключа -n.
Если компьютер выключен ― мы об этом не узнаем. Поэтому лучше предварительно проверять доступность машин или собирать в файле информацию об успешном или неудачном выполнении.
К минусам Psexec можно отнести то, что она из-за своего удобства и популярности часто используется вирусописателями. Поэтому антивирусные системы могут обнаруживать утилиту как опасность вида remote admin.
По умолчанию процесс на удаленной машине выполняется от имени пользователя, запустившего Psexec. При необходимости логин и пароль можно задать явно или же использовать аккаунт SYSTEM.
WMIC
Для управления системами Windows с помощью разных графических утилит часто используется WMI (Windows Management Instrumentation) ― реализация объектно-ориентированного стандарта управления WBEM. В качестве утилиты с графическим интерфейсом для работы с WMI можно использовать wbemtest.exe.
Для работы с WMI из консоли создана wmic.exe. Например, для проверки установленных обновлений вместо жутковатой конструкции из предыдущего примера можно использовать простую команду:
wmic /node:"servername" qfe get hotfixid | find "KB4012212"
Использовать список компьютеров также можно командой /node:»@computers.txt».
Еще при помощи WMI можно запускать программы – синтаксис предельно прост:
wmic /node:"servername" process call create "cmd /c somecommands"
К сожалению, в отличие от Psexec, получить вывод в консоли не получится ― придется выводить результаты команды в файл.
По умолчанию процесс на удаленной машине выполняется от имени пользователя, запустившего wmic. При необходимости логин и пароль можно задать явно.
Групповые политики и скрипты
Если предыдущие варианты не требовали доменной среды, то в этом случае потребуется домен. Поддерживаются скрипты при входе и выходе пользователя из системы, а также при ее включении и выключении. Поскольку каждый администратор Windows сталкивался с ними, я не буду подробно расписывать как ими пользоваться ― лишь напомню, где их искать.
Скрипты, выполняющиеся при старте и завершении системы.
Скрипты, выполняющиеся при входе и выходе пользователя из системы.
Скрипты, настраиваемые в пользовательском разделе, выполняются от имени пользователя, а в разделе компьютера ― под аккаунтом SYSTEM.
Назначенные задания
Довольно интересный способ, заслуживающий право на жизнь. Назначенные задания можно создавать из командной строки при помощи утилиты schtasks.exe, выполнять их, затем удалять. Подробнее с синтаксисом можно ознакомиться в документации, я же разберу пример использования назначенных заданий в доменной среде. Предположим, нам нужно выполнить команду как можно быстрее вне зависимости от того, выключен компьютер или нет. Для этого используются так называемые предпочтения групповых политик (Group Policy Preference).
Искать установку назначенных заданий следует в конфигурации компьютера или пользователя ― «Настройка ― Параметры панели управления ― Назначенные задания».
Создание нового назначенного задания.
Для выполнения команды или скрипта ASAP понадобится создать «Немедленную задачу (Windows 7 и выше)». Если вдруг в инфраструктуре остались машины под управлением Windows XP, то подойдет «Очередное задание (Windows XP)».
Стоит сделать несколько политик с соответствующими WMI-фильтрами или создать два разных назначенных задания в одной политике с нацеливанием ― например, при помощи того же WMI-фильтра. Это поможет избежать конфликтов в разнородной среде со старыми и новыми Windows.
Пример WMI-фильтра для применения политики только на компьютерах с Windows XP:
SELECT * FROM Win32_OperatingSystem WHERE Version LIKE "5.1%" AND ProductType = "1"
В остальном процедура создания назначенного задания тривиальна. Единственное, не забывайте отметить пункт «Применить один раз и не применять повторно», если задача не требует повторного запуска.
Запускаем немедленную задачу только один раз.
При использовании таких назначенных заданий программа запустится, как только компьютер получит обновление групповой политики. Это удобно: не нужно проверять доступность компьютеров в случае Psexec и wmic и заставлять пользователей перезагружать машины, как в случае скриптов групповых политик. При необходимости можно скопировать файл скрипта локально в разделе «Настройка ― Конфигурация Windows ― Файлы».
Назначенные задания позволяют явно задать имя пользователя для запуска программы, в том числе и для SYSTEM.
Через реестр
Модификация реестра на пользовательских машинах ― странный вариант, лишь на случай крайней необходимости. Можно использовать ветки Run или RunOnce. Подробнее о них ― в документации. Сама модификация реестра может проводиться через групповые политики или из командной строки ― например, такой командой:
reg add \\COMPUTER\HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce /v script /t Reg_SZ /d "script.cmd"
В зависимости от ветки реестра, процесс будет выполняться или под пользователем, выполнившим вход в систему, или под аккаунтом SYSTEM.
Есть и другие способы, такие как правка ярлыков в папке «Автозагрузка» или добавление в ярлык к популярной программе && script.cmd, но эти методы уже из серии «можно, но не нужно».
Теперь перейдем к новым инструментам.
Способы новые или куда же без PowerShell
PowerShell, оправдывая свое название, может подключаться к удаленным компьютерам при помощи WMI, RPC и WS-Management (WSMan). Использование последнего метода требует предварительной настройки.
Командлеты, не требующие предварительной настройки, как правило, имеют параметр ComputerName, но не имеют параметра Session. Посмотреть список таких командлетов можно командой:
Get-Command | where { $_.parameters.keys -contains "ComputerName" -and $_.parameters.keys -notcontains "Session"}
Для настройки WSMan в общем случае достаточно выполнить команду Enable-PSRemoting-Force. Она запустит службу удаленного управления WinRM и пропишет исключения в фаерволе ― в принципе, это можно сделать для всего домена при помощи групповых политик. Подробнее настройка описана в документации.
После того как все компьютеры будут готовы принимать запросы, мы сможем подключаться при помощи соответствующих командлетов PowerShell. Для проверки возможности подключения используется командлет Test-WSMan.
Проверка возможности подключения.
Для того чтобы выполнить определенную команду или скрипт, используется командлет Invoke-Command со следующим синтаксисом:
Invoke-Command -ComputerName COMPUTER -ScriptBlock { COMMAND } -credential USERNAME
Где COMPUTER ― имя компьютера, COMMAND ―– имя команды, а USERNAME ― имя пользователя, если оно нужно.
Смотрим содержимое диска С удаленного компьютера.
Если же нам нужно получить полноценную консоль ― не автоматизации ради, а ради управления конкретным компьютером, ― то можно использовать командлет Enter-PSSession.
Работаем в консоли удаленного компьютера.
Напомню, что с помощью JEA можно ограничить доступные подобной сессии командлеты или дать доступ нужным без прав администратора.
Конечно, кроме встроенных средств и небольших утилит, существует множество программ для управления структурой. Помимо взрослых решений, для управления конфигурациями вроде Chef, Ansible и MS SCCM можно использовать и средства мониторинга вроде Zabbix, и даже консоль управления антивирусом Касперского.
В период гетерогенных структур хорошо бы иметь возможность унифицированного управления Windows и Linux. Это можно сделать и с помощью PowerShell, что само по себе достойно отдельной статьи ― стоит такую сделать или уже лишнее?
Кстати, поделитесь вашими способами скрытого и не очень запуска программ на удаленных компьютерах. Ну, за исключением эксплойтов.
Quick Links
-
Enable PowerShell Remoting on the PC You Want to Access Remotely
-
Execute a Single Remote Command
PowerShell Remoting lets you run PowerShell commands or access full PowerShell sessions on remote Windows systems. It’s similar to SSH for accessing remote terminals on other operating systems.
PowerShell is locked-down by default, so you’ll have to enable PowerShell Remoting before using it. This setup process is a bit more complex if you’re using a workgroup instead of a domain—for example, on a home network—but we’ll walk you through it.
Enable PowerShell Remoting on the PC You Want to Access Remotely
Your first step is to enable PowerShell Remoting on the PC to which you want to make remote connections. On that PC, you’ll need to open PowerShell with administrative privileges.
In Windows 10, press Windows+X and then choose PowerShell (Admin) from the Power User menu.
In Windows 7 or 8, hit Start, and then type «powershell.» Right-click the result and choose «Run as administrator.»
In the PowerShell window, type the following cmdlet (PowerShell’s name for a command), and then hit Enter:
Enable-PSRemoting -Force
This command starts the WinRM service, sets it to start automatically with your system, and creates a firewall rule that allows incoming connections. The -Force
part of the cmdlet tells PowerShell to perform these actions without prompting you for each step.
If your PCs are part of a domain, that’s all the setup you have to do. You can skip on ahead to testing your connection. If your computers are part of a workgroup—which they probably are on a home or small business network—you have a bit more setup work to do.
Note: Your success in setting up remoting in a domain environment depends entirely on your network’s setup. Remoting might be disabled—or even enabled—automatically by group policy configured by an admin. You might also not have the permissions you need to run PowerShell as an administrator. As always, check with your admins before you try anything like this. They might have good reasons for not allowing the practice, or they might be willing to set it up for you.
Set Up Your Workgroup
If your computers aren’t on a domain, you need to perform a few more steps to get things set up. You should have already enabled Remoting on the PC to which you want to connect, as we described in the previous section.
Note: For PowerShell Remoting to work in a workgroup environment, you must configure your network as a private, not public, network. For more on the difference—and how to change to a private network if you already have a public network set up—check out our guide on private vs. public networks.
Next, you need to configure the TrustedHosts setting on both the PC to which you want to connect and the PC (or PCs) you want to connect from, so the computers will trust each other. You can do this in one of two ways.
If you’re on a home network where you want to go ahead and trust any PC to connect remotely, you can type the following cmdlet in PowerShell (again, you’ll need to run it as Administrator).
Set-Item wsman:\localhost\client\trustedhosts *
The asterisk is a wildcard symbol for all PCs. If instead you want to restrict computers that can connect, you can replace the asterisk with a comma-separated list of IP addresses or computer names for approved PCs.
After running that command, you’ll need to restart the WinRM service so your new settings take effect. Type the following cmdlet and then hit Enter:
Restart-Service WinRM
And remember, you’ll need to run those two cmdlets on the PC to which you want to connect, as well as on any PCs you want to connect from.
Test the Connection
Now that you’ve got your PCs set up for PowerShell Remoting, it’s time to test the connection. On the PC you want to access the remote system from, type the following cmdlet into PowerShell (replacing «COMPUTER» with the name or IP address of the remote PC), and then hit Enter:
Test-WsMan COMPUTER
This simple command tests whether the WinRM service is running on the remote PC. If it completes successfully, you’ll see information about the remote computer’s WinRM service in the window—signifying that WinRM is enabled and your PC can communicate. If the command fails, you’ll see an error message instead.
Execute a Single Remote Command
To run a command on the remote system, use the Invoke-Command
cmdlet using the following syntax:
Invoke-Command -ComputerName COMPUTER -ScriptBlock { COMMAND } -credential USERNAME
«COMPUTER» represents the remote PC’s name or IP address. «COMMAND» is the command you want to run. «USERNAME» is the username you want to run the command as on the remote computer. You’ll be prompted to enter a password for the username.
Here’s an example. I want to view the contents of the C:\ directory on a remote computer with the IP address 10.0.0.22. I want to use the username «wjgle,» so I would use the following command:
Invoke-Command -ComputerName 10.0.0.22 -ScriptBlock { Get-ChildItem C:\ } -credential wjgle
Start a Remote Session
If you have several cmdlets you want to run on the remote PC, instead of repeatedly typing the Invoke-Command cmdlet and the remote IP address, you can start a remote session instead. Just type the following cmdlet and then hit Enter:
Enter-PSSession -ComputerName COMPUTER -Credential USER
Again, replace «COMPUTER» with the name or IP address of the remote PC and replace «USER» with the name of the user account you want to invoke.
Your prompt changes to indicate the remote computer to which you’re connected, and you can execute any number of PowerShell cmdlets directly on the remote system.
Last Updated :
15 May, 2024
From the Command Line Interface on Windows, the Command Prompt Application first comes to your mind. However, another great Command Line Interface is Windows Terminal i.e. Windows Powershell which can be also useful.
If you want to perform Remote Command Execution on some other Remote Computers, then the Powershell on Windows will be used. This article will discuss the steps to Execute Remote Commands on Windows Powershell.
What is Remote Command Execution on Windows?
If you are on any local Windows OS & want to perform some actions on the Windows Powershell, the Execution of Remote Command will be the only option. The Remote Command Execution enables the method to access other Windows Powershell Applications from any single device with the help of the IP Address.
Once, you enter the Computer Name or IP Address of the Windows, those two computers will be associated only with Powershell. That means, the Powershell of two Windows Computers will be connected & from your device you can execute some commands on the Remote Device. Here, two entire Windows OS are not completely connected.
This practice can be useful for System Administrators who need to manage different computers at the same time across the network.
How to Enable Remote Command Execution on Powershell?
Note: By default, the Remote Command Execution on Windows Powershell is disabled. So, if you have to work on the concept, you have to Enable Powershell Remote Command Execution.
Step 1: Right-click on the Start Button & go for the Windows Powershell. Launch in the Administrative Format.
Step 2: Now, execute the following command there. It will Enable the Remote Command on Powershell.
Command: Enable-PSRemoting -Force
How to Check Remote Command Execution Connection on Powershell?
As you start the Powershell Remote Command Execution, you have to check whether the connection is correct or not. For that purpose, you can use the following command. If the Powershell Command is providing some output, the connection is correct. It will help to know whether the Remote Service is running on a Remote Computer or not.
Command: Test-WSMan <IP Address Or Remote Computer>
How to Run Remote Command Execution on Powershell?
Step 1: Once the Remote Command Execution Setup is completed, the following command should be used. It will connect the Local Windows Device along with the Remote Windows Device.
Command: Enter-PSSession -ComputerName <IP Address Or Remote Computer>
Step 2: Now, a Small Window will appear. You have to provide the Username & Password of the device there. Now, click on OK.
Step 3: Now, you will find the Computer Name will appear from the IP Address. Along with the Directory of Powershell will be changed. It is the indication that the Remote Connection is Successfully Created.
What are the Benefits of Remote Command Execution on Powershell?
Now, it is time to discuss the Benefits of Windows Powershell Remote Command Execution. There are multiple reasons behind to Use of Remote Execution of Commands on Powershell. Let us check all of those reasons one by one.
- Efficiency: The Administrator can effectively work on different devices with the same local device. From a single device, the Administrator can access different Powershell Applications on different Windows Devices places at a distance.
- Scalability: The Remote Command Execution increases the Scalability of any large project. At the same time, the Administrator can work on different computers without physically moving towards it. This increases the Scalability of the project.
- Consistency: Consistency can be maintained when you execute the Remote Command Execution. In this case, the Constant Configuration Settings can be changed in other devices from a single device.
Conclusion
From the above discussion, we conclude that Configuring Remote Command Execution on Powershell is a very simple task. You have to just enter the Windows Powershell Commands there properly. Also, you have to take care of the IP Address of the Remote Device as it will be inserted into the system for the connection.
Windows OS Hub / PowerShell / Invoke-Command: Run Commands or PowerShell Scripts on Remote Computers
The Invoke-Command cmdlet allows you to execute commands or PowerShell scripts remotely on one or more remote computers
Contents:
- How to Enable PowerShell Remoting (WinRM) on Windows
- Using Invoke-Commands to Run Commands on Remote Computers
- Running Commands on Multiple Computers with Invoke-Command
- PowerShell Remoting Persistent Connections
How to Enable PowerShell Remoting (WinRM) on Windows
The Invoke-Command cmdlet relies on PowerShell Remoting sessions to execute commands on remote computers. PowerShell Remoting is used to remotely control and execute commands and is based on the WS-Management protocol (implemented by WinRM, Windows Remote Management service). The HTTP (TCP/5985 port) or HTTPS (TCP/5986 port) protocol is used for communication with remote computers. By default, the HTTP protocol is used, but even this traffic is encrypted using an AES-256 key (although there is a risk of man-in-the-middle attacks). Authentication for PowerShell Remoting over WinRM can use Kerberos (for domain-joined systems), NTLM, or certificate-based (WinRM over HTTPS) auth.
To establish a PSSession with a remote computer, you must enable the WinRM service on that computer and allow remote connections:
Ensure that the WinRM service is running and a listener is properly configured on the target (client) computer:
Get-Service -Name "*WinRM*" | fl
WinRM enumerate winrm/config/listener
The WinRM service is not configured in this case. To enable it and allow remote connections through WinRM, run the following command:
winrm quickconfig
or
Enable-PSRemoting -Force
WinRM has been updated to receive requests. WinRM service started. WinRM is already set up for remote management on this computer.
This command starts the WinRM service (sets its startup type to Automatic), configures the default WinRM settings, and creates the necessary Windows Firewall exceptions.
Now, check if it is possible to remotely connect to the computer via PSRemoting:
By default, PowerShell Remoting doesn’t work for Public network connections. It is recommended to change the network location in Windows to Private or Domain. If this is not possible, you can allow WinRM for public networks and enable the appropriate firewall rule:
Enable-PSRemoting -SkipNetworkProfileCheck
Set-NetFirewallRule -Name WINRM-HTTP-In-TCP -RemoteAddress Any
If the remote hosts are not joined to the AD domain (i.e., when using a workgroup) or if the computers are accessed via IP addresses, NTLM authentication is used instead of Kerberos. To enable NTLM authentication through WimRM, add the name (or IP address) of the remote host to the trusted list on the administrator’s computer:
Set-Item wsman:\localhost\Client\TrustedHosts -value 192.168.1.201
Or you can allow PSRemote connection to all computers (not recommended, because one of the drawbacks of NTLM is that it doesn’t support mutual authentication).
Set-Item wsman:\localhost\Client\TrustedHosts -value *
The same settings must be applied to remote hosts.
List trusted hosts using the command:
Get-Item WSMan:\localhost\Client\TrustedHosts
Restart the WinRM service to apply the changes:
Restart-Service WinRM
Using Invoke-Commands to Run Commands on Remote Computers
To execute a single command on a remote computer, specify the computer name (-ComputerName
) and the command itself in the -ScriptBlock {[command]}
.
Invoke-Command -ComputerName dc01 -ScriptBlock {Get-Service wuauclt}
The cmdlet sends the specified command to the remote computer and prints the result to the console (the result is returned as a PowerShell object). In this case, we received the Windows Update service status on a remote computer.
To interrupt a remotely executed command in Invoke-Command, press CTRL+C
in the console.
The Invoke-Command cmdlet runs commands on behalf of the user who is running the PowerShell console. Use the -Credential parameter to run a command as a different user:
$cred = Get-Credential
Invoke-Command -ComputerName dc01 -Credential $cred -ScriptBlock {Get-NetAdapter}
This PowerShell command lists the network interfaces on a remote computer:
- By default, only the members of the local ‘Administrators‘ and ‘Remote Management Users‘ groups have permission to connect remotely via PSRemoting.
- If the command sent to the remote computer includes a request to access a remote resource (for example, a shared network folder), authentication to the second resource will fail. This problem is called Double-Hop and is related to Windows security restrictions that prevent credentials from being passed to a third party.
To run multiple commands sequentially on a remote computer, separate them with semicolons within the ScriptBlock. For example, the following command will display the current time zone and change it to another one:
Invoke-Command -Computername dc01 -ScriptBlock {Get-TimeZone| select DisplayName;Set-TimeZone -Name "Central Europe Standard Time"}
The Invoke-Command cmdlet allows you to run not only individual commands but also PowerShell scripts. To do this, specify the path to the local PS1 file with the script in the -FilePath parameter:
Invoke-Command -ComputerName DC01 -FilePath C:\PS\Scripts\CheckSMBversion.ps1
- This method of running remote scripts eliminates the need to manually copy the PowerShell script file to remote computers
- The PowerShell execution policy settings are ignored in this case.
Use the $using construct when you need to pass the value of a local variable from a script to an Invoke-Command block:
$localVar = Get-Date
Invoke-Command -ComputerName Server01 -ScriptBlock {
"Date = $using:localVar"
}
Running Commands on Multiple Computers with Invoke-Command
The Invoke-Command cmdlet allows you to run commands simultaneously (in parallel) on multiple remote computers. The simplest way is to use commas to separate the names of the computers on which the PowerShell commands will be executed:
Invoke-Command server1, server2, server3 -ScriptBlock {get-date}
You can save the list of remote hosts in a variable (array):
$servers = @("server1","server2","server3")
Invoke-Command -ScriptBlock { get-date} -ComputerName $servers
Or get from a text file:
Invoke-Command -ScriptBlock {Restart-Service spooler} -ComputerName(Get-Content c:\ps\servers.txt)
You can also retrieve a list of computers from Active Directory using the Get-ADComputer cmdlet from the AD PowerShell module. For example, to run a command on all Windows Server hosts in a domain, use this code:
$computers = (Get-ADComputer -Filter 'OperatingSystem -like "*Windows server*" -and Enabled -eq "true"').Name
Invoke-Command -ComputerName $computers -ScriptBlock {Get-Date} -ErrorAction SilentlyContinue
If the computer is powered off or unavailable, the SilentlyContinue parameter will prevent the script from halting, allowing it to continue running on other computers.
To understand from which computer the results were received, you need to use a special environment variable, PSComputerName.
$results = Invoke-Command server1, server2, server3 -ScriptBlock {get-date}
$results | Select-Object PSComputerName, DateTime
Invoke-Command has a limit on the maximum number of simultaneous sessions with remote computers. The default is 32 (determined by the ThrottleLimit parameter). If you need to run the command on more than 32 computers simultaneously (for example, 128), use the -ThrottleLimit 128
parameter.
To run commands on a remote computer in the background using Invoke-Command, a special –AsJob
option is used. The result of remote command execution is not returned to the console in this case. Use the Receive-Job
cmdlet to get the results of the remote command.
PowerShell Remoting Persistent Connections
If you frequently need to run commands on a remote computer, you can establish a persistent PSRemoting session with that computer. This prevents the Invoke-Command cmdlet from initiating a new remote connection each time.
Let’s create a persistent session with one or more remote computers:
$s = New-PSSession -ComputerName Server01, Server02
Now use the -Session parameter to run a command in the PSSession that you created:
Invoke-Command -Session $s -ScriptBlock { Get-ComputerInfo|select OsLastBootUpTime }
To close the remote persistent session, close the PowerShell console or run:
Remove-PSSession $s