Contents of this directory is archived and no longer updated.

Posts on this page:

Как вы знаете, я в своё время писал скрипты для управления сетевыми папками (Shares) и наконец-то решил оформить это всё в человеческий модуль PowerShell.

Данный модуль позволяет вытворять следующее:

  • Получать список сетевых папок на локальном и/или удалённых компьютерах;
  • Расшаривать новые папки;
  • Удалять сетевые папки (останавливать шаринг конкретной папки без удаления фактического содержимого);
  • Добавлять/устанавливать/удалять права доступа к сетевой папке.

Вот инструкции по установке:


Read more →

По просьбе читателей, а так же с учётом востребованности (судя по сообщениям форумов и ньюсгрупп) я нашёл время переписать скрипт ShareUtils.ps1 с поддержкой работы с удалёнными машинами и попутно пофиксив недочёты, которые были найдены за время эксплуатации предыдущей версии скрипта. Предыдущая версия опубликована здесь: Управление безопасностью общих папок (сетевых шар) в PowerShell (часть 4)

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


Read more →

Наткнулся на него когда готовил ответ для ньюсгрупп. Как известно, владелец объекта может спокойно изменять списки ACL объектов минуя все их ограничения пользуясь неоткланяемым правом владения объектом. Поэтому, если из ACL объекта удалить все ACE и сохранить, то мы из проводника можем в любой момент вызвать вкладку Security объекта и задать требуемые ACE. Однако, это возможно только из графического интерфейса проводника сделать. При использовании скрипта и командлета Set-Acl мы этого сделать не сможем. Продемонстрирую проблему:

[C:\] whoami contoso\administrator [C:\] Get-Acl C:\Test | fl Path : Microsoft.PowerShell.Core\FileSystem::C:\Test Owner : CONTOSO\administrator Group : CONTOSO\Domain Users Access : Audit : Sddl : O:LAG:DUD:PAI [C:\] $acl = Get-Acl C:\Test [C:\] $accessrule = New-Object System.Security.AccessControl.FileSystemAccessRule("Administrator","FullControl", "Allow" ) [C:\] $acl.AddAccessRule($accessRule) [C:\] $acl | Set-Acl C:\Test Set-Acl : Attempted to perform an unauthorized operation. At line:1 char:15 + $acl | Set-Acl <<<< C:\Test + CategoryInfo : PermissionDenied: (C:\Test:String) [Set-Acl], UnauthorizedAccessException + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.SetAclCommand [C:\]

Как видите, текущий пользователь (администратор) является владельцем папки. Но все ACE в ACL пустые (секция Access). Пользуясь правами владельца, всё же, я не могу ничего сделать с этим списком. Как выяснилось в процессе исследования, пользователю-владельцу, который собирается менять ACL необходимо иметь явно назначенное или унаследованное разрешение TakeOwnership. Никаких Read/ChangePermissions и прочих не надо. Теперь я из проводника добавлю себе право TakeOwnership и попробую снова исполнить код:

[C:\] Get-Acl C:\Test | fl Path : Microsoft.PowerShell.Core\FileSystem::C:\Test Owner : CONTOSO\administrator Group : CONTOSO\Domain Users Access : CONTOSO\administrator Allow TakeOwnership, Synchronize Audit : Sddl : O:LAG:DUD:PAI(A;OICI;0x180000;;;LA) [C:\] $acl = Get-Acl C:\Test [C:\] $accessrule = New-Object System.Security.AccessControl.FileSystemAccessRule("Administrator","FullControl", "Allow" ) [C:\] $acl.AddAccessRule($accessRule) [C:\] $acl | Set-Acl C:\Test [C:\] Get-Acl C:\Test | fl Path : Microsoft.PowerShell.Core\FileSystem::C:\Test Owner : CONTOSO\administrator Group : CONTOSO\Domain Users Access : CONTOSO\Administrator Allow TakeOwnership, Synchronize CONTOSO\Administrator Allow FullControl Audit : Sddl : O:LAG:DUD:PAI(A;OICI;0x180000;;;LA)(A;;FA;;;LA) [C:\]

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

Зато мною не очень любимый WMI справился с задачей на ура, израсходовав кода при этом во много раз больше, чем с использованием командлетов. И в итоге получилось вот:

