Как нейтрализовать UAC при работе со сценариями?

Джим Тернер: Я был уже почти готов вернуться на своем домашнем компьютере с Windows Vista обратно на Windows XP из-за функции управления учетными записями User Account Control (UAC). Дело в том, что постоянное срабатывание политики безопасности UAC в Vista и Windows Server 2008 отнимает много времени и мешает разрабатывать и отлаживать сценарии. Чтобы преодолеть эти затруднения, можно заблокировать UAC, но это не всегда стоит делать из соображений безопасности. В качестве альтернативы можно регистрироваться с помощью встроенной учетной записи Administrator, однако это потребует выполнения отдельных шагов и дополнительных мер предосторожности. (см. на сайте «Vista’s UAC Can Cause Problems When Writing and Running Scripts — UAC может вызвать проблемы при написании и работе сценариев», ID 99913).

После некоторого размышления я решил попытаться найти другое решение, не возвращаясь к предыдущей версии операционной системы. Изрядно повозившись с исследованиями и написав несколько строк кода, я разработал обходной маневр с помощью утилиты Elevate Script HTML Application (HTA). Эта утилита позволяет запускать VBScript или сценарий JScript с административными привилегиями в несколько щелчков. На экране 1 показано, что нужно просто найти этот сценарий, щелкнуть кнопку ElevateScript, а потом Continue во всплывающем окне UAC. Хотя я написал утилиту HTA для работы под Vista, она работает и для XP.

Пользовательский интерфейс Elevate Script HTA

В основе работы утилит Elevate Script HTA лежит процедура ElevateIt, приведенная в листинге 1. Эта процедура использует метод ShellExecute объекта Shell.Application в интерфейсе приложения Windows Shell API для сценариев. Данный метод обращается к команде runas, которая сообщает командному интерпретатору, что при выполнении некоторых операций необходимо предоставить пользователю более высокий уровень системных привилегий. Пользователь уже должен обладать необходимыми для выполнения этих операций привилегиями. Runas не назначает новых привилегий, а только активирует их.

Процедура ElevateIt

