Перечисление на основе доступа Access-Based Enumeration (ABE) — функция, появившаяся в Windows Server 2003 с пакетом обновления SP1. Если вкратце, то она не позволяет пользователям видеть на общих ресурсах те файлы и папки, к которым у них нет доступа. Если ABE отключена, то пользователи смогут увидеть все файлы и папки, которые существуют на общем ресурсе. Но если они попытаются открыть какой-либо элемент, к которому у них нет разрешения на доступ, то получат сообщение «доступ запрещен». Если же ABE включена, то пользователь просто не увидит те файлы и папки, к которым у него нет разрешения на доступ.

.

Низвержение Abecmd.exe

Abecmd.exe является одним из компонентов пакета ABE для Windows Server 2003, доступного для загрузки по адресу www.microsoft.com/downloads/details.aspx?FamilyId=04A563D9-78D9-4342-A485-B030AC442084. Этот пакет включает официальное техническое руководство по использованию ABE, а также графический интерфейс пользователя ABE для Windows 2003 (в Windows 2008 и более поздние версии уже включена встроенная графическая утилита, которая является одним из компонентов консоли управления общими ресурсами и хранилищами).

С помощью Abecmd.exe можно легко включать или отключать ABE на общих ресурсах компьютера — от случая к случаю либо на постоянной основе. Однако, к сожалению, нельзя увидеть статус ABE одновременно для большого количества общих ресурсов компьютера. Я был несколько удивлен, что подобная функция не включена в этот инструмент командной строки. При наличии такой функции можно было бы легко управлять ABE на многочисленных общих ресурсах, поскольку стало бы возможным использование сценария для проверки статуса каждого общего ресурса и его изменения в случае необходимости.

Поэтому я создал решение, которое позволяет без труда управлять ABE на большом количестве общих ресурсов и даже на множестве компьютеров. Это решение состоит из трех компонентов.

  • ShareABE.exe. Данная утилита командной строки может определить, включено ли ABE, а также включить или отключить ABE на единичном общем ресурсе. В процессе обнаружения ABE она возвращает код завершения «1» в случае, если ABE включена, и «0», если отключена. Когда утилита используется для включения или отключения ABE, в случае успеха она возвращает код завершения «0». Возврат любого другого кода указывает на отказ. В случае отказа ShareABE.exe возвращает реальный код ошибки. Например, код ошибки 53 возвращается в случае, если не найден сетевой путь, 2310 — если указанный общий ресурс не существует, и 5 — если доступ запрещен. Для получения информации о коде ошибки можно воспользоваться командой Net Helpmsg.
  • Get-ABE.ps1 (листинг 1). Этот сценарий PowerShell использует ShareABE.exe для того, чтобы проверить, включено ли ABE для одного или более общих ресурсов на одном или более компьютерах.
  • Set-ABE.ps1 (листинг 2). Данный сценарий PowerShell использует ShareABE.exe для того, чтобы включить или отключить ABE для одного или более общих ресурсов на одном или более компьютерах.

Для того чтобы изменить состояние ABE, вы должны быть участником группы «Администраторы». Если вы изменяете состояние ABE для общего ресурса на локальном компьютере, то необходимо запустить PowerShell или Cmd.exe c повышенными правами пользователя. А для того чтобы изменить состояние ABE общего ресурса для удаленного компьютера, необходимо быть участником группы «Администраторы» на этом удаленном компьютере; в таком случае запуск с повышенными правами не имеет значения. Если вы не являетесь участником группы «Администраторы» на компьютере, на котором непосредственно размещен общий ресурс, то ShareABE.exe вернет код ошибки 5.

Решение работает на Server 2003 и более новых версиях и, в отличие от Abecmd.exe, замечательно функционирует на Windows 7. Обычно я использую решение на общих ресурсах с файловой системой NTFS. Если у вас возникнет желание использовать ABE на общих ресурсах с файловой системой DFS, обратитесь к статье «How to implement Windows Server 2003 Access-based Enumeration in a DFS environment» (support.microsoft.com/kb/907458) или «How to enable Access-based Enumeration for a Distributed File System (DFS) share in Windows Server 2008» (support.microsoft.com/kb/961658).

