Сервісний центр VPSGroup ремонт комп'ютерної техніки, заправка картриджів, ремонт оргтехніки, Київ, Виставковий центр, Васильківська, 55

Управління ACL з PowerShell.

Як ви знаєте, в файлової системі NTFS кожен об'єкт (файл або папка) має свій список контролю доступу (Access Control List, ACL). ACL визначає, хто (або що) має доступ до об'єкта, і які операції дозволено (або заборонено) цього суб'єкту проводити над об'єктом.

В PowerShell для керування ACL є цілих два командлет :

• Get-ACL - витягує список ACL для об'єкта.Отримані дані можна передати для подальшої обробки (напр. По конвеєру) або просто зберегти в файл;
• Set-ACL - встановлює нові або змінює існуючі списки ACL для об'єкта.

Як найпростіший приклад скопіюємо дозволу однієї папки на іншу:

Get-Acl C: \ test | Set-Acl C: \ test2

Порівняємо ACL до і після.Як бачите, зміни в наявності.



При копіюванні ACL потрібно мати на увазі, що користувач, під яким виконується ця операція, повинен бути власником (Owner) вихідного ресурсу (в прикладі це папка Test) і мати право Take Ownership. Справа в тому, що при перенесенні дозволів не можна перенести іншого власника.Якщо власником папки Test є поточний користувач і він має право Take Ownership, то всі дозволи включаючи власника будуть скопійовані на папку Test2. Якщо ж одна з умов не виконується, то буде видана помилка.

Копіювання штука корисна, але частіше доводиться ставити дозволу більш детально.Для установки дозволів NTFS використовується .NET клас FileSystemAccessRule, а список прав перерахований в FileSystemRights Enumeration. Вивести список можливих дозволів можна командою:

[system.enum] :: getnames ([System.Security.AccessControl.FileSystemRights])

У списку будуть показані як основні, так і детальні дозволу (зазвичай вони показуються на вкладці Advanced).



Для прикладу спробуємо дати користувачеві Testuser1 повні права на папку Test2:

# зчитуємо поточний список ACL папки Test2
$ acl = Get-Acl C: \ Test2;
# Створено змінну із зазначенням користувача, прав доступу і типу дозволу
$ AccessRule = New-Object System .Security.AccessControl.FileSystemAccessRule ( "Testuser1", "FullControl", "Allow");
# Передаємо змінну в клас FileSystemAccessRule для створення об'єкта
$ acl.SetAccessRule ($ AccessRule);
# Застосовуємо дозволу до папки
$ acl | Set-Acl c: \ Test2;

За замовчуванням створене правило дає користувачеві права тільки на саму папку. Якщо потрібно поширити це правило на дочірні об'єкти, то в створюваному правилі потрібно додатково вказати параметри успадкування:

"ContainerInherit", "None" - правило застосовується для папки і її підпапок;
"ObjectInherit", "None" - правило застосовується для папки і її файлів;
"ContainerInherit, ObjectInherit", "None" - правило застосовується для самої папки, її підпапок і файлів;
"ContainerInherit", "InheritOnly" - правило застосовується тільки для підпапок;
"ObjectInherit", "InheritOnly" - правило застосовується тільки для файлів;
"ContainerInherit, ObjectInherit", "InheritOnly" - правило застосовується тільки для підпапок і файлів.

Наприклад таке правило буде поширюватися на саму папку і всі її вміст:

$ AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule ( "Testuser1", " FullControl "," ContainerInherit, ObjectInherit "," None "," Allow ")

Видалення дозволів проводиться за такою ж схемою, що і додавання, тільки замість методу SetAccessRule буде використовуватися метод RemoveAccessRule:

$ acl = Get-Acl C: \ Test2;
$ AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule ( "Testuser1", "FullControl", "Allow");
$ acl.RemoveAccessRule ($ AccessRule);
$ acl | Set-Acl c: \ Test2;

І ще один момент. Метод SetAccessRule повністю замінює дозволу для користувача. Тому, якщо потрібно додати нові права до вже наявних, то використовуємо метод AddAccessRule.



