Для управления доступом к файлам и папкам в Windows на каждый объект файловой системы NTFS (каталог или файл) назначается специальный ACL (Access Control List, список контроля доступа). В ACL объекта задаются доступные операции (разрешения), которые может совершать с этим объектом пользователь и/или группы . В большинстве случаев администраторы Window для управления NFTS разрешениями на файлы и папки используют графический интерфейс File Explorer (свойства папки/файла -> вкладка Security/Безопасность) или консольную утилиту icacls. В этой статье мы рассмотрим способы управления разрешениями на объекты файловой системы NTFS из PowerShell. Вы можете использовать эти команды в скриптах и для автоматизации управлением NTFS разрешениями на файловых серверах Windows.
Встроенные командлеты для управления ACL в NTFS: Get-Acl и Set-Acl
В PowerShell v5 (Windows 10 / Windows Server 2016) для управления ACL имеется два отдельных встроенных командлета (входят в модуль Microsoft.PowerShell.Security):
- Get-Acl — позволяет получить текущие ACL для конкретного объекта на файловой системе NTFS;
- Set-Acl – используется для добавления/изменения текущих ACL объекта.
Мы не будем подробно останавливаться на этих встроенных командлетах, т.к. их функционал в большинстве случае недостаточен для управления NTFS разрешениями в реальных задачах. Рассмотрим лишь несколько типовых примеров их использования.
Выведем текущего владельца папки (файла) и список назначенных NTFS разрешений:
get-acl C:\Drivers\ |fl
Path : Microsoft.PowerShell.Core\FileSystem::C:\Drivers\
Owner : WORKSTAT1\root
Group : WORKSTAT1\Отсутствует
Access : NT AUTHORITY\Authenticated Users Allow Modify, Synchronize
NT AUTHORITY\SYSTEM Allow FullControl
BUILTIN\Администраторы Allow FullControl
BUILTIN\Пользователи Allow ReadAndExecute, Synchronize
WORKSTAT1\root Allow Modify, Synchronize
Audit :
Sddl : O:S-1-5-21-3650440056-3766451173-3310994491-1001G:S-1-5-21-3650440056-766451173-3310994491-513D:PAI(A;OICI;0x 1301bf;;;AU)(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;0x1200a9;;;BU)(A;OICI;0x1301bf;;;S-1-5-21-3650440056-37664 51173-3310994491-1001)
Можно вывести только списки NTFS разрешений в более понятном формате:
(get-acl C:\Drivers\).access
С помощью следящей команды можно скопировать NTFS разрешения с одной папки и применить их на другую:
Get-Acl C:\Drivers | Set-Acl C:\Distr
Главная проблема при использовании Set-ACL – командлет всегда пытается сменить владельца ресурса, даже если вы просто хотите изменить NTFS разрешения. В результате, чтобы добавить права на объект нужно использовать такую конструкцию:
$path = "c:\drivers"
$user = "WORKSTAT1\user1"
$Rights = "Read, ReadAndExecute, ListDirectory"
$InheritSettings = "Containerinherit, ObjectInherit"
$PropogationSettings = "None"
$RuleType = "Allow"
$acl = Get-Acl $path
$perm = $user, $Rights, $InheritSettings, $PropogationSettings, $RuleType
$rule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $perm
$acl.SetAccessRule($rule)
$acl | Set-Acl -Path $path
Чтобы убрать NTFS доступ к папке для пользователя или группы:
$path = "c:\drivers"
$acl = Get-Acl $path
$rules = $acl.Access | where IsInherited -eq $false
$targetrule = $rules | where IdentityReference -eq "WORKSTAT1\user1"
$acl.RemoveAccessRule($targetrule)
$acl | Set-Acl -Path $path
Чтобы отключить наследование для папки из PowerShell:
$path = 'C:\dist'
$acl = Get-ACL -Path $path
$acl.SetAccessRuleProtection($True, $True) # первый $True указывает, является ли данный каталог защищенным, второй $True – нужно ли скопировать текущие NTFS разрешения
Set-Acl -Path $path -AclObject $acl
Используем модуль NTFSSecurity для управления разрешениями из PowerShell
Как я уже говорил, встроенный модуль для управления ACL на объекты в PowerShell не самый удобный. Для управления NTFS правами на файлы и папки в Windows лучше использовать отдельный модуль их галереи PowerShell – NTFSSecurity. Последнюю версию модуля NTFSSecurity (4.2.4 на данный момент) можно установить командой
Install-Module -Name NTFSSecurity
, или скачать вручную (линк). При ручной установке достаточно распаковать содержимое архива модуля в каталог C:\Windows\System32\WindowsPowerShell\v1.0\Modules\NTFSSecurity (не забудьте разблокировать скачанные файлы).
Импортируйте модуль NTFSSecurity в сессию PowerShell:
Import-Module NTFSSecurity
Выведем список команд, доступных в модуле (доступно 36 командлетов):
Get-Command -Module NTFSSecurity
Выведем текущие NTFS разрешения на каталог:
Get-Item 'c:\distr' | Get-NTFSAccess
Как вы видите, текущие разрешения представлены в более удобной форме.
Чтобы предоставить конкретному пользователю и группе группе полные права на папку, выполните команду:
Add-NTFSAccess -Path C:\distr -Account 'WORKSTAT1\confroom','BUILTIN\Администраторы' -AccessRights 'Fullcontrol' -PassThru
Чтобы предоставить права только на верхнем уровне и не изменять разрешения на вложенные объекты (только на папку), используйте команду:
Add-NTFSAccess c:\data\public -Account corp\aaivanov -AccessRights Modify -AppliesTo ThisFolderOnly
Удалить назначенные NTFS разрешения:
Remove-NTFSAccess -Path C:\distr -Account 'WORKSTAT1\confroom' -AccessRights FullControl -PassThru
Следующей командой можно лишить указанную учетную прав на все вложенные объекты в указанной папке (наследованные разрешения будут пропущены):
Get-ChildItem -Path C:\distr -Recurse | Get-NTFSAccess -Account 'WORKSTAT1\confroom' -ExcludeInherited |Remove-NTFSAccess -PassThru
Следующей командой можно назначить учетную запись Administrator владельцем всех вложенных объектов в каталоге:
Get-ChildItem -Path C:\distr -Recurse -Force | Set-NTFSOwner -Account 'Administrator'
Чтобы очистить все разрешения, назначенные на объекты каталога вручную (не будет удалены унаследованные разрешения):
Get-ChildItem -Path C:\distr -Recurse -Force | Clear-NTFSAccess
Включить NTFS наследование для всех объектов в каталоге:
Get-ChildItem -Path C:\distr -Recurse -Force | Enable-NTFSAccessInheritance
Чтобы вывести все разрешения, которые назначены вручную, исключая унаследованные разрешения:
dir C:\distr | Get-NTFSAccess –ExcludeInherited
Можно вывести разрешения, назначенные для определенного аккаунта (не путайте с эффективными разрешениями, речь о них ниже):
dir C:\distr | Get-NTFSAccess -Account corp\aaivanov
Проверка эффективных NTFS разрешений на объекты из PowerShell
Вы можете проверить эффективные NTFS разрешения на конкретный файл или папку с помощью командлета
Get-EffectiveAccess
. Допустим вы предоставили доступ на некоторую папку нескольким группам безопасности AD и теперь хотите понять, есть ли у конкретного аккаунта (SID) доступ к данной папке или нет. Как это сделать, не выводя состав групп AD, в которых входит его учетная запись? В этой ситуации как раз поможет функция проверки эффективные NTFS разрешений. Допустим, нужно проверить эффективные права на все вложенные папки в каталоге для пользователя confroom.
Get-ChildItem -Path c:\distr -Recurse -Directory | Get-NTFSEffectiveAccess -Account 'WORKSTAT1\confroom' | select Account, AccessControlType, AccessRights, FullName
Либо вы можете проверить эффективные разрешения на конкретный файл:
Get-Item -Path 'C:\distr\mstsc.exe.manifest' | Get-NTFSEffectiveAccess -Account 'WORKSTAT1\confroom' | Format-List
Get-acl, set-acl работают рекурсивно?
Нет, сами по себе командлеты get-acl и set-acl не поддерживают рекурсию, но их можно использовать совместно с get-childitem например:
get-childitem "C:\distr\" -recurse | get-acl
Friends, help write a script to transfer the ACL from .wim to the current system.
Required:
— clear the current access rights of the current system
— transfer permissions to files and folders for all users from .wim
— inheritance rules for folders from .wim
— the final step to transfer the owner of the folders (including the system folders: TrustedInstaller)
What I have at the moment:
$wPath = Read-Host "Enter original location for reading ACL (D: \ wim \) " # mounted image .wim
$ACLPath = Read-Host "Enter the full name of the file in which to save the ACL (D: \ ACL_file) "
function Recurse($path) {
$fc = new-object -com scripting.filesystemobject
$folder = $fc.getfolder($path)
foreach ($i in $folder.files) {$i}
foreach ($i in $folder.subfolders) {
Write-Host $i.path
$i
if ( (get-item -Force $i.path).Attributes.ToString().Contains("ReparsePoint") -eq $false)
{
Recurse($i.path)
}
}
}
Recurse($wPath) | Get-NTFSAccess -ExcludeInherited | Export-Clixml $ACLPath".xml"
$oldACL = Import-Clixml $ACLPath".xml"
foreach ($p in $oldACL) {
$p.Path | Clear-NTFSAccess
}
$oldACL | Add-NTFSAccess
Help seemed to me not complete (Add-NTFSAccess -? and Clear-NTFSAccess -?), could not understand how to apply the rules from .xml to files and folders in the root of the path C: \, at the moment I manually edit the path in .xml
You can use PowerShell to replace your wim path in the xml file to the system path:
For example, like this:
(Get-Content $ACLPath".xml") -replace "$wPath","c:\" | Set-Content $ACLPath".xml"
спасибо
Get-NTFSEffectiveAccess похоже работает только на локальных пользователях. Посмотреть эффективные права на доменной шаре для доменного пользоватля не получается — выдает всегда один вид прав для всех — «Synchronize» и уведомление
WARNING: The effective rights can only be computed based on group membership on this computer. For more accurate results, calculate effective access rights on the target computer
Так пробовали?
Get-NTFSEffectiveAccess -Path \\server1\share\public -Account domain\user
Да, именно так и пробовал
Добрый день.
А как можно в скрипте задать цикл, чтобы назначение прав доступа к каталогу осуществить на множество пользователей или групп, указанных в отдельном текстовом файле?
Делаете файл c:\ps\users.txt. В нем список аккаунтов:
user1
user2
user3
Следующий PowerShell скрипт загрузит список юзеров из файла и проставит NTFS разрешения:
$users=gc c:\ps\users.txt
foreach ($user in users$) {
Add-NTFSAccess -Path C:\distr -Account $user -AccessRights Modify -PassThru
}
Добрый день.
Можно ли копировать права одного каталога на несколько десятков каталогов? все каталоги расположены в одном месте, предполагаю что можно использовать цикл. Название каталогов имеют вид: «Фамилия Имя»
$dirList = dir d:\obm\
$folderACL = Get-acl ‘d:\obm\Фамилия Имя’
foreach ($folder in $dirList) {
$folderName = $folder.name
set-ACL -ACLObject $folderACL -path («d:\obm\» + $folderName)
}
Добрый день!
Подскажите, как выудить список папок в сетевой шаре, к которым имеет доступ (с указанием типа доступа) определённая группа домена?
Get-ACL и Set-ACL также можно использовать для управления разрешениями на ветки реестра.
Получить текущие разрешения:
$rights = Get-Acl -Path 'HKCU:\Control Panel\Desktop\'
Кому дать доступ:
$idRef = [System.Security.Principal.NTAccount]"BuiltIn\Users"
Уровень доступа:
$regRights = [System.Security.AccessControl.RegistryRights]::WriteKey
Параметры наследования:
$inhFlags = [System.Security.AccessControl.InheritanceFlags]::None
$prFlags = [System.Security.AccessControl.PropagationFlags]::None
Тип доступа (Allow/Deny):
$acType = [System.Security.AccessControl.AccessControlType]::Allow
Создайть правило:
$rule = New-Object System.Security.AccessControl.RegistryAccessRule ($idRef, $regRights, $inhFlags, $prFlags, $acType)
Добавить правило в ACL:
$rights.AddAccessRule($rule)
Применить ACL к ветке реестра:
$rights | Set-Acl -Path 'HKCU:\Control Panel\Desktop\'
Подробнее здесь: https://winitpro.ru/index.php/2017/02/07/rabotaem-s-reestrom-windows-cherez-powershell/
Столкнулся сегодня с довольно странной ситуацией — необходимы права на редактирование, но без удаления.
Суть проблемы — без прав на удаление становиться невозможным переименовывать файлы и папки … Файлы редактируются без вопросов(блокноты по крайней мере) хоть пустыми сохраняй, а имя — никак.
Интересная статья но вопросы остались🤔: как насчёт скратых ACL тех которые не показываться в свойства — — — >безопасность — — — >дополнительно ??
PS Прошёл достаточно большой промежуток времени но. Microsoft так и не документировала служебные скрытые ACL, ограничивщись сухим и не понятным зарезервираванно по принципу меньше знаете крепче спите😏😔