Для того чтобы использовать это решение, скопируйте файлы ShareABE.exe, Get-ABE.ps1 и Set-ABE.ps1 в папку, указанную в системной переменной Path (например, SystemRoot\system32). Для успешного запуска сценариев потребуется наличие PowerShell 2.0. При необходимости настройте политику сценариев PowerShell таким образом, чтобы был возможен запуск сценариев. Я рекомендую применять политику RemoteSigned. Если вы не знакомы с политиками PowerShell, прочтите статью «Running PowerShell Scripts Is as Easy as 1-2-3» (http://www.windowsitpro.com/article/windows-powershell/running-powershell-scripts-is-as-easy-as-1-2-3).

Утилита ShareABE.exe

ShareABE.exe — это, собственно, тот инструмент, благодаря которому работают наши сценарии. Также его можно использовать как автономную утилиту. Чтобы запустить его как автономную утилиту, откройте интерфейс командной строки Cmd.exe или PowerShell и выполните следующую команду:

ShareABE ComputerName ShareName
   [Действие]

где ComputerName — это имя компьютера, на котором размещен общий ресурс, ShareName — имя общего ресурса, а «Действие» — это либо слово enable (для включения ABE), либо disable (для его отключения). Если не указывать параметр «Действие», то ShareABE.exe просто отобразит, включено ли ABE на указанном общем ресурсе.

На экране 1 показано, как работает утилита ShareABE.exe. Первая команда отображает, что ABE отключено для указанного общего ресурса, а вторая команда включает ABE для этого ресурса. Третья команда аналогична первой, и с ее помощью мы можем убедиться, что ABE для интересующего нас общего ресурса действительно включилась.

 

Работа утилиты ShareABE.exe, запущенной как автономное приложение
Экран 1. Работа утилиты ShareABE.exe, запущенной как автономное приложение

Сценарий Get-ABE.ps1

Сценарий Get-ABE.ps1 превращает утилиту ShareABE.exe в инструмент, который может представить отчет о состоянии ABE для большого числа общих ресурсов на множестве компьютеров. Сценарий Get-ABE.ps1 имеет следующий синтаксис командной строки:

Get-ABE [-ComputerName String]
   [-ShareName String []]

Несмотря на то, что здесь эта команда переносится по строкам, в консоли PowerShell она набирается целиком в одну строку. То же самое правило действует и для других представленных здесь команд. Оба параметра сценария — ComputerName и -ShareName — являются необязательными. Если не указывать -ComputerName, то Get-ABE.ps1 будет считать, что вы хотите проверить состояние общих папок только на локальном компьютере. А если не указать -ShareName, то для Get-ABE.ps1 это будет сигналом, что вы хотите проверить все общие ресурсы. Имя общего ресурса также может содержать групповые символы. Ниже приводятся примеры команд.

Get-ABE app1

Эта команда отображает отчет о состоянии (статусе) ABE всех общих ресурсов сервера с именем app1. Обратите внимание, что при вводе этой и последующих команд указание имени параметра (-ComputerName и -ShareName) является необязательным.

Get-ABE app1, app2, app3 Scan*

Эта команда отображает отчет о состоянии ABE только для тех общих ресурсов, имена которых начинаются со слова Scan на серверах app1, app2 и app3.

Get-ABE.ps1 также допускает конвейерный (потоковый) ввод для параметра -ComputerName. Например, команда

Get-Content Servers.txt |
   Get-ABE -Sharename Shares, Users

отображает отчет о состоянии (статусе) ABE общих ресурсов с именами Shares и Users для каждого из серверов, перечисленных в файле Servers.txt (в указанном файле имя каждого сервера должно быть введено с новой строки).

Сценарий Get-ABE.ps1 отображает результаты в виде таблицы, столбцы которой содержат следующую информацию: имя компьютера, имя общего ресурса, локальный путь общего ресурса и логическую величину (принимающую значение True или False), указывающую, включено ли ABE для указанного общего ресурса. На экране 2 показан пример такой таблицы.

 

Выполнение сценария Get-ABE.ps1
Экран 2. Выполнение сценария Get-ABE.ps1

Сценарий Set-ABE.ps1

Сценарий Set-ABE.ps1 во многом подобен сценарию Get-ABE.ps1 с той лишь разницей, что он устанавливает состояние ABE для общих ресурсов, а не отображает его. Ниже представлен его синтаксис командной строки:

Set-ABE [-ComputerName String []]
   -ShareName String [] [-Enable]
   [-Disable] [-WhatIf] [-Confirm]

Параметр -ComputerName является необязательным. Если его не указать, то сценарий Set-ABE.ps1 будет считать, что речь идет о локальном компьютере. Параметр -ShareName является обязательным и допускает использование групповых символов. Так, например, если нужно включить или отключить ABE для всех общих ресурсов, можно использовать звездочку (*), которой соответствует любое имя общего ресурса. Также в команду необходимо включить параметр -Enable или -Disable (но не оба сразу). Для тестовых целей сценарий Set-ABE.ps1 также поддерживает параметры -WhatIf и -Confirm. Ниже приведены примеры команд.

Set-ABE apps1 * -Enable

Эта команда включает ABE для всех общих ресурсов на apps1. В этом примере не используются имена параметров -ComputerName и -ShareName, поскольку оба параметра располагаются в командной строке на местах, определенных синтаксисом команды.

Set-ABE apps1, apps2, apps3 Users -Disable

Эта команда отключает ABE для общего ресурса Users на серверах apps1, apps2 и apps3.

Подобно сценарию Get-ABE.ps1, сценарий Set-ABE.ps1 также поддерживает конвейерный ввод для имен компьютеров. Например, команда

Get-Content Servers.txt |
   Set-ABE -ShareName Dep* -Enable

включает ABE для тех общих ресурсов, имена которых начинаются с Dep, на каждом из серверов, перечисленных в файле Servers.txt (в указанном файле имя каждого сервера должно быть введено с новой строки). На экране 3 показано, как работает сценарий Set-ABE.ps1, причем в сочетании с параметром -Confirm.

 

Работа сценария Set-ABE.ps1
Экран 3. Работа сценария Set-ABE.ps1

Возьмите управление ABE в свои руки

ABE — это весьма полезный инструмент в арсенале системного администратора, но ему явно не хватает гибкого, поддерживающего сценарии интерфейса администрирования. Утилита ShareABE.exe и сценарии Get-ABE.ps1 и Set-ABE.ps1 исправляют этот недостаток и дают администратору возможность обнаруживать, включать и отключать ABE на множественных общих ресурсах и большом количестве компьютеров одновременно.

Листинг 1. Сценарий Get-ABE.ps1

# Written by Bill Stewart (bstewart@iname.com)
# PowerShell script to retrieve status of access-based enumeration (ABE).
# Requires ShareABE.exe to be in the path.

#requires -version 2

<#
.SYNOPSIS
Returns the status of access-based enumeration (ABE) for shares.

.DESCRIPTION
Returns the status of access-based enumeration (ABE) for one or more shares on one or more computers. Requires ShareABE.exe to be in the path.

.PARAMETER ComputerName
One or more computer names.

.PARAMETER ShareName
One or more share names. This parameter supports wildcards. If you omit this parameter, its default value is '*' (all shares).

.INPUTS
System.String.

.OUTPUTS
PSObjects containing the computer name, share name, path, and ABE status.

.LINK
http://go.microsoft.com/fwlink/?LinkID=100745

.EXAMPLE
C:\> Get-ABE server1 Apps
This command outputs the ABE status for the Apps share on server1.

.EXAMPLE
C:\> Get-ABE server2
This command outputs the ABE status for all shares on server2.

.EXAMPLE
C:\> Get-Content Servers.txt | Get-ABE -ShareName *app*
This command outputs the ABE status for shares matching the pattern '*app*' for all of the servers listed in the file Servers.txt.
#>
[CmdletBinding()]
param(
  [parameter(ValueFromPipeline=$TRUE)]
    [String[]] $ComputerName=$ENV:COMPUTERNAME,
    [String[]] $ShareName="*"
)

begin {
  # Throw an error if we can't find ShareABE.exe.
  $ShareABE = (get-command "ShareABE.exe" -erroraction SilentlyContinue).Definition
  if (-not $ShareABE) {
    throw "Can't find ShareABE.exe."
  }

  # Returns a PSObject containing the ABE information for a share. The $share
  # parameter is a WMI Win32_Share object instance.
  function get-shareABE($share) {
    & $ShareABE $share.__SERVER $share.Name > $NULL
    ""  | select-object `
      @{Name="Computer"; Expression={$share.__SERVER}},
      @{Name="Share";    Expression={$share.Name}},
      @{Name="Path";     Expression={$share.Path}},
      @{Name="ABE";      Expression={if ($LASTEXITCODE -le 1) {$LASTEXITCODE -eq 1} else {$LASTEXITCODE}}}
  }
}


process {
  foreach ($computer in $ComputerName) {
    get-wmiobject Win32_Share -computer $computer -filter "Type=0" | sort-object Name | foreach-object {
      foreach ($share in $ShareName) {
        if ($_.Name -like $share) {
          get-shareABE $_
        }
      }
    }
  }
}

end {
}

Листинг 2. Сценарий Set-ABE.ps1

# Written by Bill Stewart (bstewart@iname.com)
# PowerShell script to enable or disable access-based enumeration (ABE).
# Requires ShareABE.exe to be in the path.

#requires -version 2

<#
.SYNOPSIS
Enables or disables access-based enumeration (ABE) for shares.

.DESCRIPTION
Enables or disables access-based enumeration (ABE) for one or more shares on
one or more computers. Requires ShareABE.exe to be in the path.

.PARAMETER ComputerName
One or more computer names.

.PARAMETER ShareName
One or more share names. This parameter supports wildcards. Use '*' to specify
all shares.

.PARAMETER Enable
Enables access-based enumeration (ABE). You must specify either -Enable or
-Disable, but not both.

.PARAMETER Disable
Disables access-based enumeration (ABE).  You must specify either -Enable or
-Disable, but not both.

.INPUTS
System.String.

.OUTPUTS
PSObjects containing the computer name, share name, path, and ABE status.

.LINK
http://go.microsoft.com/fwlink/?LinkID=100745

.EXAMPLE
C:\> Set-ABE server1 Apps -Enable
This command enables access-based enumeration for the Apps share on server1.

.EXAMPLE
C:\> Set-ABE server2 * -Disable -Confirm
This command disables access-based enumeration for all shares on server2,
prompting for confirmation before modifying each share.

.EXAMPLE
C:\> Get-Content Servers.txt | Set-ABE -ShareName *app* -Enable
This command enables access-based enumeration for shares matching the pattern
'*app*' for all of the servers listed in the file Servers.txt.
#>
[CmdletBinding(SupportsShouldProcess=$TRUE)]
param(
  [parameter(ValueFromPipeline=$TRUE)]
    [String[]] $ComputerName=$ENV:COMPUTERNAME,
  [parameter(Mandatory=$TRUE)]
    [String[]] $ShareName,
    [Switch] $Enable,
    [Switch] $Disable
)

begin {
  # You must specify either -Enable or -Disable, but not both.
  if (-not ($Enable -xor $Disable)) {
    throw "You must specify either -Enable or -Disable."
  }

  # Throw an error if we can't find ShareABE.exe.
  $ShareABE = (get-command "ShareABE.exe" -erroraction SilentlyContinue).Definition
  if (-not $ShareABE) {
    throw "Can't find ShareABE.exe."
  }

  if ($Enable) { $NewABEState = "Enable" } else { $NewABEState = "Disable" }

  # Enables or disables ABE for a share. The $share parameter is a WMI
  # Win32_Share object instance, and the $newState parameter is the string
  # "Enable" or "Disable".
  function set-shareABE($share, $newState) {
    & $ShareABE $share.__SERVER $share.Name $newState > $NULL
    ""  | select-object `
      @{Name="Computer"; Expression={$share.__SERVER}},
      @{Name="Share";    Expression={$share.Name}},
      @{Name="Path";     Expression={$share.Path}},
      @{Name="ABE";      Expression={if ($LASTEXITCODE -eq 0) {$newState} else {$LASTEXITCODE}}}
  }
}

process {
  foreach ($computer in $ComputerName) {
    get-wmiobject Win32_Share -computer $computer -filter "Type=0" | sort-object Name | foreach-object {
      foreach ($share in $ShareName) {
        if ($_.Name -like $share) {
          if ($PSCMDLET.ShouldProcess("\\$($_.__SERVER)\$($_.Name)", "$NewABEState ABE")) {
            set-shareABE $_ $NewABEState
          }
        }
      }
    }
  }
}
end {
}

Билл Стюарт (bill.stewart@frenchmortuary.com) — системный и сетевой администратор компании French Mortuary, Нью-Мехико