Powershell и удалённый доступ

Команды Poweshell можно запускать на удалённом компьютере по сети. Для удалённого запуска команд должен быть настроен доступ и открыт порт в брандмауэре. Существуют несколько особенностей при удаленном доступе. Рассмотрим некоторые из них.
Note: в этом блоге уже рассматривался удалённый доступ Powershell подробности по сслыке
.

Включение удалённого доступа (Powershell Remote)

  1. Предварительные требования
    • Запущена служба WinRM
    • Открыт порт 5985 (HTTP), 5986 (HTTPS) в межсетевом экране
  2. Чтобы включить удалённый доступ запустите команду

    Enable-PSRemoting

    ИЛИ

    winrm quickconfig

  3. Проверка статуса службы удалённого доступа

    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

Note: PsExec

Для того чтобы включить удалённый доступ PowerShell нужно запустить команду Enable-PSRemoting на локальном компьютере. Можно ли включить PowerShell Remote на удалённом компьютере? Да! Если есть доступ администратора и открыты TCP-порты 135 и 445. Для этого можно использовать утилиту Sysinternals PsExec.

Для этого будет необходимо скачать PsExec на компьютер, с которого будет осуществляться подключение. На удалённом компьютере никаких программ устанавливать не нужно.

В общем виде работа PsExec выглядит следующим образом:

  1. Подключение к скрытой общей папке ADMIN$ (относящейся к папке C:\Windows) на удалённом компьютере через SMB
  2. Через менеджер сервисов Service Control Manager (SCM) запускается PsExecsvcservice и включается именованный канал (named pipe) на удалённой компьютере
  3. Ввод вывод консоли перенаправляется через созданный именованный канал

Подключиться к удалённому компьютеру и включить Powershell Remote

psexec.exe \\<computername> powershell.exe -command "& {Enable-PSRemoting -Force}"

Удалённое подключение Powershell (Remote Powershell)

По умолчанию удалённый доступ разрешён пользователям из группы локальных Администраторов на удалённом компьютере.
Если не использовать параметр Credentials, то подключение происходит под пользователем, запустившим команду.

  1. Запуск интерактивной сессии на удалённому компьютере

    Enter-PSSession Server01

    ИЛИ

    winrs -r:Server1 dir

  2. Завершить удалённую сессию

    Exit-PSSession

  3. Запуск комманды на нескольких удалённых компьютерах

    Invoke-Command -ComputerName Server01, Server02 -ScriptBlock {Get-UICulture}

  4. Запуск команд из скрипта на нескольких удалённых компьютерах

    Invoke-Command -ComputerName Server01, Server02 -FilePath c:\Scripts\DiskCollect.ps1

  5. Создать постоянную (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"}}

  6. Удалённый доступ на Workgroup компьютер или по IP адресу
    Если удалённый компьютер находиться не в домене (см. domain trust) или доступ осуществляется по IP адресу, то аутентификация может завершиться ошибкой. Соединение не установится.
    Для того, чтобы подключиться к такому компьютеру, нужно на локальном компьютере добавить его адрес в список доверенных компьютеров (trusted hosts). Проще всего добавить все возможные адреса, чтобы разрешить клиенту подключаться к любым удалённым компьютерам

    Set-Item WSMan:\localhost\Client\TrustedHosts -Value *

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

    1. Когда 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.

      https://helpcenter.gsx.com/hc/en-us/articles/202447926-How-to-Configure-Windows-Remote-PowerShell-Access-for-Non-Privileged-User-Accounts
      https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB0657528
      https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_remote_troubleshooting?view=powershell-7.1
      https://docs.microsoft.com/en-us/windows/win32/winrm/authentication-for-remote-connections
      https://stackoverflow.com/a/40266799
      https://stackoverflow.com/a/65024701

Удалённый доступ без Remote Powershell

  1. В команде присутствует параметр 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.
    https://docs.microsoft.com/en-us/powershell/scripting/learn/remoting/powershell-remoting-faq?view=powershell-7.1#do-all-remote-commands-require-powershell-remoting-
    https://stackoverflow.com/questions/39397495/credentials-parameter-with-get-counter

  2. В команде отсутствует параметр 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, то можно использовать команду, поддерживающую параметр Credential. В этом случае удалённый доступ Powershell не используется

    Get-WMIObject

Пользователь не админ

С настройками по умолчанию пользователь подключающийся удалённо должен быть в группе Администраторы на удалённом компьютере
Удалённо нельзя запустить сессию с правами администратора (как это можно сделать локально командой Start-Process -Verb RunAs).
Если команда, которую вы запускаете требует прав локального админа, то единственный способ, который вам остаётся это добавить пользователя в группу Администраторы на удалённом компьютере.
Однако существуют команды, которые можно настроить на исполнение без использования прав Администратора

  1. Get-Counter под обычным пользователем
    Что сделать:
    Добавить пользователя в группу Performance Monitor Users
  2. Get-WmiObject под обычным пользователем
    Что сделать:

    1. Открыть панель управления WMI (WMI Control) wmimgmt.msc на удалённом компьютере
    2. Перейти на вкладку Безопасность и щёлкнуть Дополнительно и Добавить
    3. Выбрать пользователя, которому дать доступ к WMI и нажать OK
    4. Выбрать тип Разрешить, применить к данному пространству имён и подпространству имён, выбрать разрешения Выполнение методов (Execute Methods) Включить учётную запись (Enable Account) и Включить удалённо (Remote Enable)
    5. Нажать ОК чтобы применить настройки
    6. Добавить пользователя в группу Distributed COM Users
  3. Get-Service под обычным пользователем
    Что сделать:
    Отредактировать SDDL для Service Control Manager. Добавить пользователя в список разрешённых для подключения к менеджеру сервисов

    1. Запустить CMD от имени администратора на удалённом компььютере и запустить команду

      sc sdshow scmanager

    2. Скопировать вывод команды SDDL
    3. Получить идентификатор пользователя (SID) для удалённого пользователя. Для доменной группы можно запустить Get-ADGroup "groupname"
    4. В скопированной строке SDDL вставить (A;;KA;;;SID) перед S:. SID нужно заменить на идентификатор из пункта выше. Пример D:...(A;;KA;;;SID)S:...
    5. Запустить sc sdset scmanager вместе с изменённой строкой SDDL. Пример sc sdset scmanager D:...(A;;KA;;;SID)S:...
    6. Если Get-Service не выводит определённый сервис, который присутствует на удалённом компьютере, то значит нужно изменить его доступ SDDL тем же образом. Только вместо scmanager нужно отредактировать SDDL для названия сервиса. Например, для просмотра SDDL сервиса SQL Server Agent можно запустить команду sc sdshow sqlserveragent
    7. https://stackoverflow.com/a/49888400

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

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s