Windows PowerShellПолномочия Shell

Дон Джонс

Загрузить исходный код для этой статьи: PowerShell2008_02.exe (151KB)

Когда речь заходит о Windows PowerShell, меня часто спрашивают о полномочиях, особенно о том, позволяет ли оболочка автоматизировать изменения полномочий и если да, то как. Чаще всего эти вопросы относятся к полномочиям на доступ к файлам, но полномочия для каталогов и реестра также всплывают довольно часто. Что касается полномочий

и любого интерфейса командной строки либо сценариев (включая Windows PowerShellTM и VBScript), то тут у меня есть и хорошие и плохие новости.

Плохие новости заключаются в том, что полномочия Windows® сложны по своей природе, и Windows PowerShell мало что может здесь сделать. Проблема вытекает из того, что в операционной системе Windows присутствуют несколько объектов, когда речь заходит о полномочиях, рассматриваем ли мы файловую систему, Active Directory®, реестр или почти всё прочее.

Во-первых, это сам ресурс – например, объект каталога, файл или папка. Далее, это объект списка управления доступом (Access Control List – ACL), которые присоединен к ресурсу. ACL состоит из одной или нескольких записей управления доступом или объектов ACE. Элемент ACE, по сути, связывает вместе участника безопасности (пользователя или группу, то есть еще один объект) с полномочием (таким как «Чтение» или «Полный контроль») и состоянием наличия и отсутствия последнего. Это не менее пяти объектов: ресурс, ACL, ACE, участник безопасности и полномочия.

Полномочия дополнительно усложняются фактом наличия различных типов полномочий у каждого типа ресурсов. Объекты каталогов, например, имеют сложные полномочия, управляющие доступом к отдельным атрибутам объекта. По сравнению с ними полномочия на доступ к файлам относительно просты.

А с технической точки зрения все это удваивается, когда дело доходит до аудита. У каждого ресурса на деле есть два списка ACL. Во-первых, это список управления доступом на уровне пользователей (DACL), который управляет доступом к ресурсу. Но существует также список управления доступом на уровне безопасности (SACL), который контролирует аудит на ресурсе. Попытка работать с этими полномочиями означает продирание через кучу довольно хитро выглядящих программных объектов, и возможности оболочки, вроде Windows PowerShell, по упрощению этого довольно ограничены.

Ограничена .NET Framework

Полученного недостаточно?

Дополнительные материалы по Windows PowerShell, включая библиотеку командлетов с возможностью поиска, а также связь с Доном Джонсом и другими экспертами по Windows PowerShell предоставляются сообществомwww.PowerShellCommunity.org.

Суть Windows PowerShell также несколько усложняет дело. Будучи построенной на основе Microsoft® .NET Framework, Windows PowerShell использует базовые классы .NET Framework для представления полномочий и работы с ними. Эти базовые классы .NET Framework разработаны с целью предоставления разработчикам возможности детализированного и точного управления полномочиями. Конечно «детализированность и точность» подразумевает большой объем информации и часто значит «крайняя сложность».

Вдобавок, .NET Framework предоставляет классы, представляющие полномочия, не для всех типов ресурсов Windows. Например, хотя .NET Framework предоставляет классы, позволяющие управлять безопасностью файлов, она не предоставляет классов, позволяющих работать с безопасностью общих папок. Как следствие, Windows PowerShell не может управлять полномочиями на некоторых типах ресурсов Windows. Попросту говоря, Windows PowerShell ограничена возможностями, которые предоставляет .NET Framework.

Полномочия в оболочке

Управление полномочиями в Windows PowerShell вытекает из двух командлетов: Get-ACL и Set-ACL. Как можно догадаться, Get-ACL получает список ACL от ресурса. Затем список ACL можно изменить в соответствии с потребностями и использовать Set-ACL для записи его обратно на ресурс. Оба командлета являются общими и полагаются на систему поставщиков PSDrive в Windows PowerShell. Следовательно, эти два командлета ACL теоретически могут работать с любым типом ресурса при наличии поставщика PSDrive, способного понимать такой тип ресурса и изменять полномочия на нем. Поставщики PSDrive FileSystem и Registry, поставляемые в комплекте с Windows PowerShell, поддерживают управление полномочиями через два командлета ACL. (Другие поставщики PSDrive могут и не поддерживать его.)

