Что сделал на этой неделе

Пишу, чтобы не забыть, что делал, потом может пригодиться.

Скрипт, меняющий пароли локального администратора на рабочих станциях

Вещи типа Local Administrator Password Solution использовать в наших широтах не очень принято, поэтому приходится изобретать свой велосипед. Работа идёт через ADSI, так как Powershell v5, где есть удобные команды типа Get-LocalUser, установлен далеко не везде (почему — это отдельная тема, слабо связанная с технической стороной).

Скрипт берёт имена рабочих станций из AD, потом для каждой проверяет соединение. Если связь есть, лезет туда и получает список членов группы локальных администраторов. Если у учётки «Администратор» пароль старше 60 дней (он в секундах, надо его делить на 86400), генерит новый и задаёт его, затем снимает флаги «пароль не требуется», «пароль не может быть изменён», и «учётная запись отключена», ставит флаг «срок действия пароля неограничен» — ведь неизвестно, когда в следующий раз удастся поменять пароль. Если среди членов группы администраторов обнаружились пользователи с определёнными названиями (техподдержка при заливке машин давала такие имена) — удаляет эти учётные записи.

Результаты пишутся в файл CSV — имя компьютера, имя локального администратора, пароль, дата последней успешной смены пароля, дата последней попытки смены пароля. Отчёт о работе скрипта высылается на почту.

Логон-скрипт, собирающий статистику о локально подключенных почтовых архивах в формате .pst

При входе пользователя в систему идёт подключение к COM-объекту Outlook.Application и выгружается список локальных объектов хранения, где встречается «.pst», также вычисляется размер этих файлов.

Результат пишется в общий каталог на сервере в формате CSV — версия Outlook, пути к файлам .pst, размеры в мегабайтах, пользователь, компьютер. Имя файла CSV также состоит из имён и пользователя, и компьютера, т. к. пользователь может заходить на несколько машин и везде иметь подключенные архивы.

Потом этот сценарий наверняка будет дорабатываться, так как изначальная идея заключается в том, чтобы хранить пользовательские архивы на сервере в их личных папках и делать оттуда резервные копии. Архивы эти можно отключить из Outlook скриптом прямо наживую, переместить их на сервер, а потом снова подключить. Это сэкономит много человеко-часов команде техподдержки — впрочем, как и любая автоматизация подобного рода.

Автоматизация создания файловой структуры, генерации групп и раздачи прав

На протяжении многих лет существования компании и смены разных команд айтишников, права на общие каталоги раздавались непонятно как и бессистемно, что закономерно привело к хаосу. Необходимо было сделать нормальную файловую структуру и раздать соответствующие права. Так как подразделений очень много, для каждого нужно создавать три ресурсные группы (листинг, чтение, запись), да ещё и с довольно сложной вложенностью (см. рис. 1), мысль о том, что всё это надо делать руками, приводила в уныние. К счастью, несколько дней размышлений и экспериментов прояснили метод решения задачи.


Рис. 1. Вложенность ресурсных групп для раздачи прав на каталоги

Сутью метода являются три вложенных друг в друга цикла, которые перебирают названия каталогов на всё большей глубине (само создание каталогов автоматизировать не удалось, т. к. единого подхода к сокращению названий подразделений нет, хотя я предлагал различные методы).

На первом этапе создаются ресурсные группы в AD (индекс вложенности в имени группы вычисляется интересно (сам быстро не додумался, пришлось гуглить) — путь к папке, например, \\server\share\department1\group2, разбивается на массив символов, где подсчитываются наклонные черты минус 2).

$level = (($_.FullName).ToCharArray() |? {$_ -eq "\"} |measure).count - 2

Второй этап — вложенность групп. Тот же тройной цикл, но теперь ищутся группы в AD, соответствующие названию текущей папки (например, FS-2-$($_.name)-). Далее делаются команды добавления членства в группах с выборками соответствующих имён согласно вышеприведённой схеме. Важно, что нужно задавать условие существования для добавления групп (if ($2groups -and $3groups)), потому что не везде существуют группы 4-го или 3-го уровней; также, нужно обнулять содержимое переменных групп 3 и 4 уровней после окончания их цикла, потому что иначе, когда снова начнётся главный цикл, не сработают условия существования групп (переменные уже будут содержать данные из предыдущего цикла), и в результате, группы нижних уровней из прошлой итерации добавятся в группы из новой, что совершенно не нужно.

Третий этап — раздача прав на папки. Здесь было уже проще — из-за такой сложной вложенности групп права на папку даются только для тех групп, которые соответствуют её названию, а также группе локальных администраторов сервера и учётной записи «Система». В Powershell изначально нет нормального функционала работы с правами NTFS, но зато есть прекрасный модуль NTFSSecurity. Вот права, например, для 3-го этапа:

Set-NTFSInheritance -Path "$($_.FullName)" -AccessInheritanceEnabled:$false
Add-NTFSAccess -Path "$($_.FullName)" -Account 'BUILTIN\Администраторы', 'NT AUTHORITY\СИСТЕМА' -AccessRights FullControl
Add-NTFSAccess -Path "$($_.FullName)" -Account $($3groups.name -match "FS-.*-r$") -AccessRights ReadAndExecute
Add-NTFSAccess -Path "$($_.FullName)" -Account $($3groups.name -match "FS-.*-rw$") -AccessRights Modify
if ($3groups.name -match "FS-.*-l$") {
  Add-NTFSAccess -Path "$($_.FullName)" -Account $($3groups.name -match "FS-.*-l$") -AccessRights ReadAndExecute -AppliesTo ThisFolderAndSubfolders
}

Наконец, для каждого каталога были убраны права для учётки «Создатель-владелец», которая портит всю картину с правами, так как стандартно каждый, кто создал что-либо в общей папке, имеет на это полный доступ, в результате через короткое время картина с правами опять превращается в хаос:

Remove-NTFSAccess -Path "$($_.FullName)" -Account "СОЗДАТЕЛЬ-ВЛАДЕЛЕЦ" -AccessRights FullControl