Во фрагменте B листинга 1 показана команда, которая включает метод ShellExecute. Как видно, при вызове этого метода необходимо включить несколько параметров. Судя по описанию метода на сайте MSDN — ShellExecute Method (http://msdn.microsoft.com/en-us/library/bb774148 (VS.85).aspx), используется следующий синтаксис:

ShellExecute (sFile [, vArguments] [, vDirectory] [, vOperation] [, vShow]

Сначала рассмотрим параметры vOperation и sFile. Параметр vOperation накладывает условия на действие, которое выполняется на файле, заданном параметром sFile. В данном случае этими параметрами являются соответственно runas и wscript.exe, которые дают команду ShellExecute активировать привилегии пользователя, запускающего механизм Windows Script Host’s (WSH’s) WScript.

Параметр sFile обязательный, а vOperation — нет. Если параметр vOperation задействован, необходимо, чтобы он принимал значение одной из команд, поддерживаемых данным типом файлов. Более подробно об этом рассказано на сайте MSDN — Verbs and File Associations, http://msdn.microsoft.com/en-us/library/cc144175.aspx.

Параметры vArguments, vDirectory и vShow, как и vOperation, необязательны. Параметр vArguments содержит аргументы для операции. В рассмотренном случае есть только один аргумент: имя пути того сценария, который нужно запустить с административными привилегиями. Поле ввода HTA содержит имя пути (то есть File1.value), поэтому подпрограмма ElevateIt берет это имя. Чтобы утилита HTA работала с XP, имя пути надо заключить в двойные кавычки. Итак, вместо использования File1.value в качестве параметра vOperation я добавил двойные кавычки к имени пути и сохранил их в переменной ScriptFile (см. фрагмент A листинга 1). В этом случае ScriptFile используется как параметр vArguments.

Параметр vDirectory используется для определения полного пути к каталогу, в котором находится файл, указанный параметром sFile. Поскольку WScript находится в каталоге Windows, задавать этот каталог не нужно. Но все равно необходимо включить пустую строку ("").

Параметр vShow определяет способ открытия окна приложения, которое запускается для выполнения этой операции. Он может принимать одно из перечисленных ниже значений.

  • 0 — открыть со спрятанным окном.
  • 1 — открыть с обычным окном.
  • 2 — открыть с минимизированным окном.
  • 3 — открыть с максимально развернутым окном.
  • 4 — открыть с окном с размерами и положением, заданными при последнем обращении.
  • 5 — открыть с окном с текущими размерами и положением.
  • 7 — открыть с минимизированным окном. Активное окно остается активным.
  • 10 — открыть с окном в состоянии по умолчанию, заданном приложением.

В моем случае требуется, чтобы окно открывалось в обычном размере, поэтому задано значение 1.

Утилита Elevate Script HTA — приложение совсем несложное, но очень полезное при разработке и отладке сценариев при использовании операционных систем Vista или Server 2008, поскольку уменьшает проблемы, создаваемые UAC. Утилита очень проста и не требует специальной установки и пользовательской настройки.

Как применять PowerShell для выполнения команд на удаленных машинах?

Джеймс Лим: Мне требовалось запустить команду ipconfig/all на всех удаленных серверах и собрать результаты на своем компьютере. Можно было воспользоваться PsExec из набора инструментов PsTools, но я решил попробовать сделать это с помощью PowerShell 1.0. PowerShell 2.0 позволяет выполнять команды PowerShell непосредственно на удаленных компьютерах, но эта версия пока еще находится на стадии CTP (Community Technology Preview). После некоторого изучения и тестирования я написал сценарий RemoteProcess.ps1, приведенный в листинге 2.

Сценарий RemoteProcess.ps1

Как показано в листинге 2, PowerShell 1.0 позволяет задействовать класс WMI Win32_Process для запуска процесса на удаленном компьютере. Если говорить более точно, я использую акселератор типа [wmiclass] для подключения к пространству имен ROOTCIMV2 из WMI и доступ к экземпляру Win32_Process на компьютере, указанном в переменной $s. Затем я использовал метод Create класса для начала удаленного процесса, который запускается командой ipconfig/all. Результаты выполнения этой команды сохраняются в текстовом файле на диске C удаленного сервера. Имя результирующего файла имеет вид $s-ipconfig.txt, где $s — имя удаленного сервера.

Помимо перенаправления в файл выдачи команды ipconfig, я сохраняю значение, возвращаемое методом Create класса Win32_Process. Этот метод возвращает 0 в случае успешного создания процесса; отличное от нуля значение указывает на ошибку. Различные значения показаны в операторе switch листинга 2. Подробнее см. на сайте MSDN, материал «Create Method of the Win32_Process Class», http://msdn.microsoft.com/en-us/library/aa389388%28 VS.85%29.aspx. Когда метод Create дает значение, предложение switch показывает имя удаленного сервера, сопровождаемого соответствующим сообщением на основе этого значения. Например, если метод Create дает значение 2, предложение switch отображает сообщение Access Denied после имени удаленного сервера.

Когда метод Create успешно выполнен, команда ipconfig/all выполняется и все результаты сохраняются на диске C удаленного сервера. Мне не нужно сохранять результаты на удаленных серверах, поэтому я поставил команду удаления Move-Item в операторе

Move-Item -path$sc$$s-ipconfig.txt `
$destination -force

для их переноса на свою локальную машину. Однако при многократном выполнении этого сценария во время проверки я получил сообщение об ошибке на строках Move-Item: Cannot find path ‘mycomputerc$mycomputer-ipconfig.txt’ because it does not exist («Невозможно найти путь ‘mycomputerc$mycomputer-ipconfig.txt’, так как его не существует»). Прочтя сообщение об ошибке, я понял, что требуется некоторое время для выполнения процесса Win32 на удаленной машине, которая находится в сети, а PowerShell не дожидается завершения запущенного процесса, сразу переходя к исполнению следующей команды. Поэтому, когда PowerShell начинал выполнение команды Move-Item, из-за того, что он еще не был создан, возникала ошибка.

Чтобы исправить ситуацию, я воспользовался методом Start класса Microsoft.NET Framework System.Diagnostics.Process для выполнения команды Move-Item, потому что PowerShell в данном случае должен ждать окончания процесса Win32, прежде чем начать выполнение следующей команды. Как показывает код фрагмента C в листинге 2, я дополнительно применил метод WaitForExit класса System.Diagnostics.Process, чтобы установить максимальное время ожидания. Это позволило PowerShell приостановить работу до выполнения условия, когда удаленный процесс заканчивается или время ожидания превысит три секунды. Прежде чем запустить сценарий RemoteProcess.ps1, надо настроить его и создать файл для ввода.

Для настройки сценария RemoteProcess.ps1 откройте его в текстовом редакторе, например в Notepad. В первой строке

$destination =mycomputerd$ipconfig

изменитеmycomputerd$ipconfig на то место, где вы собираетесь хранить результирующие файлы вывода. Во второй строке

$servers = Get-Content D:servers.txt

замените D:servers.txt именем файла, содержащего имена компьютеров, конфигурации которых собираетесь получить с помощью команды ipconfig/all. Имя каждого сервера занимает отдельную строку.

Я написал этот сценарий для запуска на удаленных серверах Windows Server 2003. Необходимо запускать PowerShell с правами администратора для того, чтобы сценарий был выполнен успешно, так как акселераторы типа [WMI] не позволяют изменять учетные сведения пользователя, а для исполнения команды на удаленном компьютере требуются административные права.

Разрешение быстрых клавиш при использовании SRP на рабочих станциях Windows XP

Рассел Смит: В Windows Vista и Windows XP политики ограничения использования программ Software Restriction Policies (SRP) обеспечивают дополнительный уровень защиты от запуска несанкционированных программ на рабочих станциях пользователей. Применение встроенных правил SRP позволяет запускать программы в защищенных местах, например в %ProgramFiles% и%SystemRoot%, без ограничений. Установка уровня безопасности по умолчанию на значение Disallowed («Запрещено») предотвратит возможность выполнения исполнимых файлов в других местах, которая с учетом всех обстоятельств является весьма полезной, учитывая растущую популярность портативных приложений.

В XP существует одна проблема с простым переключением на SRP и установлением уровня безопасности по умолчанию на уровень Disallowed. Она состоит в том, что встроенные правила не позволяют пользователям запускать приложения с помощью ярлыков рабочего стола. Для большинства организаций такой компромисс между безопасностью и функциональностью неприемлем, поскольку пользователи часто применяют ярлыки для запуска приложений. На экране 2 показано, как решить эту проблему.

Добавление правила пути *.lnk

Добавление правила пути *.lnk переактивирует все ярлыки на пользовательской системе. Интересно, что это правило пути фактически не содержит путь. В нем есть только строка *.lnk.

Для Vista политики SRP усовершенствованы и разрешают использовать ярлыки в случае установки уровня безопасности по умолчанию на Disallowed. Поэтому на рабочих станциях Vista не требуется добавлять это правило пути.


Джим Тернер (jturnervbs@gmail.com) — системный администратор и разработчик приложений в компании Computer Sciences Corporation

Джеймс Лим (james_k_k_lim@apl.com) — менеджер в подразделении Distributed Systems and Services компании Neptune Orient Lines из Сингапура. Имеет звания MCSE, CISSP, Certified Ethical Hacker (CEH) и Oracle Certified Professional (OCP) 9i

Рассел Смит (rms@russell-smith.net) — независимый ИТ-консультант, специализируется на управлении системами