Для видалення всіх дозволів користувача (повне видалення з ACL) використовується метод PurgeAccessRules, для роботи якого в якості параметра потрібно передати ім'я користувача або групи.У роботі цього методу є одна особливість - він не вміє працювати із строковими значеннями імен користувачів і груп, тому потрібен механізм перетворення строкових значень в SID. Для прикладу видалимо групу Users зі списку доступу папки Test2:

# Прочитуємо ACL
$ acl = Get-Acl C: \ Test2;
# Перетворимо строкове значення групи users в SID.Для перетворення скористаємося
# класом Ntaccout
$ users = New-Object System.Security.Principal.Ntaccount ( "users");
# Застосовуємо метод, передавши в нього в якості аргументу змінну $ users
$ acl.PurgeAccessRules ($ users);
# Застосовуємо ACL до папки
$ acl | Set-Acl C: \ Test2;

Варто мати на увазі, що подібним чином можна видаляти тільки явно призначені (не успадковане) дозволу.



Наступний етап налаштування дозволів - це управління успадкуванням. За керування спадкуванням відповідає метод SetAccessRuleProtection. Метод має два параметри, кожен з яких може бути $ true або $ false. Значення першого параметра $ true блокує успадкування дозволів від батька, $ false включає спадкування для об'єкта.Другий параметр відповідає за долю поточних дозволів для об'єкта при відключенні успадкування. Значення $ true залишає успадковані дозволи у вигляді явно заданих дозволів, $ false навпаки видалить успадковані дозволу і залишить тільки ті, які були явно задані. Наприклад SetAccessRuleProtection ($ true, $ false) - прибираємо успадкування і видаляємо успадковані дозволу.

За замовчуванням знову створений об'єкт успадковує дозволи від батьків. Для прикладу створимо новий об'єкт (папку Test3) і відключимо у неї спадкування:

# Створюємо нову папку і виводимо її ACL
md C: \ Test3 | Get-Acl | fl;
# Прочитуємо ACL папки Test3
$ acl = Get-Acl C: \ Test3;
# Відключаємо успадкування і видаляємо всі успадковані дозволу
$ acl.SetAccessRuleProtection ($ true, $ false);
# Застосовуємо ACL до папки Test3
$ acl | Set-Acl C: \ Test3;

Якщо тепер подивитися на вирішення папки Test3, то в поле Access ми побачимо порожнечу. І не дивно, адже всі успадковані дозволу ми видалили, а явно заданих у неї не було. Тепер доступ до теки зможе отримати тільки її власник (Owner).



І раз мова зайшла про власника. Власником об'єкта автоматично стає користувач, цей об'єкт створив (Creator Owner). Є політика Take Ownership, що дозволяє захоплювати права володіння об'єктом. За замовчуванням це право є тільки у членів групи локальних адміністраторів.

Для управління власниками об'єктів в PowerShell використовується метод SetOwner. Як приклад поміняємо власника папки Test2:

# Прочитуємо ACL
$ acl = Get-Acl C: \ Test2;
# Перетворимо строковий параметр групи Administrators в SID
$ group = New-Object System.Security.Principal.Ntaccount ( "Administrators");
# Застосовуємо метод SetOwner
$ acl.SetOwner ($ group);
# Застосовуємо ACL об'єкта
$ acl | Set-Acl C: \ Test2;

Чесно кажучи, управління власниками об'єктів в PowerShell не дуже зручно. Наприклад, не можна вказати в якості власника іншого користувача або групу. Власником об'єкта можна призначити тільки поточного користувача або його групу.Крім того, користувач, під яким виконується ця операція, повинен мати такі права:

• Право Take Ownership для даного об'єкта;
• Права Read і Change Permissions для даного об'єкта;
• право Restore files and directories в локальній політиці безпеки.



Ну ніби все.Список методів, що використовуються для управління ACL, докладно описаний в класі FileSystemSecurity на MSDN. Детальніше про дозволи NTFS можна почитати тут.

.