Скрипт: список папок, для которых отключено наследование разрешений.

Задал тут мне на днях начальник задачку, вполне себе типовую — предоставить финдиректору доступ ко всем папкам внутри некоей общей папки (на самом деле — дерева DFS), чтобы финдиректор мог «пойти туда, не знаю куда», и найти «то, не знаю что» (какие-то документы по какой-то старой-престарой сделке, про которую я не знаю и знать не хочу). Причем, начальник явно и недвусмысленно поставил условие — дать доступ ко всем папкам.
Если бы я работал в сферической организации в вакууме, которая придерживается «наилучших практик» в области IT, то проблемы бы не было: достаточно было бы включить финдиректора в группы, имеющие разрешения на чтение на целевые папки для каждой из ссылок DFS, и эти разрешения были бы унаследованы всеми вложенными папками. Но поскольку я работаю в реальной фирме, которая использует реальные практики, то все оказывается не так просто: где-то внутри деревьев подпапок есть папки, для которых наследование разрешений отключено , и эти папки, в полном с соответствии с реальными практиками, реально не документированы (ну, какой-то документ для начальства, конечно же, есть, но, сами понимаете…).
Поэтому для поиска таких папок был, после небольших раздумий, написан несложный скрипт на PowerShell (точнее — несколько команд для консоли, соединенных через конвейер), которым я и хочу поделиться.
Собственно, сам скрипт — вот он:
(get-item .).GetDirectories('*.*',[System.IO.SearchOption]::AllDirectories) | where-object{(Get-Acl $_.FullName).AreAccessRulesProtected}| select-object FullName
Он выводит в стандартный вывод полные имена всех папок внтури текущей папки, для которых отключено наследование разрешений.
Несколько слов по каждой команде.
1. (get-item .).GetDirectories('*.*',[System.IO.SearchOption]::AllDirectories)
Передает на конвейер (следующей команде) объекты DirectoryInfo для всех папок, вложенных в текущую: и подпапок текущей папки, и подпапок этих папок, и т.д. Эта команда имеет несколько странный вид из-за желательности оптимизации для моего случая: и сами папки, и количество файлов в них хоть и невелики, но и не так уж малы (сотни гигабайт и где-то в районе миллиона файлов). Поэтому мне не хотелось передавать дальше на конвейер объекты для всех файлов для выборки из них только объектов папок с помощью такой вот общеизвестной и кочущей по разным руководствам по PowerShell связки: Get-ChildItem -Recurse | Where-Object {$_.PSIsContainer}
Счастливый обладатель PowerShell 3.0 мог бы использовать появившуюся в нем возможность фильтрации по атрибутам: Get-ChilItem -Recurse -Directory. Но мне нужно было выполнить эту задачу на сервере под управлением Win2K8 R2 с PowerShell, установленным на нем по умолчанию. Поэтому пришлось вспомнить, что у объекта DirectoryInfo, представлющего текущую папку (его получает командлет Get-Item), есть метод GetDirectories, который, будучи вызванным с надлежащими параметрами, возвращает коллекцию из всех вложенных папок.
2. where-object{(Get-Acl $_.FullName).AreAccessRulesProtected}
Собственно, отбирает папки, для которых отключено наследование разрешений: получает объект ACL для папки и проверяет флаг наследования для DACL
3. select-object FullName
Выводит полные имена отобранных папок.
Вот и все.

Реклама
    • Юрий
    • 17.05.2013

    Боже, спасибо тебе, мил человек! Всё так просто! А я в пучине system.security пространств имён и никак и ничего. А всё на поверхности оказалось, спасибо огромное ещё раз!

  1. No trackbacks yet.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s