Примечание: данный пост перепечатан в связи с закрытием бложиков на spaces.live.com, как имеющий какую-то ценность для автора и/или читателей.
Время от времени администраторам приходится иметь дело с настройкой разрешений NTFS для объектов (файлов, папок, ключей реестра). Для этого, например, в CMD созданы специальные утилиты как XCACLS и ICACLS (более совершенная версия XCACLS). Однако, эти утилиты позволяют работать только с файловой системой, управление списками ACL в реестре данными утилитами невозможно. Для управления ACL списками доступа реестра из командной строки есть утилита REGINI и SubInACL. В PowerShell это уже есть всё внутри. Командлета по управлению ACL всего 2:
Здесь приведу простой пример использования командлета Get-ACL для папки Windows:
[C:\] Get-Acl .\WINDOWS | Format-List Path : Microsoft.PowerShell.Core\FileSystem::C:\WINDOWS Owner : BUILTIN\Administrators Group : NT AUTHORITY\SYSTEM Access : CREATOR OWNER Allow 268435456 NT AUTHORITY\Authenticated Users Allow -1610612736 NT AUTHORITY\Authenticated Users Allow ReadAndExecute, Synchronize NT AUTHORITY\SYSTEM Allow 268435456 NT AUTHORITY\SYSTEM Allow FullControl BUILTIN\Administrators Allow 268435456 BUILTIN\Administrators Allow FullControl BUILTIN\Server Operators Allow -536805376 BUILTIN\Server Operators Allow Modify, Synchronize Audit : Sddl : O:BAG:SYD:PAI(A;OICIIO;GA;;;CO)(A;OICIIO;GXGR;;;AU)(A;;0x1200a9;;;AU)(A;OICIIO;GA;;;SY)(A;;FA;;;SY)(A;OICIIO;G A;;;BA)(A;;FA;;;BA)(A;OICIIO;SDGXGWGR;;;SO)(A;;0x1301bf;;;SO)
В результате вывода команды PowerShell покажет достаточно исчерпывающую информацию о списке ACL для указанной папки. Можно так же вывести список ACL в переменную, например я это сделаю на примере реестра:
[C:\] cd HKLM: [HKEY_LOCAL_MACHINE] $ACL = Get-Acl [HKEY_LOCAL_MACHINE] $ACL | Format-List Path : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\ Owner : BUILTIN\Administrators Group : NT AUTHORITY\SYSTEM Access : Everyone Allow ReadKey NT AUTHORITY\RESTRICTED Allow ReadKey NT AUTHORITY\SYSTEM Allow FullControl BUILTIN\Administrators Allow FullControl Audit : Sddl : O:BAG:SYD:(A;CI;KR;;;WD)(A;CI;KR;;;RC)(A;CI;KA;;;SY)(A;CI;KA;;;BA)
Командой cd HKLM: я переключился с файловой системы на реестр. И используя те же самые приёмы могу управлять списками ACL в реестре. Экспортировав список ACL в переменную дальше уже можно управлять ею как заблагорассудится. Сейчас я покажу несколько вариантов применения такого способа при помощи уже команды Set-Acl.
Предположим, есть папка Test и папка Test1. И мы хотим скопировать разрешения папки Test на Test1 без копирования содержимого папок. Для этого нужно выполнить 2 операции:
Выглядеть это будет следующим образом:
# здесь я скопировал список ACL в переменную $ACL $ACL = Get-Acl -path "Test" # в этой строке я уже применил переменную для команды Set-Acl. Set-Acl -path "Test2" -AclObject $ACL
После выполнения этих двух строк можно будет убедиться, что разрешения обеих папок будут полностью идентичны.
Внимание: данный скрипт может вернуть ошибку, если пользователь, из под которого выполняется скрипт не является владельцем исходного ресурса (в нашем примере это папка Test) и не обладает правом локальной политики Take Ownership. Дело в том, что при переносе разрешений нельзя перенести другого владельца. Если владельцем папки Test является текущий пользователь и он обладает правом Take Ownership, то все разрешения и Owner будут скопированы на папку Test2. Если же одно из условий не выполняется, то скрипт выдаст ошибку переноса Owner на другой ресурс.
Но если нам нужно создать с нуля структуру разрешений? Тогда всё решается через Set-Acl. Для установки разрешений NTFS используется .NET класс, который называется: FileSystemAccessRule и список прав перечислен в FileSystemRights Enumeration. Чтобы посмотреть какие разрешения мы можем задавать для ACL достаточно в PowerShell выоплнить команду:
[system.enum]::getnames([System.Security.AccessControl.FileSystemRights])
там же в списке будут указаны и составные разрешения как Read, Write, Modify, которые состоят из набора более детальных разрешений (они обычно показываются в основной вкладке Security для файла или папки). Итак, попробуем для начала дать пользователю TestUser право Modify для папки C:\Test, на которую по умолчанию он имеет лишь право Read (через группу Users). Для этого мы сначала считаем текущий список ACL с папки Test:
$ACL = Get-ACL C:\Test
Теперь создадим переменную с указанием пользователя, прав доступа и типа разрешения (Allow или Deny):
$Setting = "TestUser","Modify","Allow"
Теперь необходимо передать эту переменную в класс FileSystemAccessRule для создания объекта:
$AccessRule = new-object System.Security.AccessControl.FileSystemAccessRule $Setting
Ну и теперь, собственно, можно уже применять объект с параметрами (пользователь, тип доступа) в ACL целевой папки:
$ACL.SetAccessRule($AccessRule) $ACL | Set-Acl C:\Test
После выполнения этого простенького скрипта пользователь TestUser получит разрешение Modify на папку C:\Test. Конечно же, нельзя сказать, что данный вариант является более предпочтительным, чем XCACLS или ICACLS, но тем не менее это интергрированное рабочее решение, которое может быть легко модифицировано для других задач управления списками ACL объектов.
В следующей статье (это будет вторая часть) я усложню задачу для командлетов Get-Acl/Set-Acl - а именно, расскажу, как работать с наследованием разрешений и управлением глубиной действия наследования.
Comments: