Архив за год: 2020



PowerShell: Метод IsInRole

В одной из заметок я рассматривал пример с повышением привилегий до администратора.
Вот фрагмент кода:

$IsAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator")

Здесь я делаю проверку прав текущего пользователя с помощью метода WindowsPrincipal.IsInRole и для данного случая всё это прекрасно работает.
Для другого скрипта мне потребовалось проверить, входит ли данный пользователь в группу администраторов и я решил использовать этот же метод. Но он мне не подошёл. Проблема в том, что работа этого метода проходит как бы в два этапа. Эта цитата имеет отношение к Windows Vista, но скорее всего работает и на поздних версиях Windows:

Члену встроенной группы «Администраторы» присваивается два маркера доступа на время выполнения: маркер доступа обычного пользователя и маркер доступа администратора. По умолчанию назначена роль обычного пользователя. При попытке выполнить задачу, для которой требуются права администратора, вы можете динамически повысить уровень роли с помощью диалогового окна «согласие».

 

Вот пример такого двойного состояния в Windows 10:
1. Мы находимся в сеансе пользователя-администратора и у нас включен Контроль учётных записей (UAC). Запускаем консоль PowerShell и пытаемся проверить текущую роль данного пользователя (админ он или пользователь с ограниченными правами):

([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator")

В этом случае мы получаем ответ: False
2. Мы находимся в сеансе пользователя-администратора и у нас включен Контроль учётных записей (UAC). Запускаем консоль PowerShell, но на этот раз с повышением привилегий и пытаемся проверить текущую роль данного пользователя (админ он или пользователь с ограниченными правами). Вызываем тот же самый метод:

([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator")

Но в этот раз нам приходит уже другой ответ: True

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

$user = "$env:COMPUTERNAME\$env:USERNAME"
$group = 'Administrators'
$isInGroup = (Get-LocalGroupMember $group).Name -contains $user

Правда стоит отметить, что он не очень универсальный, т.к. делает проверку по названию группы. В русской версии Windows оно естественно будет другим.

Использование SID вместо имени группы

Поэтому лучше будет, если использовать не имя группы, а её SID.

$user = "$env:COMPUTERNAME\$env:USERNAME"
$sid = 'S-1-5-32-544'
$isInGroup = (Get-LocalGroupMember -SID $sid).Name -contains $user

Теперь, не зависимо от локализации системы, можно проверить, состоит ли текущий пользователь в группе Администраторы.



Windows 10: Запустить редактор реестра без прав Администратора

В Windows 10 pro (build 19041) запустить редактор реестра с правами обычного пользователя нельзя. При запуске regedit.exe появляется запрос UAC. Если его отменить, приложение не запустится, если согласится, то придётся вводить данные для авторизации (пароль, либо ПИН). Мне же нужно было запустить редактор реестра именно от пользователя с ограниченными правами.
Удалось это сделать через командную строку:

cmd.exe /c "set __COMPAT_LAYER=RunAsInvoker && regedit.exe"