Запустите сценарий PowerShell от имени другого пользователя с повышенными привилегиями.

Вопрос или проблема

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

Нам нужно запустить скрипт с нашими учетными записями домена, но также выполнить его с повышенными привилегиями. Это не проблема на большинстве устройств, поскольку ярлык запускается от администратора и запрашивает у нас учетные данные. Однако, если пользователь является локальным администратором, нас не просят ввести учетные данные (только окно UAC с запросом “да/нет”).

Я запутался, почему это не сработало:

# Получить идентификацию пользователя скрипта
$identity = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()

# Повысить права скрипта, если еще не повышены
if ($identity.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Host -F Green 'ПОВЫШЕН'
} else {
    Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"& '$PSCommandPath'`""
    Exit
}

# Убедитесь, что у скрипта есть привилегии домена
if ($identity.IsInRole('[домен]\[админ группа]')) {
    Write-Host -F Green 'ДОМЕННЫЙ АДМИН'
} else {
    Start-Process PowerShell -Verb RunAsUser "-NoProfile -ExecutionPolicy Bypass -Command `"& '$PSCommandPath'`""
    Pause # требуется, иначе нижеуказанный Exit закроет окно UAC
    Exit
}
Pause

Когда самоподнятый скрипт запускается как пользователь и введены учетные данные домена, он теряет повышение… т.е. когда Start-Process -Verb RunAsUser powershell запускается из повышенного PowerShell, он сам не повышается.

Я также попробовал следующее:

Start-Process powershell -verb RunAs -argumentlist "Start-Process powershell.exe -Verb RunAsUser `"& path\to\script.ps1`""

Что неудачно, потому что доменный администратор не имеет доступа к каталогу скрипта… если только он не с повышенными правами.

Вы автоматизируете что-то или просто время от времени запускаете скрипт? Находится ли каталог скрипта на локальном диске или в сети?

Как вы заметили, запуск нового экземпляра powershell с runas не изменит пользователя, а runasuser не повысит процесс. Вам нужно сделать их в противоположном порядке. Если вы вошли как локальный администратор, запустите Powershell с RunAsUser или через:

  • Shift+Правый клик > Запустить от имени другого пользователя > Доменный администратор

Затем выполните ваш runas, чтобы повысить права оттуда (как доменный администратор):

Start-Process PowerShell -Verb RunAs

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

ИЛИ

если вы управляете ПК удаленно и уже используете powershell, подключитесь с помощью powershell, так как сессия всегда будет с повышенными правами:

Enter-PSSession MyPCName -credential (get-credential -username domain\MyAdmin)
# удаленная сессия:
[MyPCName]: PS C:\WINDOWS\system32>

Я также должен рекомендовать никогда не использовать локальный администраторский аккаунт, если это возможно.

Альтернативным инструментом является бесплатный инструмент sysinternals
PsExec.

Команда будет выглядеть так:

psexec -u domain\user -h -i command [arguments]

Параметры:

  • -i : Запускает программу так, чтобы она взаимодействовала с рабочим столом указанной сессии на удаленной системе. Если сессия не указана, процесс запускается в консольной сессии.
  • -h : Если целевая система Vista или выше, процесс запускается с повышенным токеном учетной записи, если он доступен.

Небезопасной практикой является также указание пароля:

-p : Указывает опциональный пароль для имени пользователя. Если вы пропустите это, вам будет предложено ввести скрытый пароль.

Простое решение – сначала скопировать скрипт из места, которое требует учетных данных домена в котором вы уже вошли, на локальную файловую систему машины, с которой вам нужно выполнить его с повышенными правами. Затем выполните скрипт с повышенными правами с этой локальной копии.

Выполняйте Start-Process Powershell немного иначе, чем вы его выполняли, чтобы он выполнял логику скрипта, работая с повышенными правами. Добавьте параметры ExecutionPolicy Bypass -NoProfile -File и выполните скрипт после этого, чтобы это заработало.

Примечание: Оба приведенные ниже примера решений PowerShell используют корень диска “C” по адресу C:\ локальной файловой системы, но вы можете изменить это соответствующим образом.

PowerShell (Решение 1)

Copy-Item "path\to\script.ps1" -Destination "C:\" -Force;
Start-Process Powershell -Argumentlist '-ExecutionPolicy Bypass -NoProfile -File "C:\script.ps1"' -Verb RunAs;

Если вам нужно аутентифицироваться с учетными данными домена, чтобы получить доступ к пути скрипта, вы можете использовать invoke-command с параметром -credential, чтобы выполнить операцию копирования. Затем вы можете выполнить скопированный на локальную файловую систему скрипт с повышенными правами таким образом.

PowerShell (Решение 2)

$cred = Get-Credential "domain\username";
Invoke-Command -ScriptBlock {
    Copy-Item "path\to\script.ps1" -Destination "C:\" -Force;
    } -Credential $cred;

Start-Process Powershell -Argumentlist '-ExecutionPolicy Bypass -NoProfile -File "C:\script.ps1"' -Verb RunAs;

Поддерживающие ресурсы

Несколько объясняющих моментов:

  1. Сначала вам нужно запустить, затем запросить повышение – так как ‘запустить от имени другого пользователя’ не сохраняет никаких повышенных привилегий вызывающего
  2. Вашему пользователю доменного администратора потребуются разрешения на доступ (по крайней мере, только для чтения) к скрипту, который вы вызываете, даже когда они не с повышенными правами
  3. Вы в настоящее время проверяете членство в группе [домен]\[админ группа], когда проверяете, есть ли у вас ‘запустить от имени другого пользователя’. Вы не можете проверить группу доменного администратора, если вы ‘запускаете от имени другого пользователя’, прежде чем получить повышение (пункт 1) – поскольку UAC фильтрует все группы с повышенными привилегиями (Рисунок 3) – тем не менее параметр скрипта должен сработать

Вот обновленный скрипт, который делает то, что вам нужно:

Param (
    [Switch]$RunAsUser = $false
)

# Пройти как другой пользователь, если еще не сделано
if ($RunAsUser) {
    Write-Host -F Green 'ЗАПУСТИТЬ КАК ДРУГОЙ ПОЛЬЗОВАТЕЛЬ'
} else {
    Start-Process $PSHOME\powershell.exe -Verb RunAsUser "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" -RunAsUser"
    Start-Sleep 120 # Позволить 2 минуты для открытия окна 'Запуск от имени другого пользователя' (по умолчанию тайм-аут UAC)
    Exit
}

# Получить идентификацию пользователя скрипта
$identity = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()

# Повысить права скрипта, если еще не повышены
if ($identity.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Host -F Green 'ПОВЫШЕН'
} else {
    Start-Process $PSHOME\powershell.exe -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" -RunAsUser"
    Exit
}
Pause

Быстрое и простое решение:

$Var1 = 1
$Var2 = 2
$Var3 = 3

Start-Process -FilePath 'pwsh.exe' -Verb 'RunAs' "-Command & {
    Some-Command -Arg $Var1
    Some-Command -Arg $Var2
    Some-Command -Arg $Var3
}"