$path = "C:\Test"
$user = "Administrator"
$path = $path.replace("\", "\\")
$SD = ([WMIClass] "Win32_SecurityDescriptor").CreateInstance()
$ace = ([WMIClass] "Win32_ace").CreateInstance()
$Trustee = ([WMIClass] "Win32_Trustee").CreateInstance()
$SID = (new-object security.principal.ntaccount $user).translate([security.principal.securityidentifier])
[byte[]] $SIDArray = ,0 * $SID.BinaryLength
$SID.GetBinaryForm($SIDArray,0)
$Trustee.Name = $user
$Trustee.SID = $SIDArray
$ace.AccessMask = [System.Security.AccessControl.FileSystemRights]"FullControl"
$ace.AceFlags = "0x3"
$ace.AceType = 0
$ace.Trustee = $trustee
# читаем текущий ACL с объекта
$oldDACL = (gwmi Win32_LogicalFileSecuritySetting -filter "path='$path'").GetSecurityDescriptor().Descriptor.DACL
# добавляем его к пустому объекту DACL
$SD.DACL = $oldDACL
# и добавляем новый ACE
$SD.DACL += @($ace.psobject.baseobject)
# устанавливаем флаг SE_DACL_PRESENT
$SD.ControlFlags = "0x4"
$folder = gwmi Win32_LogicalFileSecuritySetting -filter "path='$path'"
$folder.setsecuritydescriptor($SD)

Я больше склонен доверять WMI и констатировать факт, что он работает честно – даёт мне делать с объектом что угодно и как угодно признавая мои права владения.

Я считаю, что Set-Acl был сильно не прав, отказав мне в изменении пустых ACE, поэтому отрепортил это дело на connect:

https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=418906&SiteID=99

Update 28.10.2010: исправлена ошибка с назначением права ManageDocuments.


Вот и пришло время закрыть тему управления принтерами и их списками ACL в PowerShell с использованием WMI. Я в блоге уже расписывал решение частных задач по основным задачам управления принтеров и по управлению их ACL списками. В этом посте я сложу все наработки по этому вопросу в единый концептуальный скрипт, который будет называться PrinterUtils.ps1 с достаточно объёмным набором функций, которые нацелены на упрощение для администраторов автоматизации принтеров с использованием PowerShell. Если кто-то захочет разобраться в работе скрипта и понять используемые приёмы, то предлагаю ознакомиться с следующими ссылками:

В качестве основы я использовал свои предыдущие наработки с SecurityDescriptor в предыдущем блоге, когда разбирал вопрос управления SharePermissions из PowerShell:

Материала у меня на эту тему набралось достаточно много, чтобы проникнуться в идею работы классов WMI и SecurityDescriptor, который не раз пытался посадить меня в лужу :) Однако версия скрипта ShareUtils чётко говорит о том, что скрипт далеко не идеален и не оптимален, имеет свои недостатки, т.к. это был мой первый опыт работы с функциями. Сейчас я значительно переработал структуру работы скрипта (оставив только Core работы с SecurityDescriptor), добавив удалённое управление (в разумных пределах) и, главное (как мне кажется), реализовал работу функций в конвейере. Примеры использования скрипта распишу чуть ниже. Итак, представляю набор функций, которые реализованы в скрипте:

  1. Подключение (маппинг) сетевого принтера к пользователю;
  2. Отключение маппинга сетевого принтера от пользователя;
  3. Получение сведений о принтерах;
  4. Установка принтера по умолчанию;
  5. Установка принтера для общего пользования (расшаривание принтера);
  6. Отмена принтера для общего пользования;

Данная секция представляет собой базовые возможности по управлению принтерами и полностью работоспособна в среде Windows XP/Windows Server 2003. А вот секция управления ACL списками принтеров доступна только в среде Windows Vista/Windows Server 2008. Сюда входят следующие функции:

  1. Получение сведений о правах доступа на конкретный принтер, конкретный принтсервер или по списку компьютеров;
  2. Импорт сведений о правах доступа из внешнего источника. Это может быть и CSV и XML или другой формат;
  3. Добавление пользователя или группы в ACL список принтера или всех принтеров, которые подключены к принтсерверу;
  4. Удаление пользователя или группы из ACL списка принтера или всех принтеров, которые подключены к принтсерверу;
  5. Установка пользователя или группы в ACL список принтера или всех принтеров, которые подключены к принтеру. При этом все имеющиеся права доступа будут удалены и заменены только одним ACE с правом ManagePrinters.

Для этих функций полностью реализована поддержка удалённой работы и работа в конвейере. Синтаксис команд используется примерно следующий:


Read more →

Итак, как я и обещал, я вернулся к вопросу изменения ACL принтеров в PowerShell. В первой части (Странности метода SetSecurityDescriptor класса Win32_Printer) я изложил проблематику вопроса. В конечном итоге я сегодня смог найти решение, которое оказалось не совсем понятным, но относительно предсказуемым.

Вернёмся снова к документации MSDN: SetSecurityDescriptor Method of the Win32_Printer Class

Это, конечно же, было моим попустительством, что не указал флаг управления SE_DACL_PRESENT и не включил привилегии SeSecurityPrivilege ("умение читать - первое умение системного администратора" (c) Peter.G). Понимание этого факта пришло после очередного прочтения поста о смене владельца папки (Смена владельца папки или файла в PowerShell (часть 2)). Что касается флагов управления, то выложу здесь значения флагов:


Read more →