Пример сценария, показанный на Рис. 1, позволяет определить начальный каталог, участника безопасности и полномочие. Затем сценарий применяет указанное полномочие для этого участника ко всем файлам и папкам внутри указанного каталога. Сценарий также выполняет рекурсивный просмотр подкаталогов.

Figure 1 Выдача участнику полномочия на доступ к файлам и папкам в каталоге

#ChangeACL.ps1
$Right="FullControl"

#The possible values for Rights are 
# ListDirectory, ReadData, WriteData 
# CreateFiles, CreateDirectories, AppendData 
# ReadExtendedAttributes, WriteExtendedAttributes, Traverse
# ExecuteFile, DeleteSubdirectoriesAndFiles, ReadAttributes 
# WriteAttributes, Write, Delete 
# ReadPermissions, Read, ReadAndExecute 
# Modify, ChangePermissions, TakeOwnership
# Synchronize, FullControl

$StartingDir=Read-Host "What directory do you want to start at?"
$Principal=Read-Host "What security principal do you want to grant" `
"$Right to? `n Use format domain\username or domain\group"

#define a new access rule.
#note that the $rule line has been artificially broken for print purposes.
#it needs to be one line. the online version of the script is properly
#formatted.
$rule=new-object System.Security.AccessControl.FileSystemAccessRule
($Principal,$Right,"Allow")

foreach ($file in $(Get-ChildItem $StartingDir -recurse)) {
  $acl=get-acl $file.FullName
 
  #Add this access rule to the ACL
  $acl.SetAccessRule($rule)
  
  #Write the changes to the object
  set-acl $File.Fullname $acl
  }

Основная часть этого сценария – фрагмент, где он определяет новое правило доступа в переменной $rule. Чтобы сделать это, я использую «сырой» класс .NET Framework, что вероятно, является наиболее сложной частью управления полномочиями в Windows PowerShell. Затем сценарий получает список ACL от каждого файла и папки по очереди, используя Get-ACL, применяет новое правило, используя метод SetAccessRule списка ACL и записывает измененный список ACL обратно на ресурс, используя Set-ACL.

На практике это не так уж сложно, хотя более сложные операции вроде удаления элемента ACE из списка ACL, требуют большего вложения сил. По моему мнению, сложным этот процесс заставляет казаться количество этапов: получение списка ACL, определение правила, изменение списка ACL и запись списка ACL. Он не является единственной, ясной командой, делающей все сразу. А поскольку мне было нужно изменить списки ACL на нескольких файлах, все это пришлось поместить в цикл foreach, используя Get-ChildItem для реального доступа к файлам и папкам.

Мы пойдем простым путем

Командлет месяца: Get-QADUser

Данный командлет совершенно необходим при управлении Active Directory. Он не встроен в Windows PowerShell, но доступен как бесплатная загрузка в составе оболочки управления ActiveRoles Management Shell для Active Directory от компании Quest Software (www.quest.com/activeroles-server/arms.aspx).

После установки оснастки Get-QADUser можно использовать для получения объектов пользователей из каталога. Само собой, простое выполнение командлета возвращает всех имеющихся пользователей, а это не то чтобы полезно для большинства административных задач. Но командлет позволяет указать критерии фильтрации, применяемые на контроллере домена, чтобы в Windows PowerShell возвращались только нужные пользователи. Этот прием гораздо быстрее получения всех пользователей с последующей их фильтрацией посредством командлета Where-Object. Например, Get-QADUser -l Redmond вернет только тех пользователей, чей атрибут "l" содержит "Redmond". (Между прочим, атрибут "l" означает местоположение и перечислен как город в графическом интерфейсе пользователя.) Затем можно передать этих пользователей по конвейеру другим командлетам для создания отчета в формате HTML, поместить их в группу и даже удалить их.

Мои примеры не кажутся мне сложными, но я знаю, что многие администраторы предпочли бы более простой способ работы с полномочиями. Возможно, им нужно разом удалить определенную группу пользователей из набора папок, но не хочется писать многоэтапный сценарий, подобный показанному на рис. 1.

К счастью, Windows PowerShell предлагает упрощенный способ работы с полномочиями, с которым читатели, вероятно, уже знакомы.

Windows PowerShell не заставляет пользователя отказаться от его проверенных методов. Средства командной строки, такие как Dsacls.exe, Cacls.exe и Xcacls.exe, специально разработанные для упрощения работы с различными типами полномочий, по-прежнему можно использовать. Хотя их синтаксис совершенно не похож на стандартизированный синтаксис, используемый командлетам Windows PowerShell, эти служебные программы командной строки более не обязательно использовать специально подобранными для каждого случая способами, как они использовались под старой оболочкой cmd.exe. Кроме того, Windows PowerShell можно использовать для их автоматизации.