Создание ScriptBlock и его вызов с переданными аргументами – это действительно сложно в сравнении.

В моем понимании, в общем, исполняющий пользователь и привилегии текущего процесса не могут быть изменены во время его выполнения, но они устанавливаются в момент запуска процесса ядром операционной системы.
Поэтому вам следует отделить блок кода, который вы хотите выполнить с повышенными привилегиями, и запустить его с помощью RunAs (или его вариантов).
Если изменение привилегий в процессе возможно, это станет очень опасной уязвимостью безопасности операционной системы.

Кроме того, локальные привилегии (local administrator) и доменные привилегии ([домен]\[админ группа]) определяются отдельно.
Если вы хотите предоставить DomainA\User01 как local administrator, ТАК И DomainA\AdminGroup, вам нужно сделать оба:

  • предоставить DomainA\User01 в локальную группу безопасности компьютера local administrator, И
  • предоставить DomainA\User01 в доменную группу безопасности DomainA\AdminGroup

а затем выполнить скрипт с помощью RunAs.

Ответ или решение

Запуск сценария PowerShell от имени другого пользователя с повышенными привилегиями

Возникновение ситуации, когда необходимо запустить PowerShell скрипт с использованием доменной учетной записи, при этом обеспечивая повышенные привилегии, может представлять сложности для специалистов в области ИТ. Данная статья предназначена для разъяснения методов, позволяющих решить эту задачу.

Проблема

При запуске сценария PowerShell с привилегиями локального администратора у вас есть возможность взаимодействия с UAC (Контроль учетных записей). Однако, если вы хотите использовать учетные данные доменного администратора и продолжить работу с повышенными правами, вам нужно использовать определенные методы запуска.

Частые сценарии:
  • Стандартный запуск через контекстное меню или иконку может не позволить взаимодействовать с UAC, если пользователь уже обладает правами администратора.
  • Если доменный администратор не имеет доступа к сценариям на пути выполнения, выполнение может завершиться ошибкой.

Решения

1. Использование параметра -RunAsUser

Одним из наиболее эффективных способов является использование параметра -RunAsUser и его сочетание с запуском от имени другого пользователя. Давайте рассмотрим пример сценария, который можно использовать:

Param (
    [Switch]$RunAsUser = $false
)

if ($RunAsUser) {
    Write-Host -ForegroundColor Green 'RUN AS DIFFERENT USER'
} else {
    Start-Process PowerShell -Verb RunAsUser "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" -RunAsUser"
    Start-Sleep 120 # Ожидание для диалога 'Запуск от другого имени'
    Exit
}

$identity = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()

if ($identity.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Host -ForegroundColor Green 'ELEVATED'
} else {
    Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" -RunAsUser"
    Exit
}

2. Копирование скрипта на локальный диск

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

$cred = Get-Credential "domain\username"
Invoke-Command -ScriptBlock {
    Copy-Item "path\to\script.ps1" -Destination "C:\" -Force;
} -Credential $cred;

Start-Process PowerShell -ArgumentList '-ExecutionPolicy Bypass -NoProfile -File "C:\script.ps1"' -Verb RunAs;

3. Использование PsExec

Инструмент Sysinternals PsExec может быть использован для запуска процессов от имени другого пользователя с повышенными правами:

psexec -u domain\user -h -i command [arguments]

Следует помнить, что использование флага -p, чтобы указать пароль, является небезопасной практикой.

Рекомендации

  • Разделение привилегий: Используя локальную учетную запись администратора, вы все равно должны обеспечить необходимый доступ доменной учетной записи, когда это возможно.
  • Тестирование: Перед применением предложенных решений на реальных системах, обязательно протестируйте их в безопасной тестовой среде.

Заключение

Запуск скриптов PowerShell с различными учетными данными и уровнем привилегий представляет собой важный навык для администраторов. Используя предложенные методы, вы сможете более эффективно управлять задачами и избегать распространенных ошибок. Помните, что безопасность является важным аспектом, и старайтесь избегать использования местных учетных записей администратора, когда это возможно.

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

Капча загружается...