- Вопрос или проблема
- ИЛИ
- PowerShell (Решение 1)
- PowerShell (Решение 2)
- Поддерживающие ресурсы
- Ответ или решение
- Запуск сценария PowerShell от имени другого пользователя с повышенными привилегиями
- Проблема
- Решения
- 1. Использование параметра -RunAsUser
- 2. Копирование скрипта на локальный диск
- 3. Использование PsExec
- Рекомендации
- Заключение
Вопрос или проблема
Я знаю, что это выглядит как дублирующий вопрос, но я пробовал решения, и они не сработали для меня.
Нам нужно запустить скрипт с нашими учетными записями домена, но также выполнить его с повышенными привилегиями. Это не проблема на большинстве устройств, поскольку ярлык запускается от администратора и запрашивает у нас учетные данные. Однако, если пользователь является локальным администратором, нас не просят ввести учетные данные (только окно 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) – поскольку 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 с различными учетными данными и уровнем привилегий представляет собой важный навык для администраторов. Используя предложенные методы, вы сможете более эффективно управлять задачами и избегать распространенных ошибок. Помните, что безопасность является важным аспектом, и старайтесь избегать использования местных учетных записей администратора, когда это возможно.