Я сталкивался с некоторыми, скажем так, пуристами, настаивающими на том, что использование старых служебных программ командной строки в Windows PowerShell отчего-то является неправильным. Я не вполне улавливаю их логику. Я рассчитываю на то, чтобы выполнять свою работу, и если простейший способ ее выполнения – использование служебной программы командной строки десятилетней давности, то её я и использую. Я не намерен тратить дополнительные часы, пытаясь проделать что-либо определенным способом, только потому, что он кажется «более чистым». Аналогично относятся к делу и разработчики Microsoft Windows PowerShell. Если существующее средство выполняет свою задачу, Windows PowerShell позволяет использовать его. Зачем изобретать велосипед?

На рис. 2 показан короткий сценарий, взятый из моей книги Windows PowerShell: TFM (изд-во SAPIEN Press, 2006 г.), который использует Windows PowerShell для автоматизации Cacls.exe. Этот сценарий является просто демонстрацией, и чтобы сделать из него реальное средство автоматизации, потребуется дополнительная работа. Но он показывает, как сценарий Windows PowerShell может собирать информацию и использовать ее для запуска Cacls.exe, как если бы Cacls.exe был «собственной» командой Windows PowerShell. (Хотя этот сценарий собирает информацию, запрашивая пользователя, параметры также можно считывать с файла или базы данных.)

Figure 2 Автоматизация Cacls.exe

#SetPermsWithCACLS.ps1
# CACLS rights are usually
# F = FullControl
# C = Change
# R = Readonly
# W = Write

$StartingDir=Read-Host "What directory do you want to start at?"
$Right=Read-Host "What CACLS right do you want to grant? Valid choices are F, C, R or W"
Switch ($Right) {
  "F" {$Null}
  "C" {$Null}
  "R" {$Null}
  "W" {$Null}
  default {
    Write-Host -foregroundcolor "Red" `
    `n $Right.ToUpper() " is an invalid choice. Please Try again."`n
    exit
  }
}

$Principal=Read-Host "What security principal do you want to grant?" `
"CACLS right"$Right.ToUpper()"to?" `n `
"Use format domain\username or domain\group"

$Verify=Read-Host `n "You are about to change permissions on all" `
"files starting at"$StartingDir.ToUpper() `n "for security"`
"principal"$Principal.ToUpper() `
"with new right of"$Right.ToUpper()"."`n `
"Do you want to continue? [Y,N]"

if ($Verify -eq "Y") {

 foreach ($file in $(Get-ChildItem $StartingDir -recurse)) {
  #display filename and old permissions
  write-Host -foregroundcolor Yellow $file.FullName
  #uncomment if you want to see old permissions
  #CACLS $file.FullName
  
  #ADD new permission with CACLS
  CACLS $file.FullName /E /P "${Principal}:${Right}" >$NULL
  
  #display new permissions
  Write-Host -foregroundcolor Green "New Permissions"
  CACLS $file.FullName
 }
}

Успешная работа с полномочиями?

Мне приходилось слышать, что Windows PowerShell неадекватна в плане полномочий, поскольку не предоставляет собственного командлета, дающего упрощенное, универсальное управление полномочиями. Я не согласен. Во-первых, это обвинение часто выдвигается администраторами, привыкшими к UNIX, а система полномочий Windows намного более сложна, чем та, которую использует UNIX. Работа Windows PowerShell также будет непростой. Однако это не порок Windows PowerShell.

Вдобавок, Windows PowerShell позволяет использовать упрощенные средства в форме старых, добрых служебных программ командной строки, как я и показал выше. Действительно, .NET Framework требуется некоторое расширение для более полного охвата управления полномочиями в платформе Windows. Но в целом Windows PowerShell дает преимущества с обеих полюсов: упрощенное управление полномочиями вместе с доступом к детализированным и точным средствам управления.

Дон Джонс — пишущий редактор журнала TechNet Magazine и соавтор книги Windows PowerShell: TFM (изд-во SAPIEN Press, 2007г.). Он обучает работе с Windows PowerShell (www.ScriptingTraining.com) и с ним можно связаться через веб-узел ScriptingAnswers.com.

© 2008 Корпорация Майкрософт и компания CMP Media, LLC. Все права защищены; полное или частичное воспроизведение без разрешения запрещено.