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

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



Подписаться
Уведомление о
guest
0 Комментарий
Inline Feedbacks
View all comments