Powershell и удалённый доступ
Команды Poweshell можно запускать на удалённом компьютере по сети. Для удалённого запуска команд должен быть настроен доступ и открыт порт в брандмауэре. Существуют несколько особенностей при удаленном доступе. Рассмотрим некоторые из них. Note: в этом блоге уже рассматривался удалённый доступ Powershell подробности по сслыке.
Включение удалённого доступа (Powershell Remote)
-
Предварительные требования
- Запущена служба WinRM
- Открыт порт
5985
(HTTP),5986
(HTTPS) в межсетевом экране
-
Чтобы включить удалённый доступ запустите команду
Enable-PSRemoting
ИЛИ
winrm quickconfig
-
Проверка статуса службы удалённого доступа
Test-WSMan
winrm get winrm/config/listener
Вывод команды:
Listener Address = * Transport = HTTP Port = 5985 Hostname Enabled = true URLPrefix = wsman CertificateThumbprint ListeningOn = X.X.X.X
-
Проверка прослушивания порта
netstat -ano | findstr :5985
0.0.0.0:5985
Если последняя команда выдаёт, что порт привязан к 127.0.0.1 (loopback), то удалённый доступ работать не будет. Нужно привязать порт ко всем IP адресам (0.0.0.0):
netsh http show iplisten netsh http delete iplisten 127.0.0.1 netsh http add iplisten ipaddress=0.0.0.0
PsExec
Для того чтобы включить удалённый доступ PowerShell нужно запустить команду Enable-PSRemoting на локальном компьютере. Можно ли включить PowerShell Remote на удалённом компьютере? Да! Если есть доступ администратора и открыты TCP-порты 135
и 445
. Для этого можно использовать утилиту Sysinternals PsExec.
Для этого будет необходимо скачать PsExec на компьютер, с которого будет осуществляться подключение. На удалённом компьютере никаких программ устанавливать не нужно.
В общем виде работа PsExec выглядит следующим образом:
- Подключение к скрытой общей папке
ADMIN$
(относящейся к папке C:\Windows) на удалённом компьютере через SMB - Через менеджер сервисов Service Control Manager (SCM) запускается PsExecsvcservice и включается именованный канал (named pipe) на удалённой компьютере
- Ввод вывод консоли перенаправляется через созданный именованный канал
Подключиться к удалённому компьютеру и включить Powershell Remote
psexec.exe \\<computername> powershell.exe -command "& {Enable-PSRemoting -Force}"
Удалённое подключение Powershell (Remote Powershell)
По умолчанию удалённый доступ разрешён пользователям из группы локальных Администраторов на удалённом компьютере. Если не использовать параметр Credentials, то подключение происходит под пользователем, запустившим команду.
-
Запуск интерактивной сессии на удалённому компьютере
Enter-PSSession Server01
ИЛИ
winrs -r:Server1 dir
-
Завершить удалённую сессию
Exit-PSSession
-
Запуск комманды на нескольких удалённых компьютерах
Invoke-Command -ComputerName Server01, Server02 -ScriptBlock {Get-UICulture}
-
Запуск команд из скрипта на нескольких удалённых компьютерах
Invoke-Command -ComputerName Server01, Server02 -FilePath c:\Scripts\DiskCollect.ps1
-
Создать постоянную (persistent) сессию на удалённом компьютере
$s = New-PSSession -ComputerName Server01, Server02 Invoke-Command -Session $s {$h = Get-HotFix} Invoke-Command -Session $s {$h | where {$_.InstalledBy -ne "NT AUTHORITY\SYSTEM"}}
Удалённый доступ на Workgroup компьютер или по IP адресу
Если удалённый компьютер находиться не в домене (см. domain trust) или доступ осуществляется по IP адресу, то аутентификация может завершиться ошибкой. Соединение не установится. Для того, чтобы подключиться к такому компьютеру, нужно на локальном компьютере добавить его адрес в список доверенных компьютеров (trusted hosts). Проще всего добавить все возможные адреса, чтобы разрешить клиенту подключаться к любым удалённым компьютерам
Set-Item WSMan:\localhost\Client\TrustedHosts -Value *
Это команду надо запустить на компьютере, с которого осуществляется подключение. Однако этого может оказаться не достаточно, чтобы запустить команду на компьютере в рабочей группе.
Когда TrustedHost не работает, даже если пользователь в группе локальных Администраторов
Если вы запускаете команду требующую повышения прав (elevated session), то это не сработает, если удалённый компьютер в рабочей группе. Т.е. если вы подключились под локальным пользователем (даже если он в группе администраторов), он все равно получает права обычного пользователя. Чтобы проверить является ли сессия на удалённом компьютере с полными правами (вернёт $true) или с правами обычного пользователя (вернёт $false) нужно запустить команду:
[Security.Principal.WindowsPrincipal]::new([Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
Ещё один способ проверить, если сессия с правами администратора или обычного пользователя
[bool] (net session 2>$null)
Почему сессия получает ограниченные права, даже если пользователь в группе администраторы? Это происходит потому что срабатывает политика фильтрации UAC (подробнее смотри статью по сслыке). Для того чтобы локальный пользователь в группе администраторов получал привилегированную сессию при удалённом подключении Powershell нужно включить ключ реестра LocalAccountTokenFilterPolicy
. Этот ключ потребуется для компьютеров в рабочей группе, поскольку для доменных компьютеров можно исопльзовать доменную учётную запись, находящуюся в группе Администраторов.
Set-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name LocalAccountTokenFilterPolicy -Value 1
Это команду надо запустить на компьютере, к которому осуществляется подключение. Ключ реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy = 1
позволяет локальным аккаунтам из группы администраторы подключаться к сервису WinRM.
Удалённый доступ без Remote Powershell
ComputerName
В команде присутствует параметр ComputerName Некоторые команды используют параметр Computername чтобы подключаться к нескольким компьютерам одновременно. Если у команды существует параметр Computername, то настройка удалённого Powershell доступа не требуется. Пример команд не использующих Powershell Remoting
Get-Process
Get-Service
Get-WinEvent
Get-EventLog
Get-WmiObject
Test-Connection
Как правило, если команда не использует powershell remote, у неё присутствует параметр computername и отсутствует параметр session. Чтобы найти такие команды, запустите:
Get-Command | where { $_.parameters.keys -contains "ComputerName" -and $_.parameters.keys -notcontains "Session"}
Эти команды не используют PowerShell Remoting.
Credential
В команде отсутствует параметр Credential По умолчанию, если не использовать параметр Credential то команда использует учётную запись пользователя, запустившего команду. Если вы хотите указать под каким пользователем подключаться и в команде отсутствует параметр Credential, то нужно использовать удалённый доступ Powershell
Invoke-Command
Пример использования параметра Credentials в удалённом доступе:
$secpasswd = ConvertTo-SecureString “PlainTextPassword” -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential (“username”, $secpasswd)
Invoke-Command -Computername XXXX -ScriptBlock {(get-counter -Counter "\Processor(_Total)\% Processor Time" -SampleInterval 1 -MaxSamples 5 | select -ExpandProperty countersamples | select -ExpandProperty cookedvalue | Measure-Object -Average).average} -Credential $mycreds
WMI
Если объект доступен по WMI, то можно использовать команду, поддерживающую параметр Credential. В этом случае удалённый доступ Powershell не используется
Get-WMIObject
Пользователь не админ
С настройками по умолчанию пользователь подключающийся удалённо должен быть в группе Администраторы на удалённом компьютере Удалённо нельзя запустить сессию с правами администратора (как это можно сделать локально командой Start-Process -Verb RunAs
). Если команда, которую вы запускаете требует прав локального админа, то единственный способ, который вам остаётся это добавить пользователя в группу Администраторы на удалённом компьютере. Однако существуют команды, которые можно настроить на исполнение без использования прав Администратора
Get-Counter под обычным пользователем
Что сделать: Добавить пользователя в группу Performance Monitor Users
Get-WmiObject под обычным пользователем
Что сделать:
- Открыть панель управления WMI (WMI Control)
wmimgmt.msc
на удалённом компьютере - Перейти на вкладку Безопасность и щёлкнуть Дополнительно и Добавить
- Выбрать пользователя, которому дать доступ к WMI и нажать OK
-
Выбрать тип Разрешить, применить к данному пространству имён и подпространству имён, выбрать разрешения
- Выполнение методов (Execute Methods)
- Включить учётную запись (Enable Account)
- Включить удалённо (Remote Enable)
-
Нажать ОК чтобы применить настройки
- Добавить пользователя в группу Distributed COM Users
Get-Service под обычным пользователем
Что сделать:
- Отредактировать SDDL для Service Control Manager.
-
Добавить пользователя в список разрешённых для подключения к менеджеру сервисов
-
Запустить CMD от имени администратора на удалённом компььютере и запустить команду
sc sdshow scmanager
-
Скопировать вывод команды SDDL
- Получить идентификатор пользователя (SID) для удалённого пользователя. Для доменной группы можно запустить
Get-ADGroup "groupname"
- В скопированной строке SDDL вставить
(A;;KA;;;SID)
передS:
. SID нужно заменить на идентификатор из пункта выше. ПримерD:...(A;;KA;;;SID)S:...
- Запустить
sc sdset scmanager
вместе с изменённой строкой SDDL. Примерsc sdset scmanager D:...(A;;KA;;;SID)S:...
- Если Get-Service не выводит определённый сервис, который присутствует на удалённом компьютере, то значит нужно изменить его доступ SDDL тем же образом. Только вместо scmanager нужно отредактировать SDDL для названия сервиса. Например, для просмотра SDDL сервиса SQL Server Agent можно запустить команду
sc sdshow sqlserveragent
-